接上文 《Kubectl 部署有状态应用(上)》创建完StatefulSet后,本文继续介绍StatefulSet 扩展、更新、删除等内容。

StatefulSet 中的 Pod

验证序数索引和稳定的网络身份

StatefulSet 中的 Pod 具有唯一的序数索引和稳定的网络身份。

查看 Pod 的主机名
for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done------web-0web-1
查看Pod DNS
kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm

此时会启动一个新的shell,在shell中执行nslookup web-0.nginx
输出类似如下所示:

If you don't see a command prompt, try pressing enter./ # nslookup web-0.nginxServer:10.96.0.10Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName:web-0.nginxAddress 1: 10.244.2.24 web-0.nginx.default.svc.cluster.local

再次执行kubectl delete pod -l app=nginx。 删除nginx pod后,等待其重新running起来。重新执行查看查看 Pod 的主机名和查看Pod DNS命令。发现输出是一致的,并不会因此Pod重新创建而改变DNS和主机名称。(此处不再展示重新查询结果,可自行手动尝试)

稳定的存储

获取web-0和web-1的PersistentVolumeClaims(PVC)

kubectl get pvc -l app=nginx------NAMESTATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEwww-web-0 Boundpvc-e474e3c6-7793-4b16-b852-c293adbd1903 1GiRWOstandard 56mwww-web-1 Boundpvc-fd575798-fe7a-42e4-96cb-0365d6761e68 1GiRWOstandard 56m

扩展 StatefulSet

扩容

在一个窗口中打开kubectl get pods --watch -l app=nginx

在另一个窗口执行kubectl scale sts web --replicas=5
可以看到:

缩容

接下来将副本数量改成3个

kubectl patch sts web -p '{"spec":{"replicas":3}}'

Pod 有序终止

控制器会一次删除一个 Pod,按照其序数索引的相反顺序,并等待每个Pod 完全关闭,然后再删除下一个。

更新 StatefulSet

在 Kubernetes 1.7 及更高版本中,StatefulSet 控制器支持自动更新。使用的策略由spec.updateStrategyStatefulSet API 对象的字段决定。此功能可用于升级 StatefulSet 中 Pod 的容器镜像、资源请求和/或限制、标签和注释。有两种有效的更新策略,RollingUpdate和 OnDelete。

RollingUpdate更新策略是 StatefulSets 的默认策略。

滚动更新

更新RollingUpdate策略将以相反的顺序更新 StatefulSet 中的所有 Pod,同时尊重 StatefulSet 保证。

修改web StatefulSet 以应用RollingUpdate更新策略:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'

修改web StatefulSet,更改容器镜像

kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.8"}]'

另一个终端输出大概如下:

web-2 0/1 Terminating 07m7sweb-2 0/1 Terminating 07m7sweb-2 0/1 Terminating 07m7sweb-2 0/1 Pending 00sweb-2 0/1 Pending 00sweb-2 0/1 ContainerCreating 00sweb-2 1/1 Running 04sweb-1 1/1 Terminating 014mweb-1 0/1 Terminating 014mweb-1 0/1 Terminating 014mweb-1 0/1 Terminating 014mweb-1 0/1 Terminating 014mweb-1 0/1 Pending 00sweb-1 0/1 Pending 00sweb-1 0/1 ContainerCreating 00sweb-1 1/1 Running 04sweb-0 1/1 Terminating 014mweb-0 0/1 Terminating 015mweb-0 0/1 Terminating 015mweb-0 0/1 Terminating 015mweb-0 0/1 Terminating 015mweb-0 0/1 Pending 00sweb-0 0/1 Pending 00sweb-0 0/1 ContainerCreating 00sweb-0 1/1 Running 05s

StatefulSet 中的 Pod 按相反顺序更新。StatefulSet 控制器终止每个 Pod,并等待其转换为 Running 和 Ready,然后再更新下一个 Pod。
已经收到更新的 Pod 将恢复到更新后的版本,尚未收到更新的 Pod 将恢复到之前的版本。通过这种方式,控制器尝试在出现间歇性故障的情况下继续保持应用程序的健康和更新的一致性。

查看所有Pod镜像

for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done------gcr.io/google_containers/nginx-slim:0.8gcr.io/google_containers/nginx-slim:0.8gcr.io/google_containers/nginx-slim:0.8

关于更新的更多细节(暂存部署、分阶段部署等),可以查阅:https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/

删除 StatefulSet

StatefulSet 支持非级联删除和级联删除。在非级联删除中,删除 StatefulSet 时,StatefulSet 的 Pod 不会被删除。在级联删除中,StatefulSet 及其 Pod 都会被删除。

非级联删除

执行 kubectl delete statefulset web --cascade=orphan

获取 Pod,检查它们的状态

kubectl get pods -l app=nginx

即使已web被删除,所有 Pod 仍在运行并准备就绪。删除web-0:

级联删除

直接执行:

kubectl delete statefulset web

输出:
statefulset “web” deleted,会将statefulset和所有pod全部删除。

清理

kubectl delete statefulset webkubectl delete svc nginx

删除本教程中使用的 PersistentVolume 的持久存储介质。

kubectl get pvckubectl get pv----# 进行删除kubectl delete pvc www-web-0 www-web-1 www-web-2 www-web-3 www-web-4kubectl get pvc