本教程介绍如何将 Web 应用打包到 Docker 容器映像中,并在 Google Kubernetes Engine (GKE) 集群上运行该容器映像。然后将 Web 应用部署为可随用户需求而扩缩、支持负载均衡的副本集。
目标
- 将示例 Web 应用打包到 Docker 映像中。
- 将 Docker 映像上传到 Artifact Registry。
- 创建 GKE 集群。
- 将示例应用部署到集群。
- 管理部署的自动扩缩。
- 将示例应用公开发布到互联网。
- 部署示例应用的新版本。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Enable the Compute Engine, Artifact Registry, and Google Kubernetes Engine APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Enable the Compute Engine, Artifact Registry, and Google Kubernetes Engine APIs.
激活 Cloud Shell
Cloud Shell 预安装了本教程中使用的 gcloud
、docker
、kubectl
命令行工具。
- 前往 Google Cloud 控制台。
点击 Google Cloud 控制台窗口顶部的激活 Cloud Shell 按钮。
一个 Cloud Shell 会话随即会在 Google Cloud 控制台底部的新框内打开,并显示命令行提示符。
创建代码库
在本教程中,您将映像存储在 Artifact Registry 中并从注册表中部署。在本快速入门中,您需要创建一个名为 hello-repo
的代码库。
将
PROJECT_ID
环境变量设置为您的 Google Cloud 项目 ID (PROJECT_ID
)。构建容器映像并将其推送到代码库时,您将使用此环境变量。export PROJECT_ID=PROJECT_ID
确认
PROJECT_ID
环境变量的值正确无误:echo $PROJECT_ID
设置 Google Cloud CLI 的项目 ID:
gcloud config set project $PROJECT_ID
输出:
Updated property [core/project].
使用以下命令创建
hello-repo
代码库:gcloud artifacts repositories create hello-repo \ --repository-format=docker \ --location=REGION \ --description="Docker repository"
将
REGION
替换为代码库的地区,例如us-west1
。要查看可用位置的列表,请运行以下命令:gcloud artifacts locations list
构建容器映像
在本教程中,您将部署一个名为 hello-app
的示例 Web 应用,这是一个用 Go 编写的 Web 服务器,可在端口 8080 上响应所有请求并显示 Hello, World!
消息。
GKE 接受 Docker 映像作为应用部署格式。
在将 hello-app
部署到 GKE 之前,您必须将 hello-app
源代码打包为 Docker 映像。
如需构建 Docker 映像,您需要具有源代码和 Dockerfile。 Dockerfile 中包含有关如何构建该映像的说明。
通过运行以下命令下载
hello-app
源代码和 Dockerfile:git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/quickstarts/hello-app
为
hello-app
构建和标记 Docker 映像:docker build -t REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1 .
此命令指示 Docker 使用当前目录中的
Dockerfile
构建映像,将其保存到本地环境,并使用名称(例如us-west1-docker.pkg.dev/my-project/hello-repo/hello-app:v1
)对其进行标记。该映像将在下一部分中被推送到 Artifact Registry。PROJECT_ID
变量会将容器映像与您的 Google Cloud 项目中的hello-repo
代码库相关联。us-west1-docker.pkg.dev
前缀是指您的代码库的区域主机 Artifact Registry。
运行
docker images
命令以验证构建是否成功:docker images
输出:
REPOSITORY TAG IMAGE ID CREATED SIZE us-west1-docker.pkg.dev/my-project/hello-repo/hello-app v1 25cfadb1bf28 10 seconds ago 54 MB
向您的服务账号添加 IAM 政策绑定:
gcloud artifacts repositories add-iam-policy-binding hello-repo \ --location=REGION \ --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role="roles/artifactregistry.reader"
将
PROJECT_NUMBER
替换为您的项目编号。
在本地运行容器(可选)
使用本地 Docker 引擎测试容器映像:
docker run --rm -p 8080:8080 REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
点击网页预览按钮 ,然后选择
8080
端口号。GKE 会在新的浏览器窗口中打开其代理服务的预览网址。
将 Docker 映像推送到 Artifact Registry
您必须将容器映像上传到注册表,以便您的 GKE 集群可以下载并运行该容器映像。在本教程中,您需要将容器存储在 Artifact Registry 中。
配置 Docker 命令行工具以向 Artifact Registry 进行身份验证:
gcloud auth configure-docker REGION-docker.pkg.dev
将刚刚构建的 Docker 映像推送到代码库:
docker push REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
创建 GKE 集群
现在,Docker 映像已存储在 Artifact Registry 中,接下来创建 GKE 集群来运行 hello-app
。GKE 集群由运行 Kubernetes 的 Compute Engine 虚拟机实例池组成,Kubernetes 是为 GKE 提供支持的开源集群编排系统。
Cloud Shell
设置您的 Compute Engine 区域:
gcloud config set compute/region REGION
对于 Standard 可用区集群,请设置离 Artifact Registry 代码库最近的 Compute Engine 可用区。
创建名为
hello-cluster
的集群:gcloud container clusters create-auto hello-cluster
创建 GKE 集群并进行健康检查需要几分钟的时间。如需在 GKE Standard 集群上运行本教程,请改用
gcloud container clusters create
命令。
控制台
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
点击 add_box 创建。
对于 GKE Autopilot,点击配置。
在名称字段中,输入名称
hello-cluster
。从区域下拉列表中选择 Compute Engine 区域,例如
us-west1
。点击创建。
等待集群创建完成。集群准备就绪后,集群名称旁边会显示一个对勾标记。
将示例应用部署到 GKE
您现在可以将构建的 Docker 映像部署到 GKE 集群。
Kubernetes 将应用表示为 Pod,这是可扩缩的单元,包含一个或多个容器。Pod 是 Kubernetes 中最小的可部署单元。通常,您可以将 Pod 部署为可扩缩并分布在整个集群中的副本集。部署副本集的一种方法是通过 Kubernetes 部署来完成操作。
在本部分中,您将创建一个 Kubernetes Deployment,以便在您的集群上运行 hello-app
。此 Deployment 具有副本 (Pod)。一个部署 Pod 仅包含一个容器:即 hello-app
Docker 映像。您还将创建一个 HorizontalPodAutoscaler 资源,根据 CPU 负载将 Pod 数量从 3 个扩缩为 1 到 5 个之间。
Cloud Shell
确保您已连接到 GKE 集群。
gcloud container clusters get-credentials hello-cluster --region REGION
为您的
hello-app
Docker 映像创建 Kubernetes 部署。kubectl create deployment hello-app --image=REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
将部署副本的基准数量设置为 3。
kubectl scale deployment hello-app --replicas=3
为您的部署创建一个
HorizontalPodAutoscaler
资源。kubectl autoscale deployment hello-app --cpu-percent=80 --min=1 --max=5
如需查看已创建的 Pod,请运行以下命令:
kubectl get pods
输出:
NAME READY STATUS RESTARTS AGE hello-app-784d7569bc-hgmpx 1/1 Running 0 90s hello-app-784d7569bc-jfkz5 1/1 Running 0 90s hello-app-784d7569bc-mnrrl 1/1 Running 0 95s
控制台
转到 Google Cloud 控制台中的工作负载页面。
点击 add_box 部署。
在指定容器部分中,选择现有容器映像。
在映像路径字段中,点击选择。
在选择容器映像窗格中,选择您已推送到 Artifact Registry 的
hello-app
映像,然后点击选择。在容器部分中,点击完成,然后点击继续。
在配置部分中的标签下,输入
app
作为键,输入hello-app
作为值。在配置 YAML 下,点击查看 YAML。这将打开一个 YAML 配置文件,该文件表示将要部署到集群中的两个 Kubernetes API 资源:一个 Deployment 资源,以及一个用于该 Deployment 资源的
HorizontalPodAutoscaler
资源。点击关闭,然后点击部署。
Deployment Pod 准备就绪后,Deployment 详情页面随即打开。
在代管 pod 下,注意 Deployment 三个正在运行的
hello-app
Pod。
将示例应用公开发布到互联网
虽然 Pod 确实具有单独分配的 IP 地址,但这些 IP 地址只能从集群内部访问。此外,GKE Pod 设计是临时的,可根据扩缩需求启动或关闭。当 Pod 因错误而崩溃时,GKE 会自动重新部署该 Pod,并且每次都会为 Pod 分配新的 IP 地址。
这意味着对于任何部署,与活跃 Pod 组对应的 IP 地址集是动态的。我们需要一种方法来执行以下操作:1) 将 Pod 组合成一个静态主机名,以及 2) 将集群外的一组 Pod 公开发布到互联网。
Kubernetes 服务可同时解决这两个问题。
这些服务会将 Pod 组合成一个静态 IP 地址,并且可从集群内的任何 Pod 进行访问。
GKE 还会为该静态 IP 地址分配 DNS 主机名。例如 hello-app.default.svc.cluster.local
。
GKE 中的默认服务类型为 ClusterIP,其中服务将获得只能从集群内部访问的 IP 地址。
如需在集群外部公开 Kubernetes 服务,请创建 LoadBalancer
类型的服务。此类型的服务会为可通过互联网访问的一组 Pod 生成外部负载均衡器 IP 地址。
在本部分中,您将使用 LoadBalancer
类型的 Service 将 hello-app
Deployment 公开发布到互联网。
Cloud Shell
使用
kubectl expose
命令为hello-app
部署生成 Kubernetes 服务:kubectl expose deployment hello-app --name=hello-app-service --type=LoadBalancer --port 80 --target-port 8080
此处,
--port
标志指定在负载均衡器上配置的端口号,--target-port
标志指定hello-app
容器正在监听的端口号。运行以下命令以获取
hello-app-service
的服务详情:kubectl get service
输出:
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-app-service 10.3.251.122 203.0.113.0 80:30877/TCP 10s
将
EXTERNAL_IP
地址复制到剪贴板(例如:203.0.113.0
)。
控制台
转到 Google Cloud 控制台中的工作负载页面。
点击 hello-app。
在“Deployment 详情”页面中,点击 list 操作 > 公开。
在公开对话框中,将目标端口设置为
8080
。这是hello-app
容器监听的端口。从 Service 类型下拉列表中,选择负载均衡器。
点击公开,为
hello-app
创建 Kubernetes Service。负载均衡器准备就绪后,Service 详情页面随即打开。
向下滚动到外部端点字段,然后复制 IP 地址。
现在,hello-app
Pod 已通过 Kubernetes 服务公开发布到互联网,您可以打开新的浏览器标签页,然后导航到先前复制到剪贴板中的服务 IP 地址。您会看到一条 Hello, World!
消息以及一个 Hostname
字段。Hostname
对应于向浏览器传送 HTTP 请求的三个 hello-app
Pod 中的一个。
部署示例应用的新版本
在本部分中,您将通过构建新的 Docker 映像并将其部署到 GKE 集群,来将 hello-app
升级到新版本。
GKE 的滚动更新功能让您可以在不停机的情况下更新 Deployment。在滚动更新期间,GKE 集群将逐步将现有 hello-app
Pod 替换为包含新版本的 Docker 映像的 Pod。在更新期间,负载均衡器服务仅将流量路由到可用的 Pod。
返回到 Cloud Shell,现在您已在其中克隆了 hello 应用源代码和 Dockerfile。 更新
main.go
文件中的函数hello()
以报告新版本2.0.0
。构建并标记新的
hello-app
Docker 映像。docker build -t REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2 .
将该映像推送到 Artifact Registry。
docker push REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2
现在,您可以更新 hello-app
Kubernetes 部署来使用新的 Docker 映像。
Cloud Shell
使用
kubectl set image
命令通过映像更新将滚动更新应用于现有hello-app
Deployment:kubectl set image deployment/hello-app hello-app=REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2
运行
v1
映像的 Pod 停止运行后,系统会启动运行v2
映像的新 Pod。watch kubectl get pods
输出:
NAME READY STATUS RESTARTS AGE hello-app-89dc45f48-5bzqp 1/1 Running 0 2m42s hello-app-89dc45f48-scm66 1/1 Running 0 2m40s
在单独的标签页中,再次导航到
hello-app-service
外部 IP。您现在应该看到Version
被设置为2.0.0.
。
控制台
转到 Google Cloud 控制台中的工作负载页面。
点击 hello-app。
在 Deployment 详情页面上,点击 list 操作 > 滚动更新。
在滚动更新对话框中,将 hello-app 的图片字段设置为
REGION-docker.pkg.dev/PROJECT_ID/hello-repo/hello-app:v2
。点击更新。
在 Deployment 详情页面上,查看有效修订版本部分。您现在应该看到两个修订版本:1 和 2。修订版本 1 对应于您之前创建的初始 Deployment。修订版本 2 是您刚刚执行的滚动更新。
片刻之后,刷新页面。在代管 Pod 下,
hello-app
的所有副本现在均对应于修订版本 2。在单独的标签页中,再次导航到您复制的 Service IP 地址。
Version
应为2.0.0.
清除数据
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除 Service:此步骤将取消并释放为 Service 创建的 Cloud Load Balancer:
kubectl delete service hello-app-service
删除集群:此步骤将删除构成集群的资源,如计算实例、磁盘和网络资源:
gcloud container clusters delete hello-cluster --region REGION
删除容器映像:此操作会删除推送到 Artifact Registry 的 Docker 映像。
gcloud artifacts docker images delete \ REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1 \ --delete-tags --quiet gcloud artifacts docker images delete \ REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2 \ --delete-tags --quiet
后续步骤
阅读负载均衡器教程,其中演示了 web 应用的高级负载均衡配置。
为您的应用配置静态 IP 和域名。
浏览其他 Kubernetes Engine 教程。
探索有关 Google Cloud 的参考架构、图表和最佳实践。查看我们的 Cloud Architecture Center。