kubernetes快速入门10-StatefulSet控制器

网友投稿 282 2022-10-27

kubernetes快速入门10-StatefulSet控制器

kubernetes快速入门10-StatefulSet控制器

有状态副本集。

使用要求:

稳定且唯一的网络标识符; 稳定且持久的存储; 有序、平滑地部署和扩展; 有序、平滑地终止和删除; 有序的滚动更新

StatefulSet由三个组件组成:

Headless services StatefulSet控制器 volumeClaimTemplate 存储卷申请模板

StatefulSet帮助信息,statefulset可简写为sts

先准备存储和pv,存储利用NFS实现

k8s@node01:~/my_manifests/volumes$ cat pv-nfs.yaml apiVersion: v1 kind: PersistentVolume metadata: # PV资源不设置namespace name: pv001 labels: name: pv001 speed: slow spec: nfs: path: /data/nfs/volume/v1 server: node01.k8s.com accessModes: ["ReadWriteMany","ReadWriteOnce"] capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: # PV资源不设置namespace name: pv002 labels: name: pv002 speed: medium spec: nfs: path: /data/nfs/volume/v2 server: node01.k8s.com accessModes: ["ReadWriteMany","ReadWriteOnce"] capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: # PV资源不设置namespace name: pv003 labels: name: pv003 speed: medium spec: nfs: path: /data/nfs/volume/v3 server: node01.k8s.com accessModes: ["ReadWriteOnce"] capacity: storage: 2Gi k8s@node01:~/my_manifests/volumes$ kubectl apply -f pv-nfs.yaml persistentvolume/pv001 created persistentvolume/pv002 created persistentvolume/pv003 created k8s@node01:~/my_manifests/volumes$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv001 2Gi RWO,RWX Retain Available 3s pv002 2Gi RWO,RWX Retain Available 3s pv003 2Gi RWO Retain Available 3s

准备配置清单

k8s@node01:~/my_manifests/statefullset$ cat sts-myapp-pods.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc namespace: default labels: app: myapp-svc spec: clusterIP: None # 无头service,使用selector对应的标签选择相应的pods selector: app: myapp-pods ports: - name: http port: 80 --- apiVersion: apps/v1 kind: StatefulSet metadata: name: myapp spec: replicas: 2 serviceName: myapp-svc selector: matchLabels: app: myapp-pods template: metadata: labels: app: myapp-pods # pods使用的标签 spec: containers: - name: myapp image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: web containerPort: 80 volumeMounts: - name: myappdata # pod中挂载卷的名称,与volumeClaimTemplates中的名称对应 mountPath: /usr/share/nginx/html/ volumeClaimTemplates: # 卷申请模板,当pod启动时会以此模板创建相应的pvc - metadata: name: myappdata spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 2Gi k8s@node01:~/my_manifests/statefullset$ kubectl apply -f sts-myapp-pods.yaml service/myapp-svc created statefulset.apps/myapp created # pod的名称为配置清单中“pod名称+编号” k8s@node01:~/my_manifests/statefullset$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-0 1/1 Running 0 4m28s 10.244.2.105 node03 myapp-1 1/1 Running 0 4m25s 10.244.1.82 node02 # pvc的名称为 volumeClaimTemplates.metadata.name的值+pod名称 k8s@node01:~/my_manifests/statefullset$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE myappdata-myapp-0 Bound pv003 2Gi RWO 11m myappdata-myapp-1 Bound pv001 2Gi RWO,RWX 11m k8s@node01:~/my_manifests/statefullset$ kubectl get pv # 相应的pv已bound NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv001 2Gi RWO,RWX Retain Bound default/myappdata-myapp-1 72m pv002 2Gi RWO,RWX Retain Available 72m pv003 2Gi RWO Retain Bound default/myappdata-myapp-0 72m # 在sts控制中使用了headless的service,pod的名称不能直接进行解析,解析名称应为:pod名称.service名称.名称空间.svc.cluster.local,对应 k8s@node01:~/my_manifests/statefullset$ dig -t A myapp-0.myapp-svc.default.svc.cluster.local @10.96.0.10 ... ;; ANSWER SECTION: myapp-0.myapp-svc.default.svc.cluster.local. 30 IN A 10.244.2.105 k8s@node01:~/my_manifests/statefullset$ dig -t A myapp-1.myapp-svc.default.svc.cluster.local @10.96.0.10 ;; ANSWER SECTION: myapp-1.myapp-svc.default.svc.cluster.local. 30 IN A 10.244.1.82

