0x0034's Blog.

k8s灰度发布.md

字数统计: 718阅读时长: 3 min
2021/11/07

灰度发布解决方案

双Deployment滚动发布

就绪态解决方案

文件名称test-rolling.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: ikubernetes/myapp:v2
ports:
- containerPort: 80
readinessGates:
- conditionType: "www.example.com/feature-1"

strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
# 设置为0, 这个值设置为线上机器的数量*40%
# 所有机器数量不变
---
apiVersion: v1
kind: Service
metadata:
name: service-nginx
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: nginx

创建kubectl create -f test-rolling.yaml

情况下 Pod状态是就绪完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@kind-control-plane:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
discover-server-86cd6c6985-8vlqg 1/1 Running 0 2d3h
metabase-console-5b545d88d6-gzx7n 1/1 Running 0 2d5h
metabase-server-56b57f6dcc-f4vqv 1/1 Running 0 2d5h
mysql-storagedb-mysql-7cc7dfb7f5-9rg74 1/1 Running 0 2d10h
nginx-deployment-6c74c7555-8znvz 0/1 ContainerCreating 0 5s
nginx-deployment-6c74c7555-qtjs2 0/1 ContainerCreating 0 5s
root@kind-control-plane:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
discover-server-86cd6c6985-8vlqg 1/1 Running 0 2d3h
metabase-console-5b545d88d6-gzx7n 1/1 Running 0 2d5h
metabase-server-56b57f6dcc-f4vqv 1/1 Running 0 2d5h
mysql-storagedb-mysql-7cc7dfb7f5-9rg74 1/1 Running 0 2d10h
nginx-deployment-6c74c7555-8znvz 1/1 Running 0 46s
nginx-deployment-6c74c7555-qtjs2 1/1 Running 0 46s
root@kind-control-plane:~# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
discover-server 1/1 1 1 2d3h
metabase-console 1/1 1 1 2d5h
metabase-server 1/1 1 1 2d5h
mysql-storagedb-mysql 1/1 1 1 2d10h
nginx-deployment 0/2 2 0 69s

但是deployment中非ready状态

1
2
3
4
5
6
7
root@kind-control-plane:~# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
discover-server 1/1 1 1 2d3h
metabase-console 1/1 1 1 2d5h
metabase-server 1/1 1 1 2d5h
mysql-storagedb-mysql 1/1 1 1 2d10h
nginx-deployment 0/2 2 0 69s

需要使用curl去PATCH k8s的API接口修改- conditionType: "www.example.com/feature-1" 的就绪状态.

1
2
# 注: 其中的秘钥需要根据.kube/config 或者 kubectl config中的内容修改
curl --cert ./client.pem --key ./client-key.pem --cacert ./ca.pem https://localhost:39266/api/v1/namespaces/default/pods/nginx-deployment-6c74c7555-t9fn4/status -X PATCH -H "Content-Type: application/json-patch+json" -d '[{"op": "add", "path": "/status/conditions/-", "value": {"type": "www.example.com/feature-1", "status": "True", "lastProbeTime": null}}]'

其中nginx-deployment-6c74c7555-t9fn4为Pod的名称,需要依次触发上线.

仅限第一次操作.也就是需要激活Pod

执行更新

kubectl edit deployments.apps nginx-deployment

将其中的image: ikubernetes/myapp:v2改为image: ikubernetes/myapp:v3

按照yaml中的maxUnavailable: 0 maxSurge: 2 两个字段的设置,会启动至4个Pod, 我们需要手动对两个新的Pod进行确认.

即依旧使用curl方式修改就绪态.

新扩容出来的机器不会立马上线,虽然在Pod状态中是ready状态
但是在deployment中是处于Unready状态的,所以

并不会有任何的流量走到新建的pod上去,除非修改就绪状态

openkruise

openkruise是阿里开源的CRD.

使用cloneSet的资源控制器可以进行分区更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
# ...
generation: 2
spec:
replicas: 5
template:
metadata:
labels:
app: sample
spec:
containers:
- image: nginx:mainline
imagePullPolicy: Always
name: nginx
updateStrategy:
partition: 3
# ...
status:
observedGeneration: 2
readyReplicas: 5
replicas: 5
updateRevision: sample-56dfb978d4
updatedReadyReplicas: 2
updatedReplicas: 2

即可以选定分区进行更新

CATALOG
  1. 1. 灰度发布解决方案
    1. 1.1. 双Deployment滚动发布
    2. 1.2. 就绪态解决方案
      1. 1.2.1. 执行更新
    3. 1.3. openkruise