部署容器化 web 应用

本教程介绍如何在 Docker 容器映像中打包 web 应用,并在 Google Kubernetes Engine 集群上将该容器映像作为可随用户需求进行扩缩的负载平衡副本集来运行。

目标

要在 GKE 上打包和部署您的应用,您必须:

  1. 将应用打包到 Docker 映像中
  2. 在您的机器本地运行容器(可选)
  3. 将该映像上传到注册表
  4. 创建容器集群
  5. 将应用部署到集群
  6. 在互联网上公开应用
  7. 扩展您的部署
  8. 部署应用的新版本

准备工作

请按照以下步骤启用 Kubernetes Engine API:
  1. 访问 Google Cloud Platform Console 中的 Kubernetes Engine 页面
  2. 创建或选择项目。
  3. 在 API 和相关服务启用前稍作等待。此过程可能耗时几分钟。
  4. 确保您的 Google Cloud Platform 项目已启用结算功能。

    了解如何启用结算功能

选项 A:使用 Google Cloud Shell

您可以按照本教程说明使用 Google Cloud Shell,其中预装有本教程中使用的 gclouddockerkubectl 命令行工具。如果使用 Cloud Shell,则无需在工作站上安装这些命令行工具。

要使用 Google Cloud Shell,请执行以下操作:

  1. 访问 Google Cloud Platform Console
  2. 点击 Console 窗口顶部的激活 Cloud Shell 按钮。

    Google Cloud Platform console

    一个 Cloud Shell 会话随即会在 Console 底部的新框内打开,并显示命令行提示符。

    Cloud Shell 会话

选项 B:在本地使用命令行工具

如果您希望在工作站上按照本教程中的说明操作,则需要安装以下工具:

  1. 安装 Google Cloud SDK(其中包含 gcloud 命令行工具)。
  2. 使用 gcloud 命令行工具,安装 Kubernetes 命令行工具。kubectl 用于与 Kubernetes 通信,Kubernetes 是 GKE 集群的集群编排系统:

    gcloud components install kubectl
  3. 在工作站上安装 Docker Community Edition (CE)。您将使用它为应用构建容器映像。

  4. 安装 Git 源代码控制工具以从 GitHub 获取示例应用。

gcloud 命令行工具设置默认值

为了节省您在 gcloud 命令行工具中输入项目 IDCompute Engine 地区选项的时间,您可以设置默认值:
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

第 1 步:构建容器映像

GKE 接受 Docker 映像作为应用部署格式。要构建 Docker 映像,您需要有一个应用和一个 Dockerfile。

在本教程中,您将部署一个名为 hello-app示例 web 应用,这是一个用 Go 编写的网络服务器,可在端口 80 上响应所有请求并显示“Hello, World!”消息。

该应用使用 Dockerfile 打包为 Docker 映像,Dockerfile 中包含有关该映像如何构建的说明。您将使用此 Dockerfile 打包您的应用。

要下载 hello-app 源代码,请运行以下命令:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/hello-app

通过运行以下命令在 gcloud 上检索预配置的项目 ID,并在 shell 中设置 PROJECT_ID 环境变量:

export PROJECT_ID="$(gcloud config get-value project -q)"

PROJECT_ID 的值将用于标记容器映像以将其推送到您的私有 Container Registry

要构建此应用的容器映像并标记该映像以进行上传,请运行以下命令:

docker build -t gcr.io/${PROJECT_ID}/hello-app:v1 .

此命令指示 Docker 使用当前目录中的 Dockerfile 构建映像,并使用名称(例如 gcr.io/my-project/hello-app:v1)对其进行标记。gcr.io 前缀是指 Google Container Registry,映像将托管在其中。运行此命令不会上传映像。

您可以运行 docker images 命令来验证构建是否成功:

docker images
输出:
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
gcr.io/my-project/hello-app    v1                  25cfadb1bf28        10 seconds ago      54 MB

第 2 步:上传容器映像

您需要将容器映像上传到注册表,以便 GKE 可以下载并运行该映像。

首先,配置 Docker 命令行工具以对 Container Registry 进行身份验证(您只需运行一次此命令):

gcloud auth configure-docker

您现在可以使用 Docker 命令行工具将映像上传到 Container Registry:

docker push gcr.io/${PROJECT_ID}/hello-app:v1

第 3 步:在本地运行容器(可选)

要使用本地 Docker 引擎测试容器映像,请运行以下命令:

docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/hello-app:v1

如果您使用的是 Cloud Shell,则可以点击右上角的“网络预览”按钮,查看在浏览器标签中运行的应用。否则,打开一个新的终端窗口(或 Cloud Shell 标签)并运行以下命令,以验证容器是否正常工作并以“Hello,World!”消息响应请求:

curl http://localhost:8080

看到成功响应后,您可以在运行 docker run 命令的标签页中按 Ctrl+C 来关闭容器。

第 4 步:创建容器集群

容器映像存储在注册表中后,您需要创建一个容器集群来运行容器映像。集群由运行 KubernetesCompute Engine 虚拟机实例池组成,Kubernetes 是为 GKE 提供支持的开源集群编排系统。