每一个pod的名称是固定的,删除一个pod后重建后的名称也是不会发生变化,pvc的名称里隐含了pod的名称,如:myappdata-myapp-0,所以可持续的为同一个pod提供存储卷服务。

StatefulSet资源也可以进行扩容和缩容,只要有空闲的pv就可进行扩容。

# 两种方式都可以实现扩容和缩容 k8s@node01:~$ kubectl scale sts myapp --replicas=3 k8s@node01:~$ kubectl patch sts myapp -p '{"spec":{"replicases":2}}'

StatefulSet中pod更新

先设置升级分区边界

k8s@node01:~$ kubectl get sts NAME READY AGE myapp 3/3 10h k8s@node01:~$ kubectl describe sts myapp Name: myapp Namespace: default CreationTimestamp: Wed, 29 Jul 2020 22:34:06 +0800 Selector: app=myapp-pods Labels: Annotations: Replicas: 3 desired | 3 total Update Strategy: RollingUpdate Partition: 0 # 默认的更新边界为 0, 表示全部pod滚动更新 ... # 修改更新边界,这里只有3个Pod,可以只让更新编号为1和2的 k8s@node01:~$ kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":1}}}}' statefulset.apps/myapp patched k8s@node01:~$ kubectl describe sts myapp Name: myapp Namespace: default CreationTimestamp: Wed, 29 Jul 2020 22:34:06 +0800 Selector: app=myapp-pods Labels: Annotations: Replicas: 3 desired | 3 total Update Strategy: RollingUpdate Partition: 1 # 已被设置为1 # 修改pod中的image k8s@node01:~$ kubectl set image sts/myapp myapp=ikubernetes/myapp:v2 statefulset.apps/myapp image updated # 监视更新过程,先更新编号为2的,再更新编号为1的 k8s@node01:~/my_manifests/statefullset$ kubectl get pods -w NAME READY STATUS RESTARTS AGE myapp-0 1/1 Running 0 9m56s myapp-1 1/1 Running 1 10h myapp-2 1/1 Running 0 8m59s myapp-2 1/1 Terminating 0 10m myapp-2 0/1 Terminating 0 10m myapp-2 0/1 Terminating 0 10m myapp-2 0/1 Terminating 0 10m myapp-2 0/1 Pending 0 0s myapp-2 0/1 Pending 0 0s myapp-2 0/1 ContainerCreating 0 0s myapp-2 1/1 Running 0 2s myapp-1 1/1 Terminating 1 10h myapp-1 0/1 Terminating 1 10h myapp-1 0/1 Terminating 1 10h myapp-1 0/1 Terminating 1 10h myapp-1 0/1 Pending 0 0s myapp-1 0/1 Pending 0 0s myapp-1 0/1 ContainerCreating 0 0s myapp-1 1/1 Running 0 3s # 确认pod是否已更新 k8s@node01:~$ kubectl get pods myapp-0 -o yaml | grep image f:image: {} f:imagePullPolicy: {} - image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent image: ikubernetes/myapp:v1 # myapp-0 保值v1版本 imageID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513 k8s@node01:~$ kubectl get pods myapp-1 -o yaml | grep image f:image: {} f:imagePullPolicy: {} - image: ikubernetes/myapp:v2 # v2版本 imagePullPolicy: IfNotPresent image: ikubernetes/myapp:v2 imageID: docker-pullable://ikubernetes/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358 k8s@node01:~$ kubectl get pods myapp-2 -o yaml | grep image f:image: {} f:imagePullPolicy: {} - image: ikubernetes/myapp:v2 # v2版本 imagePullPolicy: IfNotPresent image: ikubernetes/myapp:v2 imageID: docker-pullable://ikubernetes/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358 # 如果更新后无问题,就可以把边界设置为0,让剩下的也一并更新

在实际生产环境中把有状态的应用迁移到k8s要慎重,可以多参考google上已实现方案,这里有个redis的事例:https://github.com/CommercialTribe/kube-redis

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:MAVLink学习之路05_ MAVLink应用编程接口分析
下一篇:springboot中如何通过main方法调用service或dao
相关文章

 发表评论

暂时没有评论,来抢沙发吧~