共计 9555 个字符,预计需要花费 24 分钟才能阅读完成。

StatefulSet是一种有状态的资源集合,管理所有有状态的服务,常用于Mysql/MongoDB集群等。StatefulSet所管理的Pod有如下特点:
- 具有固定网络标识的Pod名称和hostname,(statefulset名称)−(序号),序号:[0,副本数-1)
- Pod顺序启停
- 稳定的存储,通过VolumeClaimTemplate为每个Pod创建一一对应的PV,删除或减少副本数,不会移除相关pv。
- 其对应的Service为headless service(解析该名称将会放回对应所有的Pod的Endpoint列表)
创建StatefulSet 测试资源
# 创建一个demo
[root@node1 pratic]# cat >statusful-nginx.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
      annotations:
        volume.beta.kubernetes.io/storage-class: "nfsserver"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 100Mi
EOFPod启停有序性
观察StatusfulSet Pod创建顺序
web-0 pod处于Running和Ready状态后web-1 Pod才会被启动,这就是有状态集的启动有序性
[root@node1 pratic]# kubectl apply -f statusful-nginx.yaml
[root@node1 pratic]# kubectl get pods -w
NAME    READY   STATUS              RESTARTS   AGE
web-0   1/1     Running             0          32s
web-1   1/1     Running             0          18s
web-2   0/1     ContainerCreating   0          8s
web-2   1/1     Running             0          16s
web-3   0/1     Pending             0          0s
web-3   0/1     Pending             0          0s
web-3   0/1     Pending             0          2s
web-3   0/1     ContainerCreating   0          2s
web-3   0/1     ContainerCreating   0          3s
web-3   1/1     Running             0          12s
web-4   0/1     Pending             0          0s
web-4   0/1     Pending             0          0s
web-4   0/1     Pending             0          2s
web-4   0/1     ContainerCreating   0          2s
web-4   0/1     ContainerCreating   0          3s
web-4   1/1     Running             0          9sPod网络标志固定
测试每个pod的hostname
[root@node1 pratic]# for i in {0..4}; do kubectl exec "web-$i" -- sh -c 'hostname'; done
web-0
web-1
web-2
web-3
web-4测试Pod的DNS地址
# 创建一个静态pod busybox
[root@node1 pratic]# kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm
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.100.166.172 web-0.nginx.default.svc.cluster.local
/ # nslookup web-1.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name:      web-1.nginx
Address 1: 10.100.166.173 web-1.nginx.default.svc.cluster.local
/ # nslookup web-2.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name:      web-2.nginx
Address 1: 10.100.166.174 web-2.nginx.default.svc.cluster.local测试固定的网络标识
1.先删除创建的Pod
# 先删除创建的demo pod,再删除的同时开启另一个终端查看demo pod资源创建情况
[root@node1 pratic]# kubectl delete pod -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
pod "web-2" deleted
pod "web-3" deleted
pod "web-4" deleted
# 另一终端查看资源创建情况
[root@node1 pratic]# kubectl get pod -w -l app=nginx
NAME  web-0   1/1     Terminating         0          5m2s
web-1   1/1     Terminating         0          4m52s
web-2   1/1     Terminating         0          4m45s
web-3   1/1     Terminating         0          4m37s
web-4   1/1     Terminating         0          4m27s
web-1   0/1     Terminating         0          4m54s
web-4   0/1     Terminating         0          4m29s
web-2   0/1     Terminating         0          4m47s
web-3   0/1     Terminating         0          4m39s
web-0   0/1     Terminating         0          5m4s
web-3   0/1     Terminating         0          4m45s
web-3   0/1     Terminating         0          4m45s
web-0   0/1     Terminating         0          5m10s
web-0   0/1     Terminating         0          5m10s
web-1   0/1     Terminating         0          5m
web-0   0/1     Pending             0          0s
web-1   0/1     Terminating         0          5m
web-0   0/1     Pending             0          0s
web-2   0/1     Terminating         0          4m53s
web-2   0/1     Terminating         0          4m53s
web-4   0/1     Terminating         0          4m35s
web-4   0/1     Terminating         0          4m35s
web-0   0/1     ContainerCreating   0          1s
web-0   0/1     ContainerCreating   0          2s
web-0   1/1     Running             0          8s
web-1   0/1     Pending             0          0s
web-1   0/1     Pending             0          0s
web-1   0/1     ContainerCreating   0          0s
web-1   0/1     ContainerCreating   0          1s
web-1   1/1     Running             0          9s
web-2   0/1     Pending             0          0s
web-2   0/1     Pending             0          0s
web-2   0/1     ContainerCreating   0          0s
web-2   0/1     ContainerCreating   0          2s
web-2   1/1     Running             0          11s
web-3   0/1     Pending             0          0s
web-3   0/1     Pending             0          0s
web-3   0/1     ContainerCreating   0          0s
web-3   0/1     ContainerCreating   0          1s
web-3   1/1     Running             0          7s
web-4   0/1     Pending             0          0s
web-4   0/1     Pending             0          0s
web-4   0/1     ContainerCreating   0          0s
web-4   0/1     ContainerCreating   0          1s
web-4   1/1     Running             0          9s2.测试此时重建的pod的网络标志
# 查看重建pod后的hostname
[root@node1 pratic]# for i in {0..4}; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1
web-2
web-3
web-4
查看重建pod后的dns记录
/ # 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.100.166.188 10-100-166-188.nginx-service.default.svc.cluster.local
/ # nslookup web-1.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name:      web-1.nginx
Address 1: 10.100.166.189 web-1.nginx.default.svc.cluster.local
/ # nslookup web-2.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name:      web-2.nginx
Address 1: 10.100.166.190 10-100-166-190.nginx-service.default.svc.cluster.local
# 获取到
/ # nslookup nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name:      nginx
Address 1: 10.100.166.190 web-2.nginx.default.svc.cluster.local
Address 2: 10.100.166.189 10-100-166-189.nginx-service.default.svc.cluster.local
Address 3: 10.100.166.188 10-100-166-188.nginx-service.default.svc.cluster.local
Address 4: 10.100.166.134 10-100-166-134.nginx-service.default.svc.cluster.local
Address 5: 10.100.166.136 10-100-166-136.nginx-service.default.svc.cluster.local从上面测试可以看出Pod 的序号、主机名、SRV 条目和记录名称没有改变,但和 Pod 相关联的 IP 地址可能发生了改变。所以在应用中使用StatefulSet时应该使用pod的SRV记录。
稳定的存储
查看测试资源创建的pvc/pv,发现其分别为每个pod创建了一个pvc,且是一一根据序号对应
# 查看pvc
[root@node1 pratic]# kubectl get pvc -l app=nginx
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
www-web-0   Bound    pvc-a08aa8a7-cd1d-4584-b55b-80cd1b217e66   100Mi      RWO            nfsserver      33m
www-web-1   Bound    pvc-5707ad69-9e7c-4423-9144-e3e2f000b9ed   100Mi      RWO            nfsserver      33m
www-web-2   Bound    pvc-975520a6-de1f-4e26-b7d8-65e3353866ab   100Mi      RWO            nfsserver      33m
www-web-3   Bound    pvc-4e7b5b31-a334-4503-8b82-935d2a561cc0   100Mi      RWO            nfsserver      33m
www-web-4   Bound    pvc-39787c7a-2ae3-44ca-8821-d2bad2a4a75c   100Mi      RWO            nfsserver      33m
# 查看pvc
[root@node1 pratic]# kubectl get pv | grep www-web
pvc-39787c7a-2ae3-44ca-8821-d2bad2a4a75c   100Mi      RWO            Delete           Bound         default/www-web-4                            nfsserver                               34m
pvc-4e7b5b31-a334-4503-8b82-935d2a561cc0   100Mi      RWO            Delete           Bound         default/www-web-3                            nfsserver                               34m
pvc-5707ad69-9e7c-4423-9144-e3e2f000b9ed   100Mi      RWO            Delete           Bound         default/www-web-1                            nfsserver                               35m
pvc-975520a6-de1f-4e26-b7d8-65e3353866ab   100Mi      RWO            Delete           Bound         default/www-web-2                            nfsserver                               35m
pvc-a08aa8a7-cd1d-4584-b55b-80cd1b217e66   100Mi      RWO            Delete           Bound         default/www-web-0                            nfsserver                               35m测试pvc和pod的对应关系
1.将每个Pod hostname写入各自PV中
[root@node1 pratic]# for i in {0..4}; do kubectl exec "web-$i" -- sh -c 'echo "$(hostname)" > /usr/share/nginx/html/index.html'; done
[root@node1 pratic]# for i in {0..4}; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1
web-2
web-3
web-42.删除所有Pod
[root@node1 pratic]# kubectl delete pod -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
pod "web-2" deleted
pod "web-3" deleted
pod "web-4" deleted3.查看pv/pvc
# 五个 PersistentVolumeClaims 和五个 PersistentVolumes 仍然存在
[root@node1 pratic]# kubectl get pvc -l app=nginx
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
www-web-0   Bound    pvc-a08aa8a7-cd1d-4584-b55b-80cd1b217e66   100Mi      RWO            nfsserver      33m
www-web-1   Bound    pvc-5707ad69-9e7c-4423-9144-e3e2f000b9ed   100Mi      RWO            nfsserver      33m
www-web-2   Bound    pvc-975520a6-de1f-4e26-b7d8-65e3353866ab   100Mi      RWO            nfsserver      33m
www-web-3   Bound    pvc-4e7b5b31-a334-4503-8b82-935d2a561cc0   100Mi      RWO            nfsserver      33m
www-web-4   Bound    pvc-39787c7a-2ae3-44ca-8821-d2bad2a4a75c   100Mi      RWO            nfsserver      33m
[root@node1 pratic]# kubectl get pv | grep www-web
pvc-39787c7a-2ae3-44ca-8821-d2bad2a4a75c   100Mi      RWO            Delete           Bound         default/www-web-4                            nfsserver                               34m
pvc-4e7b5b31-a334-4503-8b82-935d2a561cc0   100Mi      RWO            Delete           Bound         default/www-web-3                            nfsserver                               34m
pvc-5707ad69-9e7c-4423-9144-e3e2f000b9ed   100Mi      RWO            Delete           Bound         default/www-web-1                            nfsserver                               35m
pvc-975520a6-de1f-4e26-b7d8-65e3353866ab   100Mi      RWO            Delete           Bound         default/www-web-2                            nfsserver                               35m
pvc-a08aa8a7-cd1d-4584-b55b-80cd1b217e66   100Mi      RWO            Delete           Bound         default/www-web-0                            nfsserver                               35m4.验证每个Pod和PV bond关系,虽然所有Pod重新创建和调度,但是他们PersistentVolumeClaim 相关联的 PersistentVolume 被重新挂载到了各自的 volumeMount 上。
[root@node1 pratic]# for i in {0..4}; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1
web-2
web-3
web-4StatefulSet扩缩容
扩容
[root@node1 pratic]# kubectl scale sts web --replicas=8
statefulset.apps/web scaled
# 安顺序扩容
[root@node1 pratic]# kubectl get pod -w -l app=nginx
......
web-5   0/1     Pending             0          0s
web-5   0/1     Pending             0          0s
web-5   0/1     Pending             0          1s
web-5   0/1     ContainerCreating   0          1s
web-5   0/1     ContainerCreating   0          2s
web-5   1/1     Running             0          8s
web-6   0/1     Pending             0          0s
web-6   0/1     Pending             0          0s
web-6   0/1     Pending             0          2s
web-6   0/1     ContainerCreating   0          2s
web-6   0/1     ContainerCreating   0          3s
web-6   1/1     Running             0          13s
web-7   0/1     Pending             0          0s
web-7   0/1     Pending             0          0s
web-7   0/1     Pending             0          2s
web-7   0/1     ContainerCreating   0          2s
web-7   0/1     ContainerCreating   0          4s
web-7   1/1     Running             0          11s缩容
[root@node1 pratic]# kubectl scale sts web --replicas=5
statefulset.apps/web scaled
# 按倒序缩容
[root@node1 pratic]# kubectl get pod -w -l app=nginx
......
web-7   1/1     Terminating         0          2m50s
web-7   0/1     Terminating         0          2m52s
web-7   0/1     Terminating         0          2m53s
web-7   0/1     Terminating         0          2m53s
web-6   1/1     Terminating         0          3m6s
web-6   0/1     Terminating         0          3m7s
web-6   0/1     Terminating         0          3m8s
web-6   0/1     Terminating         0          3m8s
web-5   1/1     Terminating         0          3m16s
web-5   0/1     Terminating         0          3m17s
web-5   0/1     Terminating         0          3m25s
web-5   0/1     Terminating         0          3m25spodManagementPolicy
有时候StatefulSet的启停有序性并不是必要的,只需要网络标志和存储固定即可,所有可以使用podManagementPolicy字段控制
[root@node1 pratic]# cat >statusfulset-nginx2.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx2
  labels:
    app: nginx2
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx2
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web2
spec:
  serviceName: "nginx2"
  podManagementPolicy: "Parallel"
  replicas: 4
  selector:
    matchLabels:
      app: nginx2
  template:
    metadata:
      labels:
        app: nginx2
    spec:
      containers:
      - name: nginx2
        image: nginx:latest
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www2
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www2
      annotations:
        volume.beta.kubernetes.io/storage-class: "nfsserver"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 100Mi
