(四) Kubernetes基础之StatefulSet

171 阅读4分钟

StatefulSet

用于部署有状态且需要有序启动的应用程序。主要用于管路有状态应用程序的工作负载API对象。比如生产环境中部署ElasticSearch集群、MongoDB集群或者需要持久化的RabbitMQ集群、Redis集群、kafka集群和zookeeper集群等。

创建

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: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:nginx:1.15.2
        ports:
        - containerPort: 80
          name: web
» kubectl create -f statefulset-nginx.yaml
service/nginx created
statefulset.apps/web created

» kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          10s
web-1   1/1     Running   0          8s

扩容缩容

» kubectl scale --replicas=3 sts web
statefulset.apps/web scaled

» kubectl get sts
NAME   READY   AGE
web    3/3     2m33s

» kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          2m38s
web-1   1/1     Running   0          2m36s
web-2   1/1     Running   0          14s

创建过程

顺序创建 先创建web-0成功继续创建web-1,失败则停止创建。
从后往前删除 先删web-2,再web-1,最后web-0。

  • 删除或创建时若发生异常(某个节点挂掉) 则停止创建或删除

查看创建过程

$ kubectl get pods -w
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          9m38s
web-1   1/1     Running   0          9m36s
web-2   1/1     Running   0          7m14s

-- 新开窗口执行命令
» kubectl scale --replicas=5 sts web     
statefulset.apps/web scaled


-- 查看变化过程
» kubectl get pods -w
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          9m38s
web-1   1/1     Running   0          9m36s
web-2   1/1     Running   0          7m14s
web-3   0/1     Pending   0          0s
web-3   0/1     Pending   0          0s
web-3   0/1     ContainerCreating   0          0s
web-3   1/1     Running             0          2s
web-4   0/1     Pending             0          0s
web-4   0/1     Pending             0          0s
web-4   0/1     ContainerCreating   0          0s
web-4   1/1     Running             0          1s

更新策略

» kubectl get sts web -o yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  creationTimestamp: "2022-07-03T07:23:37Z"
  generation: 3
  name: web
  namespace: default
  resourceVersion: "56239"
  uid: 2fdc1f52-3858-49c0-9ecc-4250a63e69ce
spec:
  podManagementPolicy: OrderedReady
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  serviceName: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.2
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          name: web
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  updateStrategy: #更新策略
    rollingUpdate:
      partition: 0 # 更新大于等于partition的容器 (详解见下面)
    type: RollingUpdate #滚动更新,从后往前更新    OnDelete:只有手动删除才会更新镜像
status:
  availableReplicas: 5
  collisionCount: 0
  currentReplicas: 5
  currentRevision: web-6949d64dc8
  observedGeneration: 3
  readyReplicas: 5
  replicas: 5
  updateRevision: web-6949d64dc8
  updatedReplicas: 5

灰度发布

利用StatefulSet 更新策略我们可以实现灰度发布

假设有5个副本 web-0,web-1,web-2,web-3,web-4
设置 partition: 2,则滚动更新只会更新web-2,web-3,web-4

-- 修改滚动更新策略
» kubectl edit sts web
  updateStrategy:
    rollingUpdate:
      partition: 2
    type: RollingUpdate
    
-- 修改镜像版本
» kubectl edit sts web 
        image: nginx:1.15.3

-- 由创建时间可以看到web-2,web-3,web-4更新了,并且从web-4开始往上更新
» kubectl get po
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          32m
web-1   1/1     Running   0          32m
web-2   1/1     Running   0          4s
web-3   1/1     Running   0          6s
web-4   1/1     Running   0          45s


-- 查看pods镜像
» kubectl get po -oyaml | grep image
    - image: nginx:1.15.2
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.2
      imageID: docker-pullable://nginx@sha256:d85914d547a6c92faa39ce7058bd7529baacab7e0cd4255442b04577c4d1f424
    - image: nginx:1.15.2
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.2
      imageID: docker-pullable://nginx@sha256:d85914d547a6c92faa39ce7058bd7529baacab7e0cd4255442b04577c4d1f424
    - image: nginx:1.15.3
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.3
      imageID: docker-pullable://nginx@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
    - image: nginx:1.15.3
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.3
      imageID: docker-pullable://nginx@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
    - image: nginx:1.15.3
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.3
      imageID: docker-pullable://nginx@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3

级联删除和非级联删除

  • 级联删除:删除sts时,同时删除Pod (默认)
  • 非级联删除:删除sts时,不删除Pod
-- 非级联删除 --cascade=false
» kubectl delete sts web --cascade=false
warning: --cascade=false is deprecated (boolean value) and can be replaced with --cascade=orphan.
statefulset.apps "web" deleted

» kubectl get sts
No resources found in default namespace.

» kubectl get po
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          62s
web-1   1/1     Running   0          60s

-- 此时删除pod不会新建,因为sts已经不存在了
» kubectl delete po web-0 web-1
pod "web-0" deleted
pod "web-1" deleted
» kubectl get po
No resources found in default namespace.