创建 GKE 集群后,可以使用 Kubernetes 将应用部署到集群,还可以管理应用的生命周期。

运行以下命令以创建名为 hello-cluster 的双节点集群:

gcloud container clusters create hello-cluster --num-nodes=2

集群可能需要几分钟才能完成创建。命令完成后,运行以下命令并查看集群的三个工作器虚拟机实例:

gcloud compute instances list
输出:
NAME                                          ZONE           MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
gke-hello-cluster-default-pool-07a63240-822n  us-central1-b  n1-standard-1               10.128.0.7   35.192.16.148   RUNNING
gke-hello-cluster-default-pool-07a63240-kbtq  us-central1-b  n1-standard-1               10.128.0.4   35.193.136.140  RUNNING

第 5 步:部署应用

要在 GKE 集群上部署和管理应用,您必须与 Kubernetes 集群管理系统进行通信。您通常使用 kubectl 命令行工具执行此操作。

Kubernetes 将应用表示为 Pod,这是表示一个容器(或一组紧密耦合的容器)的单元。Pod 是 Kubernetes 中最小的可部署单元。在本教程中,每个 Pod 仅包含您的 hello-app 容器。

下面的 kubectl run 命令会使 Kubernetes 在您的集群上创建名为 hello-webDeployment。Deployment 管理应用的多个运行实例(称为副本),并安排这些副本在集群中的各个节点上运行。在本例中,Deployment 将只运行应用的一个 Pod。

运行以下命令部署应用,侦听端口 8080:

kubectl run hello-web --image=gcr.io/${PROJECT_ID}/hello-app:v1 --port 8080

要查看 Deployment 创建的 Pod,请运行以下命令:

kubectl get pods
输出:
NAME                         READY     STATUS    RESTARTS   AGE
hello-web-4017757401-px7tx   1/1       Running   0          3s

第 6 步:在互联网上公开应用

默认情况下,无法从互联网访问您在 GKE 上运行的容器,因为这些容器没有外部 IP 地址。您必须明确向来自互联网的流量公开应用,为此,请运行以下命令:

kubectl expose deployment hello-web --type=LoadBalancer --port 80 --target-port 8080

上面的 kubectl expose 命令创建了一个 Service 资源,它为应用的 Pod 提供网络和 IP 支持。GKE 为您的应用创建外部 IP 和负载平衡器(需要付费)。

--port 标志指定在负载平衡器上配置的端口号,--target-port 标志指定由上一步中的 kubectl run 命令创建的 Pod 使用的端口号。

确定应用的外部 IP 地址后,请复制该 IP 地址。将浏览器指向此网址(例如 http://203.0.113.0)以检查您的应用是否可访问。

第 7 步:扩展应用

您可以使用 kubectl scale 命令向应用的 Deployment 资源添加更多副本。要向 Deployment 再添加两个副本(总共三个),请运行以下命令:

kubectl scale deployment hello-web --replicas=3

您可以通过运行以下命令来查看在集群上运行的新副本:

kubectl get deployment hello-web
输出:
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-web   3         3         3            2           1m
kubectl get pods
输出:
NAME                         READY     STATUS    RESTARTS   AGE
hello-web-4017757401-ntgdb   1/1       Running   0          9s
hello-web-4017757401-pc4j9   1/1       Running   0          9s
hello-web-4017757401-px7tx   1/1       Running   0          1m

现在,您有多个应用实例彼此独立运行,您可以使用 kubectl scale 命令调整应用的容量。

您在上一步中预配的负载平衡器将开始自动将流量路由到这些新副本。

第 8 步:部署新版本的应用

GKE 的滚动更新机制可确保您的应用保持正常运行,并且即使在系统将所有正在运行的副本中的旧容器映像实例替换为新容器映像时也依然可用。

您可以通过构建相同的源代码并将其标记为 v2 来为应用的 v2 版本创建映像(或者您可以在构建映像之前将 "Hello, World!" 字符串更改为 "Hello, GKE!"):

docker build -t gcr.io/${PROJECT_ID}/hello-app:v2 .

然后将映像推送到 Google Container Registry:

docker push gcr.io/${PROJECT_ID}/hello-app:v2

现在,通过映像更新将滚动更新应用于现有部署:

kubectl set image deployment/hello-web hello-web=gcr.io/${PROJECT_ID}/hello-app:v2

通过 http://[EXTERNAL_IP] 再次访问应用,您会看到所做的更改已生效。

清理

为避免因本教程中使用的资源而导致我们向您的 Google Cloud Platform 帐号收取费用,请执行以下操作:

完成本教程后,请按照以下步骤移除以下资源,以防止您的帐号产生不必要的费用:

  1. 删除 Service:此步骤将取消并释放为 Service 创建的 Cloud Load Balancer:

    kubectl delete service hello-web

  2. 删除容器集群:此步骤将删除构成容器集群的资源,如计算实例、磁盘和网络资源。

    gcloud container clusters delete hello-cluster

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Kubernetes Engine 教程