如果您完全不熟悉容器化工作负载,那么本教程非常适合您。本教程将引导您完成从源代码到在 GKE 上运行的容器的简单应用设置,从而向您介绍容器和容器编排。
本教程不要求您具备任何容器或 Kubernetes 使用经验。不过,如果您想在开始学习本教程之前先大致了解核心 Kubernetes 术语,请参阅开始了解 Kubernetes(或者,如果您更喜欢以漫画形式了解 Kubernetes,请参阅我们的 Kubernetes 漫画)。如需查看更详细的资源,请参阅本教程末尾的后续步骤部分。
如果您已熟悉容器和 Kubernetes,可以跳过本教程,直接开始了解 GKE 本身。
目标
- 探索简单多服务“hello world”应用。
- 从来源运行应用。
- 将应用容器化。
- 创建一个 Kubernetes 集群。
- 将容器部署到集群。
准备工作
请按照以下步骤启用 Kubernetes Engine API:- 访问 Google Cloud 控制台中的 Kubernetes Engine 页面。
- 创建或选择项目。
- 稍作等待,让 API 和相关服务完成启用过程。 此过程可能耗时几分钟。
-
Verify 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 编辑器,您可以通过点击 Cloud Shell 窗口顶部的 打开编辑器来访问该编辑器。
Emac、Vim 或 Nano,可从 Cloud Shell 中的命令行访问。
In the Google Cloud console, activate Cloud Shell.
下载示例代码
下载
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 上运行的应用:
如需详细了解 Pod、Deployment 和 Service,请参阅开始学习 Kubernetes 或本页末尾的资源。
服务器
首先,我们来看看“hello world”server
的清单:
此清单包含以下字段:
kind
表示对象的类型。metadata.name
指定 Deployment 的名称。- 第一个
spec
字段包含所需状态的说明。 spec.replicas
指定所需 Pod 的数量。spec.template
部分定义 Pod 模板。Pod 的规范中包含image
字段,该字段是从 Artifact Registry 中拉取的映像的名称。在下一步中,您会将此映像更新为您刚刚创建的新映像。
hellosvc
Service 的定义如下:
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
Deployment 的 Pod 规范包含一个名为 env
的字段。此部分定义 loadgen
所需的环境变量,此变量是您在从来源运行应用时设置的。
由于 loadgen
不接受传入请求,因此将 type
字段设置为 ClusterIP
。此类服务提供集群中的实体可以使用的稳定 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 编辑器,系统会自动保存该文件。点击打开终端,返回终端窗口。
- 如果您使用的是 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 编辑器,系统会自动保存该文件。点击打开终端,返回终端窗口。
- 如果您使用的是 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 概念: