首充送50%
续费低至5折
AWS CDN 1折购
免费代充值
免费选购指南
免费协助迁移

使用 Redis 和 PHP 创建留言板

2023-07-25

本教程演示了如何使用 Google Kubernetes Engine (GKE) 构建多层 Web 应用。本教程中的应用是一个留言板,访问者可在一份日志中输入文字,并查看其中最新的几个日志条目。


本教程介绍如何使用负载平衡器在外部 IP 上设置留言板 Web 服务,以及如何使用单个主实例 (Leader) 和多个副本(关注者)运行 Redis 集群。

该示例强调了一些重要的 GKE 概念:

  • 使用 YAML 清单文件的声明式配置
  • Deployment,这是 Kubernetes 资源,用于确定一组副本 Pod 的配置
  • Service,用于为一组 Pod 创建内部和外部负载平衡器

目标如需在 GKE 上部署和运行留言板应用,请执行以下操作:


  1. 设置 Redis Leader
  2. 设置两个 Redis 关注者
  3. 设置留言板 Web 前端
  4. 访问留言板网站
  5. 扩展留言板网络前端

下图展示了完成上述目标后创建的集群架构概览:留言板 GKE 图示


费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。


完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理


准备工作请按照以下步骤启用 Kubernetes Engine API:

  1. 访问 Google Cloud Console 中的 Kubernetes Engine 页面
  2. 创建或选择项目。
  3. 稍作等待,让 API 和相关服务完成启用过程。 此过程可能耗时几分钟。
  4. 确保您的 Google Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能。

安装本教程中使用的以下命令行工具:

  • gcloud 用于创建和删除 Kubernetes Engine 集群。gcloud 包含在 gcloud CLI 中。
  • kubectl 用于管理 Kubernetes(即 Kubernetes Engine 使用的集群编排系统)。您可以使用 gcloud 安装 kubectl

设置 Google Cloud CLI 的默认值为了节省您在 gcloud CLI 中输入项目 IDCompute Engine 可用区或区域选项的时间,您可以设置默认值:


gcloud config set project project-id

根据您在 GKE 中选择使用的操作模式,然后指定默认的可用区或区域。如果您使用标准模式,您的集群是可用区级(对于本教程),因此请设置您的默认计算可用区。如果您使用 Autopilot 模式,您的集群是区域级,因此请设置您的默认计算区域

Autopilot

标准


运行以下命令,将 compute-region 替换为您的计算区域,例如 us-west1


  gcloud config set compute/region compute-region

创建 GKE 集群

第一步是创建用于运行留言板应用和 Redis 服务的 GKE 集群

创建名为 guestbook 的 GKE 集群:

Autopilot

标准


 gcloud container clusters create-auto guestbook

您可以使用以下命令列出项目中运行的集群:


gcloud container clusters list
gcloud container clusters describe guestbook
注意:如果您使用的是现有 Google Kubernetes Engine 集群,或者已通过 Google Cloud Console 创建集群,则需要运行以下命令来检索集群凭据,并使用这些凭据配置 kubectl 命令行工具:

gcloud container clusters get-credentials guestbook如果您已使用上面列出的 gcloud container clusters create 命令创建集群,则无需执行此步骤。

设置 Redis Leader

留言板应用使用 Redis 来存储其数据。该应用将数据写入 Redis Leader 实例,并从多个 Redis 关注者实例中读取数据。第一步是部署 Redis Leader。

首先,克隆示例清单:


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

使用名为 redis-leader-deployment 的清单文件部署 Redis Leader。此清单文件指定运行单个副本 Redis Leader Pod 的 Kubernetes Deployment:

guestbook/redis-leader-deployment.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: apps/v1kind: Deploymentmetadata:  name: redis-leader  labels:    app: redis    role: leader    tier: backendspec:  replicas: 1  selector:    matchLabels:      app: redis  template:    metadata:      labels:        app: redis        role: leader        tier: backend    spec:      containers:      - name: leader        image: 'docker.io/redis:6.0.5'        resources:          requests:            cpu: 100m            memory: 100Mi        ports:        - containerPort: 6379---

运行以下命令以部署 Redis Leader:


kubectl apply -f redis-leader-deployment.yaml

验证 Redis Leader Pod 是否正在运行:


kubectl get pods
输出:

NAME                           READY     STATUS    RESTARTS   AGE
redis-leader-343230949-qfvrq   1/1       Running   0          43s

运行以下命令以查看 Redis Leader Pod 中的日志:


kubectl logs deployment/redis-leader

输出:


1:M 24 Jun 2020 14:48:20.917 * Ready to accept connections


创建 Redis Leader 服务

留言板应用需要与 Redis Leader 通信才能写入其数据。您可以创建一个 Service 来代理传输到 Redis Leader Pod 的流量。

Service 是 Kubernetes 抽象,定义了一个逻辑 Pod 集及其访问政策。Service 实际上是一个命名的负载平衡器,可将流量代理传输到一个或多个 Pod。 设置 Service 时,您需要根据 Pod 标签来说明要代理哪些 Pod。