EOF
测试查看创建Pod的顺序
[root@node1 pratic]# kubectl apply -f statusfulset-nginx2.yaml 
service/nginx2 created
statefulset.apps/web2 created
# 不再按顺序等待pod状态为running和ready,而是同时创建
[root@node1 pratic]# kubectl get pod -w -l app=nginx2
NAME     READY   STATUS              RESTARTS   AGE
web2-0   0/1     ContainerCreating   0          4s
web2-1   0/1     ContainerCreating   0          4s
web2-2   0/1     ContainerCreating   0          4s
web2-3   0/1     ContainerCreating   0          4s
web2-1   1/1     Running             0          8s
web2-3   1/1     Running             0          13s
web2-0   1/1     Running             0          19s
web2-2   1/1     Running             0          25s
正文完
   
  隐私政策
 隐私政策 留言板
 留言板 金色传说
 金色传说 kubernetes
 kubernetes terraform
 terraform 云生原
 云生原 helm
 helm 代码编程
 代码编程 Java
 Java Python
 Python Shell
 Shell DevOps
 DevOps Ansible
 Ansible Gitlab
 Gitlab Jenkins
 Jenkins 运维
 运维 老司机
 老司机 Linux 杂锦
 Linux 杂锦 Nginx
 Nginx 数据库
 数据库 elasticsearch
 elasticsearch 监控
 监控 上帝视角
 上帝视角 DJI FPV
 DJI FPV DJI mini 3 pro
 DJI mini 3 pro 关于本站
 关于本站