Example: Deploying PHP Guestbook application with Redis
本教程将向你展示如何使用 Kubernetes 和 Docker 构建并部署一个简单的(不适用于生产环境)多层 Web 应用程序。此示例包含以下组件:
- 一个单实例的 Redis 用于存储留言簿条目
- 多个 Web 前端实例
Objectives
- 启动一个 Redis 主节点。
- 启动两个 Redis 从节点。
- 启动留言簿前端服务。
- 暴露并查看前端服务。
- 清理资源。
Before you begin
你需要拥有一个 Kubernetes 集群,并且必须将 kubectl 命令行工具配置为与你的集群进行通信。 建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。 如果你还没有集群,你可以使用 Minikube 创建一个,或者你也可以使用以下这些 Kubernetes 在线实验环境之一:
你的 Kubernetes 服务器版本必须为 v1.14 或更高。 要检查版本,请输入 kubectl version 命令。
Start up the Redis Database
留言簿应用程序使用 Redis 来存储其数据。
Creating the Redis Deployment
下面给出的清单文件指定了一个 Deployment 控制器,该控制器会运行一个单副本的 Redis Pod。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-leader
labels:
app: redis
role: leader
tier: backend
spec:
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: 63791.在你下载清单文件的目录中打开一个终端窗口。
2.根据 redis-leader-deployment.yaml 文件应用 Redis Deployment:
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml3.查询 Pod 列表以验证 Redis Pod 是否正在运行:
kubectl get pods响应应该类似于以下内容:
NAME READY STATUS RESTARTS AGE
redis-leader-fb76b4755-xjr2n 1/1 Running 0 13s4.运行以下命令来查看 Redis leader Pod ( Redis主节点 )的日志:
kubectl logs -f deployment/redis-leaderCreating the Redis leader Service
留言簿应用程序需要与 Redis 进行通信以写入数据。你需要应用一个Service,将流量代理到 Redis Pod。Service定义了访问 Pod 的策略。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: v1
kind: Service
metadata:
name: redis-leader
labels:
app: redis
role: leader
tier: backend
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
role: leader
tier: backend1.根据下面的 redis-leader-service.yaml 文件来应用 Redis Service:
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml2.查询Service列表,以验证 Redis Service是否正在运行:
kubectl get service响应应该与以下内容类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 1m
redis-leader ClusterIP 10.103.78.24 <none> 6379/TCP 16s注意:
此清单文件会创建一个名为 redis-leader 的Service,该Service带有一组标签,这些标签与之前定义的标签相匹配,这样Service就能将网络流量路由到 Redis Pod。
Set up Redis followers
虽然 Redis 主节点只是一个 Pod,但你可以通过添加几个 Redis 从节点(即副本)来使其具备高可用性,并满足流量需求。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-follower
labels:
app: redis
role: follower
tier: backend
spec:
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: 63791.根据下面的 redis-follower-deployment.yaml 文件来应用 Redis Deployment:
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml2.通过查询 Pod 列表来验证两个 Redis 从节点副本是否正在运行:
kubectl get pods3.响应应该类似如下内容:
NAME READY STATUS RESTARTS AGE
redis-follower-dddfbdcc9-82sfr 1/1 Running 0 37s
redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 38s
redis-leader-fb76b4755-xjr2n 1/1 Running 0 11mCreating the Redis follower service
留言簿应用程序需要与 Redis follower进行通信以读取数据。为了让 Redis follower 能够被发现,你必须设置另一个Service。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: v1
kind: Service
metadata:
name: redis-follower
labels:
app: redis
role: follower
tier: backend
spec:
ports:
# the port that this service should serve on
- port: 6379
selector:
app: redis
role: follower
tier: backend1.根据下面的 redis-follower-service.yaml 文件应用 Redis Service:
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml2.查询Service列表以验证 Redis Service是否正在运行:
kubectl get service响应应该类似如下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d19h
redis-follower ClusterIP 10.110.162.42 <none> 6379/TCP 9s
redis-leader ClusterIP 10.103.78.24 <none> 6379/TCP 6m10s注意:
此清单文件会创建一个名为 redis-follower 的Service,该Service带有一组与之前定义的标签相匹配的标签,这样服务就能将网络流量路由到 Redis Pod。
Set up and Expose the Guestbook Frontend
现在你的留言簿应用的 Redis 存储已经启动并运行,接下来启动留言簿的 Web 服务器。和 Redis follower一样,前端应用也是通过 Kubernetes 的 Deployment 来部署的。
留言簿应用使用 PHP 作为前端。它被配置为根据请求是读操作还是写操作,与 Redis follower Service或leader Service进行通信。前端对外提供一个 JSON 接口,并采用基于 jQuery - Ajax 的用户体验(UX)设计。
Creating the Guestbook Frontend Deployment
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
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: 801.根据 frontend-deployment.yaml 文件应用前端Deployment:
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml2.查询Pod列表,验证前端应用是否被部署:
kubectl get pods -l app=guestbook -l tier=frontend响应应该与以下内容类似:
NAME READY STATUS RESTARTS AGE
frontend-85595f5bf9-5tqhb 1/1 Running 0 47s
frontend-85595f5bf9-qbzwm 1/1 Running 0 47s
frontend-85595f5bf9-zchwc 1/1 Running 0 47sCreating the Frontend Service
你所应用的 Redis Service仅可在 Kubernetes 集群内部访问,因为服务的默认类型是 ClusterIP(集群内部 IP)。ClusterIP 为Service所指向的一组 Pod 提供一个单一的 IP 地址,该 IP 地址仅在集群内部可访问。
如果你希望外部访客能够访问你的留言簿,就必须将前端Service配置为对外可见,这样客户端就可以从 Kubernetes 集群外部请求该Service。不过,即使Service使用的是 ClusterIP,Kubernetes 用户也可以使用 kubectl port-forward 命令来访问该Service。
注意:
一些云服务提供商,如谷歌计算引擎(Google Compute Engine)或谷歌 Kubernetes 引擎(Google Kubernetes Engine),支持外部负载均衡器。如果你的云服务提供商支持负载均衡器,并且你想使用它,请取消 type: LoadBalancer 这一行的注释。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# if your cluster supports it, uncomment the following to automatically create
# an external load-balanced IP for the frontend service.
# type: LoadBalancer
#type: LoadBalancer
ports:
# the port that this service should serve on
- port: 80
selector:
app: guestbook
tier: frontend1.从 frontend-service.yaml 文件中应用前端Service:
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml2.查询Service列表以验证前端Service是否正在运行:
kubectl get services响应应该与以下内容类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend ClusterIP 10.97.28.230 <none> 80/TCP 19s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d19h
redis-follower ClusterIP 10.110.162.42 <none> 6379/TCP 5m48s
redis-leader ClusterIP 10.103.78.24 <none> 6379/TCP 11mViewing the Frontend Service via kubectl port-forward
1.运行以下命令,将你本地机器上的 8080 端口转发到Service的 80 端口。
kubectl port-forward svc/frontend 8080:80响应应该与以下内容类似:
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 802.在你的浏览器中打开网址 http://localhost:8080,即可查看留言簿。 (opens in a new tab)
Viewing the Frontend Service via LoadBalancer
1.运行以下命令来获取前端Service的 IP 地址。
kubectl get service frontend响应应该与以下内容类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.242.136 109.197.92.229 80:32372/TCP 1m2.复制外部 IP 地址,并在浏览器中打开该地址对应的页面,以查看你的留言簿。
注意:
尝试输入一条消息,然后点击 “提交” 来添加一些留言簿条目。你输入的消息会显示在前端界面上。这表明数据已通过你之前创建的Service成功添加到 Redis 中。
Scale the Web Frontend
由于你的服务器被定义为使用Deployment controller的服务,因此你可以根据需要进行扩缩容操作。
1.运行以下命令来增加前端 Pod 的数量:
kubectl scale deployment frontend --replicas=52.查询 Pod 列表以验证正在运行的前端 Pod 的数量:
kubectl get pods响应应该与以下内容类似:
NAME READY STATUS RESTARTS AGE
frontend-85595f5bf9-5df5m 1/1 Running 0 83s
frontend-85595f5bf9-7zmg5 1/1 Running 0 83s
frontend-85595f5bf9-cpskg 1/1 Running 0 15m
frontend-85595f5bf9-l2l54 1/1 Running 0 14m
frontend-85595f5bf9-l9c8z 1/1 Running 0 14m
redis-follower-dddfbdcc9-82sfr 1/1 Running 0 97m
redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 97m
redis-leader-fb76b4755-xjr2n 1/1 Running 0 108m3.运行以下命令来减少前端 Pod 的数量:
kubectl scale deployment frontend --replicas=24.查询 Pod 列表以验证正在运行的前端 Pod 的数量:
kubectl get pods响应应该与以下内容类似:
NAME READY STATUS RESTARTS AGE
frontend-85595f5bf9-cpskg 1/1 Running 0 16m
frontend-85595f5bf9-l9c8z 1/1 Running 0 15m
redis-follower-dddfbdcc9-82sfr 1/1 Running 0 98m
redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 98m
redis-leader-fb76b4755-xjr2n 1/1 Running 0 109mCleaning up
删除Deployments和Services也会一并删除所有正在运行的 Pod。你可以利用标签来通过一条命令删除多个资源。
1.运行以下命令来删除所有的 Pod、Deployment和Service。
kubectl delete deployment -l app=redis
kubectl delete service -l app=redis
kubectl delete deployment frontend
kubectl delete service frontend响应应该与以下内容类似:
deployment.apps "redis-follower" deleted
deployment.apps "redis-leader" deleted
deployment.apps "frontend" deleted
service "frontend" deleted2.查询 Pod 列表,以验证是否没有 Pod 正在运行:
kubectl get pods响应应该与以下内容类似:
No resources found in default namespace.