欢迎访问我的博客,你的支持,是我最大的动力!

马哥_K8s进阶实战(7)StatefulSet控制器

Docker 小马奔腾 399℃ 评论
目录:
[显示]
StatefulSet 概述

有状态应用的管控
有状态意味着进程存储了以前交互过程的记录,并可基于它对新的请求进行响应

StatefulSet管控的的每个Pod对象都有固定的主机名和专有存储卷,即便被重构后亦能保持不变

StatefulSet的特性:
稳定且唯一的网络标识符
稳定且持久的存储
有序、优雅地部署和扩展
有序、优雅地删除和终止
有序而自动地滚动更新

典型的StatefulSet由三个组件构成:
Headless Service,为Pod标识符生成可解析的DNS资源记录
StatefulSet,管控Pod资源
volumeClaimTemplate,基于静态或动态PV供给方式为Pod资源提供专有且固定的存储

StatefulSet 基础应用

restauthenabled: "false" 表示heketi不需要帐号认证

默认,StatefulSet控制器以串行方式创建各Pod副本 若要并行,可设置 spec.podManagementPolicy 值为Parallet 默认为 OrderedReady

查看glusterfs的磁盘供给:
gluster volume info
heketi-cli volume list

释放存储卷:
1、删除statefulset
2、删除对应的pvc   # kubectl delete pvc --all
此时 PV 会自动删除;对应的glusterfs的存储卷也会自动删除

Pod 资源标识符及存储卷

1、Pod资源的固定标识符
格式 <statefulset_name>-<index> 如myapp-0
kubectl get pods -l app=myapp-pod
Pod的主机名和Pod名称一致
for i in 0 1; do kubectl exec myapp-$i -- sh -c 'hostname'; done
DNS记录
服务:<service_name>.<namespace>.svc.cluster.local
# myapp-svc.default.svc.cluster.local
具体Pod:<pod_name>.<service_name>.<namespace>.svc.cluster.local
# myapp-0.myapp-svc.default.svc.cluster.local

# 验证
kubectl run -it --image busybox dns-client --restart=Never --rm /bin/sh
nslookup myapp-0.myapp-svc  # 实测无法解析  但是能ping通
# kubectl run -it --image cirros client --restart=Never --rm /bin/sh  这个镜像能用nslookup
# 其中 myapp-svc 会返回两个ip(即所属Pod的IP)

由StatefulSet控制器管控的Pod资源终止后,自动重建的IP会变化,但名称标识保持不变,DNS名称也不会变
客户端向StatefulSet资源发出访问时,通常针对Headless Service的CNAME进行(myapp-svc.default.svc.cluster.local)
也可以直接向Pod的名称发起访问

2、Pod资源的专有存储卷
kubectl get pvc -l app=myapp-pod

for i in 0 1; do kubectl exec myapp-$i -- /bin/sh -c 'echo $(date),Hostname: $(hostname) > /usr/share/nginx/html/index.html'; done
kubectl run -it --image cirros client --restart=Never --rm /bin/sh
curl myapp-0.myapp-svc

StatefulSet 资源扩缩容

修改资源副本数
kubectl scale 、kubectl patch、kubectl edit、kubectl apply等都可实现

kubectl scale statefulset myapp --replicas=6
kubectl patch statefulsets.apps myapp -p '{"spec":{"replicas":3}}'

缩容后,存储卷不会被删除,若再扩展回来,此前的数据依然可用,且Pod名称保持不变

StatefulSet 资源升级

kubectl explain statefulset.spec.updateStrategy
更新策略默认为RollingUpdate,即滚动更新
可更新Pod中容器镜像、标签、注解、资源配额等

滚动更新

滚动更新从序号最大的Pod开始

kubectl get statefulsets.apps myapp -o yaml

kubectl set image statefulset myapp myapp=ikubernetes/myapp:v6
kubectl get pods -l app=myapp-pod -w   #监控为变更过程
kubectl rollout status statefulset myapp
# 查看更新后的镜像
for i in 0 1 2; do kubectl get po myapp-$i --template '{{range $i,$c:=.spec.containers}}{{$c.image}}{{end}}'; echo; done

暂存更新操作

分区更新操作
将spec.updateStrategy.rollingUpdate.partition设置为Pod副本数量时,即意味着所有Pod资源都不会处于可直接更新的分区内
直到partition小于Pod数时,才会开始更新

kubectl patch statefulsets.apps myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":3}}}}'
kubectl set image statefulset myapp myapp=ikubernetes/myapp:v7
kubectl rollout status statefulset myapp
kubectl get pods -l app=myapp-pod -o custom-columns=NAME:metadata.name,IMAGE:spec.containers[0].image
此时,即便删除某Pod,也会按旧版本进行重建,即暂存状态的更新对所有Pod资源均不产生影响

金丝雀部署

对处于暂存状态的更新操作,修改其partition值,即可转入金丝雀部署模式

kubectl patch statefulsets.apps myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":2}}}}'
kubectl get pods -l app=myapp-pod -o custom-columns=NAME:metadata.name,IMAGE:spec.containers[0].image
kubectl rollout status statefulset myapp
# 此时会有一个Pod被更新,们于非更新区内的Pod即便被删除重建,也会保持旧版本

分段更新

在要更新Pod数量较多时,可逐渐调小partition的值,进行分段更新;也可直接设置partition值为0,进行全部更新

StatefulSet的删除默认是级联删除,即会在删除StatefulSet时,同时删除Pod,若要执行非级联删除,使用 --cascade=false

StatefulSet管理Pod默认策略是 OrderedReady(顺序创建,逆序删除),也支持并行创建和删除,Parallel

案例: etcd 集群

etcd 是分布式键值数据存储系统,具有可靠、快速、强一致性等特性,它通过分布式锁、leader选举、写屏障实现可靠的分布式协作
etcd采用raft算法,若发生网络分区或节点故障,raft算法会通过quorum机制处理集群状态转移,其中成员数量大于半数的一方可继续工作,少于半数的将停止任何写入操作

K8s中将所有数据存储于/registry目录中,且仅有API Server直接与etcd进行通信,从而确保数据高度一致性

1、创建Service资源

两种Service的对照,StatefulSet使用的是Headless Service为Pod提供名称解析服务,而后一种使用节点端口向集群外提供服务

2、etcd StatefulSet

需要使用持久化存储,gluster-dynamic

注意,实际测试中,etcd启动不了,应该是启动命令的问题,可能是哪个地方不对
查看错误日志 kubectl log etcd-0

kubectl get endpoints -l app=ectd
# 检测集群健康状态
kubectl exec etcd-0 -- etcdctl cluster-health
kubectl exec etcd-0 -- etcdctl -v  # 查看版本

配置文件中提供的StatefulSet进行规模变动时,需要手动对etcd集群执行命令以完成节点的添加和删除,不能自动完成扩缩容
缩容时要先移除节点再缩减副本数量,扩容时先提升副本数量再添加节点

 

转载请注明:轻风博客 » 马哥_K8s进阶实战(7)StatefulSet控制器

喜欢 (0)or分享 (0)