learning/k8s-intermediate/workload/wl-deployment/canary.md
如果您想使用 Deployment 将最新的应用程序版本发布给一部分用户(或服务器),您可以为每个版本创建一个 Deployment,此时,应用程序的新旧两个版本都可以同时获得生产上的流量。
<b-card> <b-tabs content-class="mt-3"> <b-tab title="使用 kubectl 执行金丝雀发布" active>部署第一个版本
第一个版本的 Deployment 包含了 3 个Pod副本,Service 通过 label selector app: nginx 选择对应的 Pod,nginx 的标签为 1.7.9
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: 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
假设此时想要发布新的版本 nginx 1.8.0,可以创建第二个 Deployment:
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
::: tip
app: nginx,由 nginx-deployment 和 nginx-deployment-canary 创建的 Pod 都带有标签 app: nginx,所以,Service 的流量将会在两个 release 之间分配当您确定新的版本没有问题之后,可以将 nginx-deployment 的镜像标签修改为新版本的镜像标签,并在完成对 nginx-deployment 的滚动更新之后,删除 nginx-deployment-canary 这个 Deployment
在 Kuboard 执行金丝雀发布的过程,与使用 kubectl 的过程相同,此处特别说明的一点是,当使用 Kuboard 创建 web-nginx-canary Deployment时,可以在原工作负载上点击 复制 按钮,如下图所示:
在弹出对话框的 名称 字段中填写 web-nginx-canary,如下图所示:
如何解决其Pod 的标签被 web-nginx 的Service包含的问题:
web-nginx-canary 之后,将默认创建两个标签,且不可修改:k8s.eip.work/layer:web 和 k8s.eip.work/name:web-nginx-canaryk8s.eip.work/name:web-nginx,可以覆盖原默认创建的标签web-nginx-canary 的 Pod 也包含标签 k8s.eip.work/layer:web 和 k8s.eip.work/name:web-nginx,可以被 web-nginx 的Service选中web-nginx-canary 部署时,无需配置 Service 和 Ingress::: danger 局限性 按照 Kubernetes 默认支持的这种方式进行金丝雀发布,有一定的局限性:
::: tip 在 Kubernetes 中不能解决上述局限性的原因是:Kubernetes Service 只在 TCP 层面解决负载均衡的问题,并不对请求响应的消息内容做任何解析和识别。如果想要更完善地实现金丝雀发布,可以考虑如下三种选择: