如果您对容器化工作负载完全不熟悉,不妨参阅本教程。本课程将引导您将简单的应用从源代码设置为在 GKE 上运行的容器,以此向您介绍容器和容器编排。
本教程不需要您具备任何容器或 Kubernetes 方面的相关经验。不过,如果您想在开始本教程之前阅读核心 Kubernetes 术语的概览,请参阅开始了解 Kubernetes(如果您更喜欢以漫画的形式了解 Kubernetes,请参阅我们的 Kubernetes 漫画)。如需查看更详细的资源,请参阅本教程末尾的后续措施部分。
如果您已熟悉容器和 Kubernetes,可以跳过本教程,直接开始了解 GKE 本身。
目标
- 探索简单多服务“hello world”应用。
- 从源代码运行应用。
- 将应用容器化。
- 创建一个 Kubernetes 集群。
- 将容器部署到集群。
准备工作
请按照以下步骤启用 Kubernetes Engine API:- 访问 Google Cloud 控制台中的 Kubernetes Engine 页面。
- 创建或选择项目。
- 稍作等待,让 API 和相关服务完成启用过程。 此过程可能耗时几分钟。
-
Make sure that billing is enabled for your Google Cloud project.
准备 Cloud Shell
本教程使用 Cloud Shell,其中预配了运行基于 Debian 的 Linux 操作系统的 g1-small Compute Engine 虚拟机 (VM)。
使用 Cloud Shell 具有以下优势:
- 已完全设置 Python 3 开发环境(包括
virtualenv
)。 - 本教程中使用的
gcloud
、docker
、git
和kubectl
命令行工具已安装。 您可以选择内置的文本编辑器:
Cloud Shell Editor,您可以通过点击 Cloud Shell 窗口顶部的 Open Editor 访问该编辑器。
Emacs、Vim 或 Nano,可从 Cloud Shell 中的命令行访问。
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
下载示例代码
下载
helloserver
源代码:git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
切换到示例代码目录:
cd anthos-service-mesh-samples/docs/helloserver
探索多服务应用
示例应用是使用 Python 编写的。它包含以下使用 REST 进行通信的组件:
server
:一个基本服务器,具有一个GET
端点/
,可将“hello world”输出到终端窗口。loadgen
:一种将流量发送到server
的脚本,可配置每秒请求数 (RPS)。
从来源运行应用
如需熟悉示例应用,请在 Cloud Shell 中运行该应用:
从
sample-apps/helloserver
目录运行server
:python3 server/server.py
启动时,
server
会显示以下内容:INFO:root:Starting server...
打开另一个终端窗口,以便向
server
发送请求。如需在 Cloud Shell 中执行此操作,请点击 打开新标签页以打开另一个会话。在新终端窗口中,向
server
发送请求:curl http://localhost:8080
server
的输出如下所示:Hello World!
在同一标签页中,切换到包含
loadgen
脚本的目录:cd anthos-service-mesh-samples/docs/helloserver/loadgen
创建以下环境变量:
export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5
启动
virtualenv
:virtualenv --python python3 env
激活此虚拟环境:
source env/bin/activate
安装
loadgen
的要求:pip3 install -r requirements.txt
运行
loadgen
应用以为server
生成流量:python3 loadgen.py
在启动时,
loadgen
的输出类似于以下内容:Starting loadgen: 2024-10-11 09:49:51.798028 5 request(s) complete to http://localhost:8080
现在,打开运行
server
的终端窗口。您应该会看到如下所示的消息:127.0.0.1 - - [11/Oct/2024 09:51:28] "GET / HTTP/1.1" 200 - INFO:root:GET request, Path: / Headers: Host: localhost:8080 User-Agent: python-requests/2.32.3 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive
从网络的角度来看,整个应用目前在同一主机上运行,这样您就可以使用
localhost
向server
发送请求。如需停止
loadgen
和server
,请在每个终端窗口中按Ctrl-c
。在
loadgen
终端窗口中,停用虚拟环境:deactivate
将应用容器化
如需在 GKE 上运行应用,您需要将示例应用的两个组件打包到容器中。容器是一个软件包,其中包含应用在任何环境中运行所需的所有元素。本教程使用 Docker 将应用容器化。
如需使用 Docker 将应用容器化,您需要一个 Dockerfile
。Dockerfile
是一个文本文件,用于定义将应用源代码及其依赖项汇编到容器映像中所需的命令。构建映像后,您可以将其上传到容器注册表,例如 Artifact Registry。
本教程的源代码包含一个 Dockerfile
用于 server
和 loadgen
,后者具有构建映像所需的所有命令。以下是 server
的 Dockerfile
:
在此文件中,您可以看到以下内容:
FROM python:3-slim as base
指令告知 Docker 将最新的 Python 3 映像用作基础映像。COPY . .
指令会将当前工作目录(在本例中为server.py
)中的源文件复制到容器的文件系统。ENTRYPOINT
定义用于运行容器的指令。在此示例中,该指令与您用于通过源代码运行server.py
的命令类似。EXPOSE
指令指定server
监听端口8080
。此指令不会公开任何端口,但可用作您在运行容器时打开端口8080
所需的文档。
准备将应用容器化
在将应用容器化之前,您需要为要使用的工具和服务进行一些设置:
为 Google Cloud CLI 设置默认 Google Cloud 项目。
gcloud config set project PROJECT_ID
为 Google Cloud CLI 设置默认区域。
gcloud config set compute/region us-central1
创建代码库
如需在 Artifact Registry 中为 Docker 容器映像创建新的代码库,请执行以下操作:
确保在 Google Cloud 项目中启用 Artifact Registry 服务。
gcloud services enable artifactregistry.googleapis.com
创建 Artifact Registry 代码库:
gcloud artifacts repositories create container-intro --repository-format=docker \ --location=us-central1 \ --description="My new Docker repository"
使用 Google Cloud CLI 设置从 Docker 到 Artifact Registry 的身份验证:
gcloud auth configure-docker us-central1-docker.pkg.dev
将 server
容器化
现在,该将应用容器化了。首先,将“hello world”server
容器化,并将映像推送到 Artifact Registry:
切换到示例
server
所在的目录:cd ~/anthos-service-mesh-samples/docs/helloserver/server/
使用
Dockerfile
构建映像:docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1 .
- 将
PROJECT_ID
替换为您的 Google Cloud 项目的 ID。
-t
标志表示 Docker 标记。这是您在部署容器时使用的映像的名称。- 将
将该映像推送到 Artifact Registry。
docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
将 loadgen
容器化
接下来,以相同的方式将负载生成器服务容器化:
切换到示例
loadgen
所在的目录:cd ../loadgen
构建映像:
docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1 .
将该映像推送到 Artifact Registry。
docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1
列出映像
获取代码库中的映像列表,以确认是否已推送映像:
gcloud container images list --repository us-central1-docker.pkg.dev/PROJECT_ID/container-intro
输出应列出您推送的映像名称,类似如下所示:
NAME us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen
创建 GKE 集群
此时,您只需使用 docker run
命令在 Cloud Shell 虚拟机上运行容器即可。但是,若要运行可靠的生产工作负载,您需要以更统一的方式管理容器。例如,您需要确保容器在发生故障时重启,并且需要一种方法来纵向扩容和启动容器的其他实例,以便处理流量增加。
GKE 可帮助您满足这些需求。GKE 是一个容器编排平台,其工作方式是将虚拟机连接到集群。每个虚拟机称为一个节点。GKE 集群由 Kubernetes 开源集群管理系统提供支持。Kubernetes 为用户提供了与集群进行交互的机制。
如需在 GKE 上运行容器,您需要先创建集群,然后连接到该集群:
创建集群:
gcloud container clusters create-auto container-intro
gcloud
命令会在您之前设置的默认 Google Cloud 项目和区域中创建一个集群。创建集群的命令需要几分钟才能完成。集群准备就绪后,输出类似于以下内容:
NAME: container-intro LOCATION: us-central1 MASTER_VERSION: 1.30.4-gke.1348000 MASTER_IP: 34.44.14.166 MACHINE_TYPE: e2-small NODE_VERSION: 1.30.4-gke.1348000 NUM_NODES: 3 STATUS: RUNNING
向
kubectl
命令行工具提供凭据,以便使用它来管理集群:gcloud container clusters get-credentials container-intro
检查 Kubernetes 清单
从源代码运行应用时,您使用了命令式命令:python3 server.py
命令式意味着以动词为导向:“这样做”。
相比之下,Kubernetes 基于声明式模型运行。这意味着,您无需确切地告知 Kubernetes 做什么,而只需为 Kubernetes 提供所需状态。例如,Kubernetes 会根据需要启动和终止 Pod,以使实际系统状态与所需状态匹配。
您可以在名为清单的文件中指定所需状态。清单使用 YAML 或 JSON 等语言编写,并包含一个或多个 Kubernetes 对象的规范。
该示例包含 server
和 loadgen
各自的清单。每个清单都指定 Kubernetes Deployment 对象(用于管理作为 Kubernetes Pod 打包并运行的容器)和 Service(用于为 Pod 提供 IP 地址)的所需状态。Pod 是您可以在 Kubernetes 中创建和管理的最小可部署计算单元,可容纳一个或多个容器。
下图显示在 GKE 上运行的应用:
您可以参阅开始学习 Kubernetes,或参阅本页末尾的资源,详细了解 Pod、部署和服务。
服务器
首先,查看“Hello World”server
的清单:
此清单包含以下字段:
kind
表示对象的类型。metadata.name
指定 Deployment 的名称。- 第一个
spec
字段包含所需状态的说明。 spec.replicas
指定所需 Pod 的数量。spec.template
部分定义 Pod 模板。Pod 的规范中包含image
字段,该字段是从 Artifact Registry 中拉取的映像的名称。在下一步中,您将将其更新为您刚刚创建的新图片。
hellosvc
服务的定义如下:
LoadBalancer
:客户端向网络负载平衡器的 IP 地址发送请求,网络负载平衡器具有稳定的 IP 地址,并且可从集群外部访问。targetPort
:回想一下,Dockerfile
中的EXPOSE 8080
命令不会实际公开任何端口。您可以公开端口8080
,以便访问集群外部的server
容器。在这种情况下,hellosvc.default.cluster.local:80
(简称:hellosvc
)映射到helloserver
Pod IP 的端口8080
。port
:这是在发送请求时集群中的其他服务使用的端口号。
负载生成器
loadgen.yaml
中的 Deployment 对象类似于 server.yaml
。一个显著区别是,loadgen
部署的 Pod 规范有一个名为 env
的字段。本部分定义 loadgen
所需的环境变量,此变量是您在从源代码运行应用时设置的。
由于 loadgen
不接受传入请求,因此将 type
字段设置为 ClusterIP
。此类 Service 提供集群中的实体可以使用的稳定 IP 地址,但不会向外部客户端公开 IP 地址。
将容器部署到 GKE
如需部署容器,您可以使用 kubectl
应用指定所需状态的清单。
部署 server
切换到示例
server
所在的目录:cd ~/anthos-service-mesh-samples/docs/helloserver/server/
在 Cloud Shell Editor(或首选文本编辑器)中打开
server.yaml
。将
image
字段中的名称替换为您的 Docker 映像的名称。image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
将 PROJECT_ID 替换为您的 Google Cloud 项目 ID。
- 如果您使用的是 Cloud Shell Editor,系统会自动保存文件。点击打开终端,返回终端窗口。
- 如果您在 Cloud Shell 中使用文本编辑器,请保存并关闭
server.yaml
。
将清单部署到 Kubernetes:
kubectl apply -f server.yaml
输出类似于以下内容:
deployment.apps/helloserver created service/hellosvc created
部署 loadgen
切换到
loadgen
所在的目录。cd ../loadgen
像之前一样,在文本编辑器中打开
loadgen.yaml
。再次将
image
字段中的名称替换为您的 Docker 映像的名称。image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1
将 PROJECT_ID 替换为您的 Google Cloud 项目 ID。
- 如果您使用的是 Cloud Shell Editor,系统会自动保存文件。点击打开终端,返回终端窗口。
- 如果您在 Cloud Shell 中使用文本编辑器,请保存并关闭
loadgen.yaml
。
将清单部署到您的集群:
kubectl apply -f loadgen.yaml
成功后,该命令会返回以下内容:
deployment.apps/loadgenerator created service/loadgensvc created
验证您的部署
将清单部署到集群后,请验证容器是否已成功部署:
检查集群中 Pod 的状态:
kubectl get pods
该命令将返回如下状态:
NAME READY STATUS RESTARTS AGE helloserver-69b9576d96-mwtcj 1/1 Running 0 58s loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s
从
loadgen
Pod 获取应用日志。将 POD_ID 替换为上一步输出中的负载生成器 Pod 标识符。kubectl logs POD_ID
获取
hellosvc
的外部 IP 地址:kubectl get service hellosvc
输出类似于以下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m
向
hellosvc
发送请求。将 EXTERNAL_IP 替换为hellosvc
的外部 IP 地址。curl http://EXTERNAL_IP
您应该会看到服务器发送的“Hello World!”消息。
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
如果您不想删除整个项目,请执行以下操作:
删除 GKE 集群。 删除集群会删除构成集群的所有资源,例如 Compute Engine 实例、磁盘和网络资源。
gcloud container clusters delete container-intro
删除 Artifact Registry 代码库:
gcloud artifacts repositories delete container-intro --location=us-central1
后续步骤
详细了解本教程中使用的技术:
详细了解这些工具:
详细了解 Kubernetes 概念: