接上文 《Kubectl 部署有状态应用(上)》创建完StatefulSet后,本文继续介绍StatefulSet 扩展、更新、删除等内容。
StatefulSet 中的 Pod 具有唯一的序数索引和稳定的网络身份。
for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
------
web-0
web-1
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.nginx
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 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
------
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pvc-e474e3c6-7793-4b16-b852-c293adbd1903 1Gi RWO standard 56m
www-web-1 Bound pvc-fd575798-fe7a-42e4-96cb-0365d6761e68 1Gi RWO standard 56m
在一个窗口中打开kubectl get pods --watch -l app=nginx
在另一个窗口执行kubectl scale sts web --replicas=5
可以看到:
接下来将副本数量改成3个
kubectl patch sts web -p '{"spec":{"replicas":3}}'
控制器会一次删除一个 Pod,按照其序数索引的相反顺序,并等待每个Pod 完全关闭,然后再删除下一个。
在 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 0 7m7sweb-2 0/1 Terminating 0 7m7sweb-2 0/1 Terminating 0 7m7sweb-2 0/1 Pending 0 0sweb-2 0/1 Pending 0 0sweb-2 0/1 ContainerCreating 0 0sweb-2 1/1 Running 0 4sweb-1 1/1 Terminating 0 14m
web-1 0/1 Terminating 0 14m
web-1 0/1 Terminating 0 14m
web-1 0/1 Terminating 0 14m
web-1 0/1 Terminating 0 14m
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 4s
web-0 1/1 Terminating 0 14m
web-0 0/1 Terminating 0 15m
web-0 0/1 Terminating 0 15m
web-0 0/1 Terminating 0 15m
web-0 0/1 Terminating 0 15m
web-0 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 5s
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.8
gcr.io/google_containers/nginx-slim:0.8
gcr.io/google_containers/nginx-slim:0.8
关于更新的更多细节(暂存部署、分阶段部署等),可以查阅:https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/
StatefulSet 支持非级联删除和级联删除。在非级联删除中,删除 StatefulSet 时,StatefulSet 的 Pod 不会被删除。在级联删除中,StatefulSet 及其 Pod 都会被删除。
执行 kubectl delete statefulset web --cascade=orphan
kubectl get pods -l app=nginx
即使已web被删除,所有 Pod 仍在运行并准备就绪。删除web-0:
直接执行:
kubectl delete statefulset web
输出:
statefulset “web” deleted,会将statefulset和所有pod全部删除。
kubectl delete statefulset web
kubectl delete svc nginx
删除本教程中使用的 PersistentVolume 的持久存储介质。
kubectl get pvc
kubectl get pv
----
# 进行删除
kubectl delete pvc www-web-0 www-web-1 www-web-2 www-web-3 www-web-4
kubectl get pvc