Kubernetes与灰度发布的一些思考

看资料时看到了一个Kubernetes原生支持灰度发布的案例,他是利用两个发布不同版本的镜像Deployment实现的。这个方案的特点在于两个Deployment发布的Pod的标签是一致的(我这儿其实是有疑惑的,这样真的不会有影响到Deployment的调度么,我之前貌似进行过一个相关的实验,貌似标签一致的Pod也会被管理,可能我的实验是RS,而Deployment不存在该问题吧),而Service会将流量路由到指定标签的Pod上。

 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
  - name: nginx-port
    protocol: TCP
    port: 80
    nodePort: 32600
    targetPort: 80
  type: NodePort

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-canary
  labels:
    app: nginx
    track: canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      track: canary
  template:
    metadata:
      labels:
        app: nginx
        track: canary
    spec:
      containers:
      - name: nginx
        image: nginx:1.8.0

这样Service的流量将会在两个release之间分配,且在新旧版本之间,流量分配的比例为两个版本副本数的比例,此处为1:3。当确定了新的版本没有问题之后,可以将nginx-deployment的镜像标签改为新版本的镜像,然后进行滚动更新。

Kubernetes Service 只在 TCP 层面解决负载均衡的问题,并不对请求响应的消息内容做任何解析和识别。因此这个方案是有局限性地:

  1. 不能根据用户注册时间、地区等请求中的内容属性进行流量分配
  2. 同一个用户如果多次调用该Service,有可能第一次请求到了旧版本的Pod,第二次请求到了新版本的Pod

我们可以考虑如下方案:

  1. 业务代码编码实现
  2. Spring Cloud灰度发布
  3. Istio灰度发布

(突然发现自己基本功还是不够)