一、StatefulSet灰度发布

通过声明 .spec.updateStrategy.rollingUpdate.partition 的方式,RollingUpdate 更新策略可以实现分区。 如果声明了一个分区,当 StatefulSet 的 .spec.template 被更新时, 所有序号大于等于该分区序号的 Pod 都会被更新。 所有序号小于该分区序号的 Pod 都不会被更新,并且,即使它们被删除也会依据之前的版本进行重建。 如果 StatefulSet 的 .spec.updateStrategy.rollingUpdate.partition 大于它的 .spec.replicas,则对它的 .spec.template 的更新将不会传递到它的 Pod。 在大多数情况下,你不需要使用分区,但如果你希望进行阶段更新、执行金丝雀或执行分阶段上线,则这些分区会非常有用。

StatefulSet灰度发布-分段更新

1.定义一个yaml文件,其中partition: 3,replicas: 5。

$ vim stateful.yaml
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:
  updateStrategy:
    rollingUpdate:
      partition: 3
    type: RollingUpdate
  serviceName: "nginx"
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        ports:
        - containerPort: 80
          name: web

2.查看目前pod镜像

$ k get po -l app=nginx -oyaml | grep image:
    - image: nginx:1.9.1
      image: docker.io/library/nginx:1.9.1
    - image: nginx:1.9.1
      image: docker.io/library/nginx:1.9.1

3.创建StatefulSet文件

$ k replace -f stateful.yaml
service/nginx replaced
statefulset.apps/web replaced

4.再次查看pod状态,观察到只有web-3和web-4自动更新,实现了简单的灰度发布

$ k get po -l app=nginx -oyaml | grep image:
    - image: nginx:1.9.1
      image: docker.io/library/nginx:1.9.1
    - image: nginx:1.9.1
      image: docker.io/library/nginx:1.9.1
    - image: nginx:1.9.1
      image: docker.io/library/nginx:1.9.1
    - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
      image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
    - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
      image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2

二、StatefulSet删除策略

删除StatefulSet有两种方式,即级联删除和非级联删除。使用非级联方式删除 StatefulSet时, StatefulSet 的 Pod 不会被删除;使用级联删除时,StatefulSet 和它的 Pod 都会被删除

2.1 非级联删除

使用 kubectl delete sts xxx 删除 StatefulSet 时,只需提供--cascade=false 参数,就会采用 非级联删除,此时删除 StatefulSet 不会删除它的 Pod

下面进行示例说明:

1.使用kubectl delete sts xxx删除 StatefulSet

$ k delete statefulset web --cascade=false

2.查看sts已被删除

$ kubectl get sts
No resources found in default namespace.

3.查看pod未被删除

$ k get po
NAME             READY   STATUS    RESTARTS      AGE
web-0            1/1     Running   0             33m
web-1            1/1     Running   0             33m
web-2            1/1     Running   0             33m
web-3            1/1     Running   0             26m
web-4            1/1     Running   0             26m

4.删除web-0

$ k delete pod web-0
pod "web-0" deleted

5.由于此时删除了 StatefulSet,它管理的 Pod 变成了“孤儿”Pod,因此单独删除 Pod 时,该 Pod 不会被重建

$ k get po
NAME             READY   STATUS    RESTARTS      AGE
etcd-with-grpc   1/1     Running   2 (97m ago)   11h
web-1            1/1     Running   0             34m
web-2            1/1     Running   0             34m
web-3            1/1     Running   0             27m
web-4            1/1     Running   0             27m

2.2 级联删除

使用 kubectl delete sts xxx删除 StatefulSet 时,就会采用 级联删除,此时删除 StatefulSet 时一并删除它的 Pod

下面进行示例说明:

1.使用kubectl delete sts xxx删除 StatefulSet

$ k delete sts web
statefulset.apps "web" deleted

2.查看sts

$ k get sts
No resources found in default namespace.

3.查看pod,观察到pod已被删除

$ k get po -l app=nginx
No resources found in default namespace.