背景
Pod 本质上是临时的。这意味着 GKE 在删除、逐出或重新安排 Pod 时会销毁 Pod 中存储的状态和值。
作为应用运营人员,您可能需要维护有状态工作负载。此类工作负载的示例包括处理 WordPress 文章的应用、即时通讯应用和处理机器学习操作的应用。
通过在 GKE 上使用 Filestore,您可以执行以下操作:
- 部署可扩缩的有状态工作负载。
- 使多个 Pod 的
accessMode
为ReadWriteMany
,以便多个 Pod 可以同时对同一存储进行读写。 - 设置 GKE 以同时将卷装载到多个 Pod 中。
- 移除 Pod 后持久保留存储空间。
- 使 Pod 能够共享数据并轻松扩缩。
目标
本教程适用于想要使用 PVC 和 NFS 在 GKE 上设置可扩缩的有状态工作负载的应用运营人员和其他用户。本教程介绍以下步骤:
- 创建 GKE 集群。
- 使用 CSI 通过 Filestore 配置代管式文件存储。
- 创建 reader 和 writer Pod。
- 将 reader Pod 公开给 Service 负载均衡器并访问 reader Pod。
- 扩容 writer。
- 访问 writer Pod 中的数据。
费用
本教程使用 Google Cloud的以下收费组件:您可使用价格计算器根据您的预计使用情况来估算费用。
完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理。
如需在 Google Cloud 控制台中直接遵循有关此任务的分步指导,请点击操作演示:
准备工作
设置项目
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, GKE, and Filestore APIs.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, GKE, and Filestore APIs.
设置 Google Cloud CLI 的默认值
在 Google Cloud 控制台中,启动 Cloud Shell 实例:
打开 Cloud Shell下载此示例应用的源代码:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/databases/stateful-workload-filestore
设置默认环境变量:
gcloud config set project PROJECT_ID gcloud config set compute/region COMPUTE_REGION gcloud config set compute/zone COMPUTE_ZONE gcloud config set filestore/zone COMPUTE_ZONE gcloud config set filestore/region COMPUTE_REGION
替换以下值:
- PROJECT_ID:您的 Google Cloud 项目 ID。
- COMPUTE_REGION:Compute Engine 区域。
- COMPUTE_ZONE:Compute Engine 可用区。
创建 GKE 集群
创建 GKE 集群:
gcloud container clusters create-auto CLUSTER_NAME --region COMPUTE_REGION
替换以下值:
- CLUSTER_NAME:您的集群名称。
创建集群后,结果类似于以下内容:
gcloud container clusters describe CLUSTER_NAME NAME: CLUSTER_NAME LOCATION: northamerica-northeast2 MASTER_VERSION: 1.21.11-gke.1100 MASTER_IP: 34.130.255.70 MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.11-gke.1100 NUM_NODES: 3 STATUS: RUNNING
其中,
STATUS
是RUNNING
。
使用 CSI 通过 Filestore 配置代管式文件存储
GKE 提供了一种在集群中自动部署和管理 Kubernetes Filestore CSI 驱动程序的方法。使用 Filestore CSI,您可以动态创建或删除 Filestore 实例,并在具有 StorageClass
或 Deployment
的 Kubernetes 工作负载中使用这些实例。
您可以创建新的 Filestore 实例(方法是创建动态预配 Filestore 实例和 PV 的 PVC),或访问 Kubernetes 工作负载中预先预配的 Filestore 实例。
新建实例
创建存储类别
volumeBindingMode
设置为Immediate
,允许立即开始预配卷。tier
设置为standard
,可以缩短 Filestore 实例创建时间。如果您需要可用性更高的 NFS 存储、数据备份快照、多个可用区中的数据复制和其他企业级功能,请将tier
设置为enterprise
。注意:如果未设置StorageClass
中的reclaimPolicy
,则动态创建的 PV 的收回政策默认为Delete
。
创建
StorageClass
资源:kubectl create -f filestore-storageclass.yaml
验证存储类别已创建:
kubectl get sc
输出类似于以下内容:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE filestore-sc filestore.csi.storage.gke.io Delete Immediate true 94m
预先配置的实例
创建存储类别
当 volumeBindingMode
设置为 Immediate
时,允许立即开始预配卷。
创建
StorageClass
资源:kubectl create -f preprov-storageclass.yaml
验证存储类别已创建:
kubectl get sc
输出类似于以下内容:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE filestore-sc filestore.csi.storage.gke.io Delete Immediate true 94m
为 Filestore 实例创建永久性卷
验证现有的 Filestore 实例已准备就绪:
gcloud filestore instances list
输出类似于以下内容,其中
STATE
值为READY
:INSTANCE_NAME: stateful-filestore LOCATION: us-central1-a TIER: ENTERPRISE CAPACITY_GB: 1024 FILE_SHARE_NAME: statefulpath IP_ADDRESS: 10.109.38.98 STATE: READY CREATE_TIME: 2022-04-05T18:58:28
记下 Filestore 实例的
INSTANCE_NAME
、LOCATION
、FILE_SHARE_NAME
和IP_ADDRESS
。填充 Filestore 实例控制台变量:
INSTANCE_NAME=INSTANCE_NAME LOCATION=LOCATION FILE_SHARE_NAME=FILE_SHARE_NAME IP_ADDRESS=IP_ADDRESS
将文件
preprov-pv.yaml
中的占位符变量替换为上面获取的控制台变量:sed "s/<INSTANCE_NAME>/$INSTANCE_NAME/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml sed "s/<LOCATION>/$LOCATION/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml sed "s/<FILE_SHARE_NAME>/$FILE_SHARE_NAME/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml sed "s/<IP_ADDRESS>/$IP_ADDRESS/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml
创建 PV
kubectl apply -f preprov-pv.yaml
验证 PV 的
STATUS
已设置为Bound
:kubectl get pv
输出类似于以下内容:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE fileserver 1Ti RWX Delete Bound default/fileserver filestore-sc 46m
使用 PersistentVolumeClaim 访问卷
以下 pvc.yaml
清单引用了名为 filestore-sc
的 Filestore CSI 驱动程序的 StorageClass
。
为了让多个 Pod 读写卷,请将 accessMode
设置为 ReadWriteMany
。
部署 PVC:
kubectl create -f pvc.yaml
验证 PVC 已创建:
kubectl get pvc
输出类似于以下内容:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE fileserver Bound pvc-aadc7546-78dd-4f12-a909-7f02aaedf0c3 1Ti RWX filestore-sc 92m
验证新创建的 Filestore 实例已准备就绪:
gcloud filestore instances list
输出类似于以下内容:
INSTANCE_NAME: pvc-5bc55493-9e58-4ca5-8cd2-0739e0a7b68c LOCATION: northamerica-northeast2-a TIER: STANDARD CAPACITY_GB: 1024 FILE_SHARE_NAME: vol1 IP_ADDRESS: 10.29.174.90 STATE: READY CREATE_TIME: 2022-06-24T18:29:19
创建 reader 和 writer Pod
在本部分中,您将创建一个读取器 Pod 和一个写入器 Pod。本教程使用 Kubernetes 部署来创建 Pod。Deployment 是一个 Kubernetes API 对象,可让您运行在集群节点中分布的多个 Pod 副本。
创建 reader Pod
reader Pod 将读取 writer Pod 写入的文件。reader Pod 将看到写入文件的时间以及 Pod writer 副本。
reader Pod 将从在所有 Pod 之间共享的路径 /usr/share/nginx/html
读取数据。
部署 reader Pod:
kubectl apply -f reader-fs.yaml
查询 Pod 列表以验证 reader 副本正在运行:
kubectl get pods
输出类似于以下内容:
NAME READY STATUS RESTARTS AGE reader-66b8fff8fd-jb9p4 1/1 Running 0 3m30s
创建 writer Pod
writer Pod 将定期写入其他 writer 和 reader Pod 可以访问的共享文件。writer Pod 会将其主机名写入共享文件以记录其存在。
writer Pod 使用的映像是用于实用程序和生产应用的 Alpine Linux 自定义映像。它包含一个脚本 indexInfo.html
,该脚本将获取最新 writer 的元数据,并记录所有唯一 writer 的数量和写入总数。
在本教程中,writer Pod 每 30 秒向路径 /html/index.html
写入一次。修改 sleep
数字值可使用不同的写入频率。
部署 writer Pod:
kubectl apply -f writer-fs.yaml
查询 Pod 列表,以验证 writer Pod 正在运行:
kubectl get pods
输出类似于以下内容:
NAME READY STATUS RESTARTS AGE reader-66b8fff8fd-jb9p4 1/1 Running 0 3m30s writer-855565fbc6-8gh2k 1/1 Running 0 2m31s writer-855565fbc6-lls4r 1/1 Running 0 2m31s
将 reader 工作负载公开给 Service 负载均衡器并访问 reader 工作负载
如需在集群外部公开工作负载,请创建 LoadBalancer
类型的 Service。此类型的 Service 会创建具有可通过互联网访问的 IP 地址的外部负载均衡器。
创建一个名为
reader-lb
的LoadBalancer
类型的 Service:kubectl create -f loadbalancer.yaml
监视该部署,直至看到 GKE 为
reader-lb
Service 分配了EXTERNAL-IP
:kubectl get svc --watch
Service
准备就绪后,EXTERNAL-IP
列会显示负载均衡器的公共 IP 地址:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.8.128.1 <none> 443/TCP 2d21h reader-lb LoadBalancer 10.8.131.79 34.71.232.122 80:32672/TCP 2d20h
按 Ctrl+C 终止监视过程。
使用网络浏览器访问分配给负载均衡器的
EXTERNAL-IP
。该页面每 30 秒刷新一次。writer Pod 越多,频率越高,它显示的条目就越多。
如需详细了解负载均衡器服务,请参阅 loadbalancer.yaml
。
扩容 writer
由于 PV accessMode
设置为 ReadWriteMany
,因此 GKE 可以增加 Pod 的数量,使更多 writer Pod 能够写入此共享卷(或者更多 reader 可以读取它们)。
将
writer
扩容到五个副本:kubectl scale deployment writer --replicas=5
输出类似于以下内容:
deployment.extensions/writer scaled
验证正在运行的副本数:
kubectl get pods
输出类似于以下内容:
NAME READY STATUS RESTARTS AGE reader-66b8fff8fd-jb9p4 1/1 Running 0 11m writer-855565fbc6-8dfkj 1/1 Running 0 4m writer-855565fbc6-8gh2k 1/1 Running 0 10m writer-855565fbc6-gv5rs 1/1 Running 0 4m writer-855565fbc6-lls4r 1/1 Running 0 10m writer-855565fbc6-tqwxc 1/1 Running 0 4m
使用网络浏览器再次访问分配给负载均衡器的
EXTERNAL-IP
。
此时,您已对集群进行了配置和扩容,可以支持五个有状态 writer Pod。多个 writer Pod 同时写入同一文件。reader Pod 也可以轻松扩容。
可选:访问 writer Pod 中的数据
本部分演示如何使用命令行界面访问 reader 或 writer Pod。您可以看到 writer 写入和 reader 读取的共享组件。
获取 writer Pod 名称:
kubectl get pods
输出类似于以下内容:
NAME READY STATUS RESTARTS AGE writer-5465d65b46-7hxv4 1/1 Running 0 20d
记下 writer Pod 的主机名(示例:
writer-5465d65b46-7hxv4
)。运行以下命令以访问 writer Pod:
kubectl exec -it WRITER_HOSTNAME -- /bin/sh
查看文件
indexData.html
中的共享组件:cd /html cat indexData.html
清除
indexData.html
文件:echo '' > indexData.html
刷新托管
EXTERNAL-IP
地址的网络浏览器以查看变化。退出环境:
exit
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
逐个删除资源
删除负载均衡器 Service:
kubectl delete service reader-lb
等待直到为 reader 服务预配的负载均衡器被删除
验证列表返回
Listed 0 items
:gcloud compute forwarding-rules list
删除 Deployment
kubectl delete deployment writer kubectl delete deployment reader
验证 Pod 已删除并返回
No resources found in default namespace.
kubectl get pods
删除 PVC。由于保留政策设置为
delete
,此命令还将删除 PV 和 Filestore 实例kubectl delete pvc fileserver
删除 GKE 集群:
gcloud container clusters delete CLUSTER_NAME --zone=COMPUTE_ZONE
此命令将删除构成 GKE 集群的资源,包括 reader 和 writer Pod。
后续步骤
- 了解如何使用 GKE 部署 Cloud SQL
- PV 和 PVC 的访问模式
- 详细了解 GKE 和 Filestore
- 详细了解 Filestore CSI 驱动程序
- 如何创建 Filestore 实例
- 了解如何从 GKE 集群访问 Filestore 实例
- 浏览其他 Kubernetes Engine 教程。
- 详细了解如何在 GKE 中使用 Service 公开应用