查看 redis-leader-service.yaml 清单文件,该文件描述了 Redis Leader 的 Service 资源:

guestbook/redis-leader-service.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: v1kind: Servicemetadata:  name: redis-leader  labels:    app: redis    role: leader    tier: backendspec:  ports:  - port: 6379    targetPort: 6379  selector:    app: redis    role: leader    tier: backend---

此清单文件创建了一项名为 redis-leader 的 Service,该 Service 带有一组标签选择器。这些标签与上一步中部署的标签集匹配。因此,该 Service 将网络流量路由到上一步中创建的 Redis Leader Pod。

清单的 ports 部分声明了单个端口映射。在本例中,此 Service 将 port: 6379 上的流量路由到匹配指定 selector 标签的容器的 targetPort: 6379。请注意,Deployment 中使用的 containerPort 必须与 targetPort 匹配才能将流量路由到 Deployment。

通过运行以下命令来启动 Redis Leader Service:


kubectl apply -f redis-leader-service.yaml

验证 Service 已成功创建:


kubectl get service
输出:

NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.51.240.1     <none>        443/TCP    42s
redis-leader   10.51.242.233   <none>        6379/TCP   12s

设置 Redis 关注者

虽然 Redis Leader 属于单个 Pod,但您可以通过添加一些 Redis 关注者副本来为其实现高可用性,并满足流量需求。

查看 redis-follower-deployment.yaml 清单文件,该文件描述了 Redis 关注者 Pod 的 Deployment:

guestbook/redis-follower-deployment.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: apps/v1kind: Deploymentmetadata:  name: redis-follower  labels:    app: redis    role: follower    tier: backendspec:  replicas: 2  selector:    matchLabels:      app: redis  template:    metadata:      labels:        app: redis        role: follower        tier: backend    spec:      containers:      - name: follower        image: us-docker.pkg.dev/google-samples/containers/gke/gb-redis-follower:v2        resources:          requests:            cpu: 100m            memory: 100Mi        ports:        - containerPort: 6379---

如需创建 Redis 关注者 Deployment,请运行以下命令:


kubectl apply -f redis-follower-deployment.yaml

通过查询 Pod 列表,验证这两个 Redis 关注者副本是否正在运行:


kubectl get pods
输出:

NAME                              READY   STATUS    RESTARTS   AGE
redis-follower-76588f55b7-bnsq6   1/1     Running   0          27s
redis-follower-76588f55b7-qvtws   1/1     Running   0          27s
redis-leader-dd446dc55-kl7nl      1/1     Running   0          119s

获取其中一个 Redis 关注者的 Pod 日志。


kubectl logs deployment/redis-follower
输出:

1:M 24 Jun 2020 14:50:43.617 * Background saving terminated with success
1:M 24 Jun 2020 14:50:43.617 * Synchronization with replica 10.12.3.4:6379 succeeded

创建 Redis 关注者服务

留言板应用需要与 Redis 关注者通信以读取数据。如需让 Redis 关注者更容易被发现,您必须设置其他 Service。

redis-follower-service.yaml 定义了 Redis 关注者的 Service 配置:

guestbook/redis-follower-service.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: v1kind: Servicemetadata:  name: redis-follower  labels:    app: redis    role: follower    tier: backendspec:  ports:    # the port that this service should serve on  - port: 6379  selector:    app: redis    role: follower    tier: backend---

此文件定义一项在端口 6379 上运行的名为 redis-follower 的 Service。请注意,Service 的 selector 字段与上一步中创建的 Redis 关注者 Pod 匹配。

运行以下命令来创建 redis-follower Service:


kubectl apply -f redis-follower-service.yaml

验证 Service 已成功创建:


kubectl get service
输出:

NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.51.240.1     <none>        443/TCP    1m
redis-leader   10.51.242.233   <none>        6379/TCP   49s
redis-follower 10.51.247.238   <none>        6379/TCP   3s

设置留言板 Web 前端

在启动并运行了留言板的 Redis 存储后,可以启动留言板 Web 服务器。与 Redis 关注者一样,该前端将使用 Kubernetes Deployment 进行部署。

留言板应用使用 PHP 前端。该前端配置为根据请求属于读取请求还是写入请求,与 Redis 关注者 Service 或 Redis Leader Service 进行通信。该前端公开了一个 JSON 接口,并提供基于 jQuery-Ajax 的用户体验。

查看 frontend-deployment.yaml 清单文件,该文件描述了留言板 Web 服务器的 Deployment:

guestbook/frontend-deployment.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: apps/v1kind: Deploymentmetadata:  name: frontendspec:  replicas: 3  selector:    matchLabels:        app: guestbook        tier: frontend  template:    metadata:      labels:        app: guestbook        tier: frontend    spec:      containers:      - name: php-redis        image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5        env:        - name: GET_HOSTS_FROM          value: 'dns'        resources:          requests:            cpu: 100m            memory: 100Mi        ports:        - containerPort: 80---

