k8s-Statefulset 资源

6,393次阅读
没有评论
k8s-Statefulset

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
EOF

Pod启停有序性

观察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          9s

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地址

# 创建一个静态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          9s

2.测试此时重建的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-4

2.删除所有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

3.查看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                               35m

4.验证每个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-4

StatefulSet扩缩容

扩容

[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          3m25s

podManagementPolicy

有时候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
293
xadocker
版权声明:本站原创文章,由 xadocker2022-03-12发表,共计9555字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码
载入中...