如需创建留言板 Web 前端 Deployment,请运行以下命令:


kubectl apply -f frontend-deployment.yaml

如需验证这三个副本正在运行,请查询用于标识 Web 前端的标签列表:


kubectl get pods -l app=guestbook -l tier=frontend
输出:

NAME                        READY   STATUS    RESTARTS   AGE
frontend-7b78458576-8kp8s   1/1     Running   0          37s
frontend-7b78458576-gg86q   1/1     Running   0          37s
frontend-7b78458576-hz87g   1/1     Running   0          37s

清单文件指定了环境变量 GET_HOSTS_FROM=dns。当您将配置提供给留言板 Web 前端应用时,前端应用会使用主机名 redis-followerredis-leader 来执行 DNS 查找。DNS 查找将查找您在先前步骤中创建的适当 Service 的 IP 地址。此概念称为 DNS 服务发现。

在外部 IP 地址公开前端

您在先前步骤中创建的 redis-followerredis-leader Service 只能在 GKE 集群中访问,因为 Service 的默认类型是 ClusterIPClusterIP 为 Service 指向的 Pod 集提供单个 IP 地址。此 IP 地址只能在集群内访问。

但是,您需要让留言板 Web 前端 Service 可供外部用户查看。 也就是说,您希望客户端能够从 GKE 集群外部请求 Service。如需完成此请求,您可以根据需求在 Service 配置中指定 type: LoadBalancertype: NodePort。在此示例中,您将使用 type: LoadBalancer。指定此配置的 frontend-service.yaml 清单文件如下所示:

guestbook/frontend-service.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: v1kind: Servicemetadata:  name: frontend  labels:    app: guestbook    tier: frontendspec:  type: LoadBalancer  ports:    # the port that this service should serve on  - port: 80  selector:    app: guestbook    tier: frontend---

创建 frontend Service 时,GKE 会创建一个负载平衡器和一个外部 IP 地址。请注意,这些资源需要付费ports 部分下方的端口声明指定了 port: 80,未指定 targetPort。如果忽略 targetPort 属性,则默认为 port 字段的值。在本例中,此 Service 将端口 80 上的外部流量路由到 frontend Deployment 中容器的端口 80。

要创建 Service,请运行以下命令:


kubectl apply -f frontend-service.yaml

访问留言板网站

如需访问留言板 Service,请通过运行以下命令找到您设置的 Service 的外部 IP 地址:


kubectl get service frontend
输出:

NAME       CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
frontend   10.51.242.136   109.197.92.229     80:32372/TCP   1m

注意:创建负载平衡器时,EXTERNAL-IP 列可能会显示 <pending>。可能需要几分钟时间才能创建负载平衡器。

复制 EXTERNAL-IP 列中的 IP 地址,然后在浏览器中加载页面。

在 GKE 上运行的留言板

如需尝试添加一些留言板条目,请尝试输入信息帖,然后点击提交。您输入的消息会显示在前端。此消息表示数据已通过您之前创建的 Service 成功添加到 Redis。

扩充 Web 前端

假设您的留言板应用已经运行了一段时间,公共宣传突然激增。您决定为前端添加更多 Web 服务器。由于您的服务器被定义为使用 Deployment 控制器的服务,因此您可以轻松进行扩展。

通过运行以下命令,将 frontend Pod 数量扩展到 5 个:


kubectl scale deployment frontend --replicas=5

输出:


deployment.extensions/frontend scaled


系统会更新 Deployment 的配置,以指定现在应该运行 5 个副本:Deployment 会调整正在运行的 Pod 数量,以匹配配置。如需验证副本数量,请运行以下命令:


kubectl get pods
输出:

NAME                             READY     STATUS    RESTARTS   AGE
frontend-88237173-3s3sc          1/1       Running   0          1s
frontend-88237173-twgvn          1/1       Running   0          1s
frontend-88237173-5p257          1/1       Running   0          23m
frontend-88237173-84036          1/1       Running   0          23m
frontend-88237173-j3rvr          1/1       Running   0          23m
redis-leader-343230949-qfvrq     1/1       Running   0          54m
redis-follower-132015689-dp23k   1/1       Running   0          37m
redis-follower-132015689-xq9v0   1/1       Running   0          37m

您可以使用同一命令缩减前端 Pod 的数量。


清理

为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

  1. 删除 Service:此步骤将取消并释放为 frontend Service 创建的 Cloud Load Balancer:kubectl delete service frontend
  2. 等待系统完成删除为 frontend Service 预配的负载平衡器:当您运行 kubectl delete 时,系统会在后台异步删除负载平衡器。观察以下命令的输出,直到负载平衡器被删除:gcloud compute forwarding-rules list
  3. 删除 GKE 集群:此步骤将删除构成 GKE 集群的资源,如计算实例、磁盘和网络资源。gcloud container clusters delete guestbook