kubernetes的Ingress实现软件发布的蓝绿和金丝雀模式

 

 

软件发布/发版模式

蓝绿 v1.0 v2.0 v3.0
金丝雀、灰度

 

蓝绿 生产两个版本两套服务器环境 v1.0 v2.0  更新新版本v2.0 50台服务器v1.0 50台服务器v2.0  v2.0 没有问题 把v1.0服务器更新到 v2.0 ,或者v2.0发布出去有问题,回滚到v1.0 

 

金丝雀、灰度

v1.0 99%
v2.0 1%

v1.0 50%
v2.0 50%

v1.0 0%
v2.0 100%

 

 

实现service 蓝绿发布

[root@master1 ingress]# cat deployment-myapp1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp
    version: v0.1
  name: myapp1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: v0.1
  strategy: {}
  template:
    metadata:
      labels:
        app: myapp
        version: v0.1
    spec:
      containers:
      - image: registry.cn-beijing.aliyuncs.com/wangxiaochun/pod-test:v0.1
        name: pod-test
        resources: {}
status: {}

 

[root@master1 ingress]# cat deployment-myapp2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp
    version: v0.2
  name: myapp2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: v0.2
  strategy: {}
  template:
    metadata:
      labels:
        app: myapp
        version: v0.2
    spec:
      containers:
      - image: registry.cn-beijing.aliyuncs.com/wangxiaochun/pod-test:v0.2
        name: pod-test
        resources: {}
status: {}

 

kubectl apply -f deployment-myapp1.yaml

kubectl apply -f deployment-myapp2.yaml

 

[root@master1 ingress]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE    IP             NODE        NOMINATED NODE   READINESS GATES
myapp1-64ff8b9f4b-g2nt9   1/1     Running   0          170m   10.244.2.2     node2.org   <none>           <none>
myapp1-64ff8b9f4b-jxh6c   1/1     Running   0          170m   10.244.1.254   node1.org   <none>           <none>
myapp1-64ff8b9f4b-vjdbw   1/1     Running   0          170m   10.244.1.253   node1.org   <none>           <none>
myapp2-7f5bc74fd4-8f6qc   1/1     Running   0          170m   10.244.1.2     node1.org   <none>           <none>
myapp2-7f5bc74fd4-nwcrj   1/1     Running   0          170m   10.244.1.3     node1.org   <none>           <none>
myapp2-7f5bc74fd4-w4pjf   1/1     Running   0          170m   10.244.2.3     node2.org   <none>           <none>

deployment 有3个pod 0.1版本 有3个0.2版本

root@master1 ingress]# cat svc-myapp.yaml    
apiVersion: v1
kind: Service
metadata:
  labels:
    app: myapp
    version: v0.1
  name: myapp-svc
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myapp
    version: v0.1
  type: LoadBalancer

 

kubectl apply -f svc-myapp.yaml

 

[root@master1 ingress]# kubectl get svc  --show-labels
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE   LABELS
kubernetes   ClusterIP      10.96.0.1      <none>         443/TCP        16d   component=apiserver,provider=kubernetes
myapp-svc    LoadBalancer   10.108.9.110   192.168.3.11   80:32247/TCP   41s   app=myapp,version=v0.1

 

[root@master1 ingress]# 
[root@master1 ingress]# kubectl get ep
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
NAME         ENDPOINTS                                       AGE
kubernetes   192.168.3.60:6443                               16d
myapp-svc    10.244.1.253:80,10.244.1.254:80,10.244.2.2:80   27s

 

 

现在是0.1版本

[root@node1 ~]# curl 192.168.3.11
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-vjdbw, ServerIP: 10.244.1.253!

现在蓝绿要变成蓝版新版本 0.2  访问期间service规约文件 version标签改成0.2

 

0.1

root@node1 ~]# while :; do curl 192.168.3.11;sleep 1;done
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-jxh6c, ServerIP: 10.244.1.254!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-jxh6c, ServerIP: 10.244.1.254!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-vjdbw, ServerIP: 10.244.1.253!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-vjdbw, ServerIP: 10.244.1.253!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.0, ServerName: myapp1-64ff8b9f4b-g2nt9, ServerIP: 10.244.2.2!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.0, ServerName: myapp1-64ff8b9f4b-g2nt9, ServerIP: 10.244.2.2!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.0, ServerName: myapp1-64ff8b9f4b-g2nt9, ServerIP: 10.244.2.2!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.0, ServerName: myapp1-64ff8b9f4b-g2nt9, ServerIP: 10.244.2.2!

 

[root@master1 ingress]# cat svc-myapp.yaml    
apiVersion: v1
kind: Service
metadata:
  labels:
    app: myapp
    version: v0.2
  name: myapp-svc
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myapp
    version: v0.2
  type: LoadBalancer

kubectl apply -f svc-myapp.yaml

 

kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-jxh6c, ServerIP: 10.244.1.254!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.0, ServerName: myapp1-64ff8b9f4b-g2nt9, ServerIP: 10.244.2.2!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.0, ServerName: myapp1-64ff8b9f4b-g2nt9, ServerIP: 10.244.2.2!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.0, ServerName: myapp1-64ff8b9f4b-g2nt9, ServerIP: 10.244.2.2!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-vjdbw, ServerIP: 10.244.1.253!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-jxh6c, ServerIP: 10.244.1.254!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-vjdbw, ServerIP: 10.244.1.253!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-vjdbw, ServerIP: 10.244.1.253!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.0, ServerName: myapp1-64ff8b9f4b-g2nt9, ServerIP: 10.244.2.2!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-jxh6c, ServerIP: 10.244.1.254!
kubernetes pod-test v0.1!! ClientIP: 10.244.1.1, ServerName: myapp1-64ff8b9f4b-vjdbw, ServerIP: 10.244.1.253!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.0, ServerName: myapp2-7f5bc74fd4-w4pjf, ServerIP: 10.244.2.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-8f6qc, ServerIP: 10.244.1.2!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-nwcrj, ServerIP: 10.244.1.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-8f6qc, ServerIP: 10.244.1.2!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.0, ServerName: myapp2-7f5bc74fd4-w4pjf, ServerIP: 10.244.2.3!

 

一执行马上切换 0.2 的pod

kubernetes pod-test v0.2!! ClientIP: 10.244.1.0, ServerName: myapp2-7f5bc74fd4-w4pjf, ServerIP: 10.244.2.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-8f6qc, ServerIP: 10.244.1.2!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-nwcrj, ServerIP: 10.244.1.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-8f6qc, ServerIP: 10.244.1.2!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.0, ServerName: myapp2-7f5bc74fd4-w4pjf, ServerIP: 10.244.2.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-nwcrj, ServerIP: 10.244.1.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-nwcrj, ServerIP: 10.244.1.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-8f6qc, ServerIP: 10.244.1.2!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.0, ServerName: myapp2-7f5bc74fd4-w4pjf, ServerIP: 10.244.2.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.1, ServerName: myapp2-7f5bc74fd4-8f6qc, ServerIP: 10.244.1.2!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.0, ServerName: myapp2-7f5bc74fd4-w4pjf, ServerIP: 10.244.2.3!
kubernetes pod-test v0.2!! ClientIP: 10.244.1.0, ServerName: myapp2-7f5bc74fd4-w4pjf, ServerIP: 10.244.2.3!

 

匹配住0.2的pod

[root@master1 ingress]# kubectl get svc  --show-labels 
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE     LABELS
kubernetes   ClusterIP      10.96.0.1      <none>         443/TCP        16d     component=apiserver,provider=kubernetes
myapp-svc    LoadBalancer   10.108.9.110   192.168.3.11   80:32247/TCP   7m48s   app=myapp,version=v0.2

 

yapp-svc    LoadBalancer   10.108.9.110   192.168.3.11   80:32247/TCP   7m48s   app=myapp,version=v0.2
[root@master1 ingress]# kubectl get ep  --show-labels   
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
NAME         ENDPOINTS                                   AGE     LABELS
kubernetes   192.168.3.60:6443                           16d     endpointslice.kubernetes.io/skip-mirror=true
myapp-svc    10.244.1.2:80,10.244.1.3:80,10.244.2.3:80   8m26s   app=myapp,endpoints.kubernetes.io/managed-by=endpoint-controller,version=v0.2

0.1 0.2 pod也存在 回滚版本 修改标签就可以了 流量切换

service标签方法切换实现 蓝绿

 Service 支持流量分配,只支持基于Pod的数量或比例实现

 

Ingress Nginx 实现蓝绿 BlueGreen 和灰度Canary 发布

Ingress Nginx 进行BlueGreen 和 Canary 灰度发布说明

Service 虽然支持流量分配,但是只支持基于Pod的数量或比例实现,而不支持基于Header,cookie,权重等更为清确的流量发配策略


Ingress-Nginx支持配置Ingress Annotations来实现不同场景下的灰度发布和测试,它能够满足金丝雀发布、蓝绿部署与A/B测试等不同的业务场景
注意:Ingress-Nginx 只能支持南北向的流量发布,而东西向流量的发布可以利用工作负载型如deployment的更新策略或者服务网格技术实现


Ingress Nginx的流量发布机制:

image

 

蓝绿:

  • production: 100%, canary: 0%
  • production: 0%, canary: 100% --> Canary变成后面的Production


金丝雀 Canary:
流量比例化切分: weight 比例逐渐调整   90%旧版本 10% 新版本  10%旧版本 90% 新版本
流量识别,将特定的流量分发给Canary:


By-Header:基于特定的标头识别
Header 值默认:只有Always 或 Nerver 两种值
Header 值自定义
Header 值可以基于正则表达式Pattern进行匹配
By-Cookie: 基于Cookie识别

 

 

基于Ingress Nginx的Canary规则
Ingress Nginx 的 Annotations支持的Canary规则, Annotations 和 Label 相似也是保存资源对象上的
元数据,但不能被标签选择器选择,且没有Label的名称最长63个字符的限制


nginx.ingress.kubernetes.io/canary-weight:

  • 基于服务权重进行流量切分,适用于蓝绿或灰度发布,权重范围0 - 100按百分比将请求路由到Canary Ingress中指定的服务
  • 权重为 0 意味着该金丝雀规则不会向Canary入口的服务发送任何请求
  • 权重为100意味着所有请求都将被发送到 Canary 入口

nginx.ingress.kubernetes.io/canary-by-cookie:

  • 基于 cookie 的流量切分,适用于灰度发布与 A/B 测试
  • cookie 的值设置为 always 时,它将被路由到Canary入口
  • cookie 的值设置为 never 时,请求不会被发送到Canary入口
  • 对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较,默认转发给旧版本

nginx.ingress.kubernetes.io/canary-by-header:

  • 基于该Annotation中指定Request Header进行流量切分,适用于灰度发布以及A/B测试
  • 在请求报文中,若存在该Header且其值为always时,请求将会被发送到Canary版本,注意:always是大小敏感
  • 若存在该Header且其值为never,请求将不会被发送至Canary版本
  • 若存在该Header且其值为任何其它值,将忽略该Annotation指定的Header,并按优先级将请求与其他金丝雀规则进行比较,默认转发给旧版本
  • 若不存在该Header时,请求将不会被发送至Canary版本

nginx.ingress.kubernetes.io/canary-by-header-value:

  • 基于该Annotation中指定的Request Header的值进行流量切分,Header名称则由前一个Annotation(nginx.ingress.kubernetes.io/canary-by-header)进行指定
  • 请求报文中存在指定的Header,且其值与该Annotation的值匹配时,它将被路由到Canary版本对于任何其它值,将忽略该Annotation,默认转发给旧版本

nginx.ingress.kubernetes.io/canary-by-header-pattern

  • 同canary-by-header-value的功能类似,但该Annotation基于正则表达式匹配Request Header的值
  • 若该Annotation与canary-by-header-value同时存在,则该Annotation会被忽略,默认转发给旧版本

 


规则的应用次序
Canary规则会按特定的次序进行评估
优先级从低到高顺序: canary-weight-> canary-by-cookie -> canary-by-header

 

 

范例:初始环境准备新旧两个版本应用和Ingress

#准备新旧版本对应的各自独立的两套deployment和service

 

[root@master1 ingress]# cat deploy-pod-test-v1.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: pod-test
  name: pod-test-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pod-test
      version: v0.1
  strategy: {}
  template:
    metadata:
      labels:
        app: pod-test
        version: v0.1
    spec:
      containers:
      - image: registry.cn-beijing.aliyuncs.com/wangxiaochun/pod-test:v0.1
        name: pod-test
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: pod-test
  name: pod-test-v1
spec:
  ports:
  - name: http-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: pod-test
    version: v0.1
  type: ClusterIP

 

 

[root@master1 ingress]# cat deploy-pod-test-v2.yaml  
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: pod-test
  name: pod-test-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pod-test
      version: v0.2
  strategy: {}
  template:
    metadata:
      labels:
        app: pod-test
        version: v0.2
    spec:
      containers:
      - image: registry.cn-beijing.aliyuncs.com/wangxiaochun/pod-test:v0.2
        name: pod-test

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: pod-test
  name: pod-test-v2
spec:
  ports:
  - name: http-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: pod-test
    version: v0.2
  type: ClusterIP

 

#部署新旧两个版本

kubectl apply -f deploy-pod-test-v1.yaml -f deploy-pod-test-v2.yaml

 

 

[root@master1 ingress]# kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP   16d
pod-test-v1   ClusterIP   10.111.225.91    <none>        80/TCP    9s
pod-test-v2   ClusterIP   10.106.119.251   <none>        80/TCP    9s
[root@master1 ingress]# 
[root@master1 ingress]# kubectl get pod -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP           NODE        NOMINATED NODE   READINESS GATES
pod-test-v1-65cf4d8c45-d44t9   1/1     Running   0          15s   10.244.1.5   node1.org   <none>           <none>
pod-test-v2-54c45485c9-hj56g   1/1     Running   0          15s   10.244.1.4   node1.org   <none>           <none>

#创建Ingress对应旧版本的应用

 

[root@master1 ingress]# cat ingress-pod-test.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pod-test
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"  
    nginx.ingress.kubernetes.io/session-cookie-expires: "172800"  #可选
    nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"  #可选
  #  kubernetes.io/ingress.class: nginx
spec:
  ingressClassName: nginx
  rules:
  - host: www.ming.org
    http:
      paths:
      - backend:
          service:
            name: pod-test-v1
            port: 
              number: 80
        path: /
        pathType: Prefix

 

#配置说明
#启用基于cookie的会话亲和性。这意味着,当同一个客户端发起一系列请求时,这些请求将被路由到同一个后端Pod。

#这是通过在一个cookie中存储后端Pod的选择信息来实现的。当客户端第一次请求时,Ingress控制器会在
响应中设置一个cookie,后续客户端请求应携带此cookie,以便Ingress控制器将请求路由到相同的后端。


nginx.ingress.kubernetes.io/affinity: "cookie"
#指定用于会话亲和性的cookie的名称。这里设置为"route"。
nginx.ingress.kubernetes.io/session-cookie-name: "route"
#指定cookie的过期时间(以秒为单位)。这里设置为172800秒,即48小时。默认是会话级的有效期
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
#指定cookie的最大年龄(以秒为单位)。这里同样设置为172800秒,即48小时。默认是会话级的有效期
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"

 

 kubectl apply -f ingress-pod-test.yaml

[root@master1 ingress]# kubectl get ingress
NAME       CLASS   HOSTS          ADDRESS        PORTS   AGE
pod-test   nginx   www.ming.org   192.168.3.10   80      68s

 

#集群外客户端访问

C:\Users\Administrator>curl www.ming.org
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!

 

现在让用户把请求切换到0.2新版本

#持续执行观察

while :; do curl -H"host: www.ming.org" 192.168.3.10;sleep 1;done

[root@node1 ~]# while :; do curl -H"host: www.ming.org" 192.168.3.10;sleep 1;done
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!

 

 范例:蓝绿发布 

完整切换到新版本

让用户切换0.2新版本

[root@master1 ingress]# kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP   16d
pod-test-v1   ClusterIP   10.111.225.91    <none>        80/TCP    14m
pod-test-v2   ClusterIP   10.106.119.251   <none>        80/TCP    14m

 

#方法1:在线编辑

kubectl edit ingress pod-test

 http:
     paths:
      - backend:
          service:
            #name: pod-test-v1
           name: pod-test-v2         #修改此行,指向新版应用的SVC

 

#客户端访问,观察全部都切换至新版本

while :; do curl -H"host: www.ming.org" 192.168.3.10;sleep 1;done

 

切换了

rnetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!

 

ubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 1

 

#修改上前的Ingress清单文件,对应使用新版本的应用
#方法2

#回滚旧版本

vim ingress-pod-test.yaml

http:
     paths:
      - backend:
          service:
            #name: pod-test-v2   
           name: pod-test-v1         #指向旧版应用的SVC
           port: 
             number: 80
       path: /
       pathType: Prefix

#应用

kubectl apply -f ingress-pod-test.yaml 

kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerI

 

 

 

范例:基于权重的金丝雀发布

先发布一部分让用户访问新版本 10%的人访问新版本 90%的人访问旧版本

#新版的清单文件

[root@master1 ingress]# cat canary-by-weight.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true" 
    nginx.ingress.kubernetes.io/canary-weight: "10"       #指定使用金丝雀发布新版占用的百分比10
    #因为用户访问时先判断走Stable还是Canary, 再在对应版本里选择具体Pod,所以下面两条不能实现第一步的版本绑定,最终仍然可以无法实现会话粘性    
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"    
    #下面配置可以让同一个用户粘在一个版本,不反复横跳,但需要配合上面两条配置才能实现会话粘性   
    nginx.ingress.kubernetes.io/affinity-canary-behavior: "sticky"    
  name: pod-test-canary-by-weight 
spec:
  ingressClassName: nginx
  rules:
  - host: www.ming.org
    http:
      paths:
      - backend:
          service:
            name: pod-test-v2
            port:
              number: 80 
        path: /
        pathType: Prefix

金丝雀主要应用在pod-test-v2 0.2新版本

 

annotations:
nginx.ingress.kubernetes.io/canary: "true"  #开启金丝雀
nginx.ingress.kubernetes.io/canary-weight: "10" #指定使用金丝雀发布新版占用的百分比10  指定多少人使用新版本
#因为用户访问时先判断走Stable还是Canary, 再在对应版本里选择具体Pod,所以下面两条不能实现第一步的版本绑定,最终仍然可以无法实现会话粘性
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
#下面配置可以让同一个用户粘在一个版本,不反复横跳,但需要配合上面两条配置才能实现会话粘性
nginx.ingress.kubernetes.io/affinity-canary-behavior: "sticky"

 

kubectl apply -f canary-by-weight.yaml

 

客户端访问,观察新旧版本的比例

while :; do curl -H"host: www.ming.org" 192.168.3.10;sleep 1;done

ernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5

etes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.2

缺点用户 不能固定访问新版本 用户一会访问新版本 一会访问旧版本

nginx.ingress.kubernetes.io/affinity: "cookie"
  nginx.ingress.kubernetes.io/session-cookie-name: "route"    
   #下面配置可以让同一个用户粘在一个版本,不反复横跳,但需要配合上面两条配置才能实现会话粘性  
  nginx.ingress.kubernetes.io/affinity-canary-behavior: "sticky"

 

有cookie

[root@node1 ~]# curl -H"host: www.ming.org" 192.168.3.10 -v
*   Trying 192.168.3.10:80...
* Connected to 192.168.3.10 (192.168.3.10) port 80 (#0)
> GET / HTTP/1.1
> Host: www.ming.org
> User-Agent: curl/7.76.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Tue, 26 May 2026 16:57:50 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 115
< Connection: keep-alive
< Set-Cookie: route=1779814671.848.1267.504138|9e44f10a8928e75574156ebd60af071c; Expires=Thu, 28-May-26 16:57:50 GMT; Max-Age=172800; Path=/; HttpOnly
< 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
* Connection #0 to host 192.168.3.10 left intact

这个值会变 Set-Cookie: route=1779814719.929.1266.280833|  route是cookie名字

root@node1 ~]# curl -H"host: www.ming.org" 192.168.3.10 -v
*   Trying 192.168.3.10:80...
* Connected to 192.168.3.10 (192.168.3.10) port 80 (#0)
> GET / HTTP/1.1
> Host: www.ming.org
> User-Agent: curl/7.76.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Tue, 26 May 2026 16:58:38 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 115
< Connection: keep-alive
< Set-Cookie: route=1779814719.929.1266.280833|9e44f10a8928e75574156ebd60af071c; Expires=Thu, 28-May-26 16:58:38 GMT; Max-Age=172800; Path=/; HttpOnly
< 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
* Connection #0 to host 192.168.3.10 left intact

基于cookie实现绑定 

 先确定是0.1版本还是0.2版本 按照比例分   10%新版本 90%旧版本  先把比例分开 转发给各个pod

10%的人第一次访问新版本 下次永远也是访问新版本 基于cookie

 

让用户这次访问 新版本下次也是访问新版本,这次访问旧版本,下次也是访问旧版本

这次访问把cookie存下来,下次访问带上这个cookie

curl 存储cookie 访问带上cookie

 

-c 存储cookie 到文件

curl -H"host: www.ming.org" -c'cookie.txt' 192.168.3.10 -v

 

[root@node1 ~]# curl -H"host: www.ming.org" -c'cookie.txt' 192.168.3.10 -v
*   Trying 192.168.3.10:80...
* Connected to 192.168.3.10 (192.168.3.10) port 80 (#0)
> GET / HTTP/1.1
> Host: www.ming.org
> User-Agent: curl/7.76.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Tue, 26 May 2026 17:11:39 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 115
< Connection: keep-alive
* Added cookie route="1779815500.863.1267.338438|9e44f10a8928e75574156ebd60af071c" for domain www.ming.org, path /, expire 1779988299
< Set-Cookie: route=1779815500.863.1267.338438|9e44f10a8928e75574156ebd60af071c; Expires=Thu, 28-May-26 17:11:39 GMT; Max-Age=172800; Path=/; HttpOnly
< 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
* Connection #0 to host 192.168.3.10 left intact

 

[root@node1 ~]# ll
total 8
-rw-------. 1 root root 987 May  7 15:29 anaconda-ks.cfg
-rw-r--r--  1 root root 245 May 27 01:11 cookie.txt

 

把cookie存到文件

[root@node1 ~]# cat cookie.txt 
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

#HttpOnly_www.ming.org  FALSE   /       FALSE   1779988299      route   1779815500.863.1267.338438|9e44f10a8928e75574156ebd60af071c

 

-b 携带cookie访问 使用刚刚存下来cookie

curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 -v 

[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 -v 
*   Trying 192.168.3.10:80...
* Connected to 192.168.3.10 (192.168.3.10) port 80 (#0)
> GET / HTTP/1.1
> Host: www.ming.org
> User-Agent: curl/7.76.1
> Accept: */*
> Cookie: route=1779815500.863.1267.338438|9e44f10a8928e75574156ebd60af071c
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Tue, 26 May 2026 17:15:08 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 115
< Connection: keep-alive
< 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
* Connection #0 to host 192.168.3.10 left intact
[root@node1 ~]# 

不变了版本固定了 这次是v1 下次也是v1 ,这次是v2 下次也是v2 实现会话绑定 底层基于cookie做

[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!

 

#调整weight权重为50

用户新版本访问不错 把访问比例改打

vim canary-by-weight.yaml

nginx.ingress.kubernetes.io/canary-weight: "50"

kubectl apply -f canary-by-weight.yaml

 

#观察比例变化

while :; do curl -H"host: www.ming.org" 192.168.3.10;sleep 1;done

rnetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g,

刚才存下来cookie  cookie访问的 已经固定版本

[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!

 

用户新版本访问没问题 全部改成新版本 

比例改成100%

vim canary-by-weight.yaml

nginx.ingress.kubernetes.io/canary-weight: "100"

 

[root@master1 ingress]# cat canary-by-weight.yaml    
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true" 
    nginx.ingress.kubernetes.io/canary-weight: "100"       #指定使用金丝雀发布新版占用的百分比10
    #因为用户访问时先判断走Stable还是Canary, 再在对应版本里选择具体Pod,所以下面两条不能实现第一步的版本绑定,最终仍然可以无法实现会话粘性    
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"    
    #下面配置可以让同一个用户粘在一个版本,不反复横跳,但需要配合上面两条配置才能实现会话粘性   
    nginx.ingress.kubernetes.io/affinity-canary-behavior: "sticky"    
  name: pod-test-canary-by-weight 
spec:
  ingressClassName: nginx
  rules:
  - host: www.ming.org
    http:
      paths:
      - backend:
          service:
            name: pod-test-v2
            port:
              number: 80 
        path: /
        pathType: Prefix

 

kubectl apply -f canary-by-weight.yaml

#观察比例变化

while :; do curl -H"host: www.ming.org" 192.168.3.10;sleep 1;done

 

全部都是新版本

kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!

 

用存下来cookie访问 固定版本

root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!

 

root@node1 ~]# curl -H"host: www.ming.org" -c'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10   
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!

 

 

回滚到旧版本

vim canary-by-weight.yaml

[root@master1 ingress]# 
[root@master1 ingress]# cat canary-by-weight.yaml    
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true" 
    nginx.ingress.kubernetes.io/canary-weight: "0"       #指定使用金丝雀发布新版占用的百分比10
    #因为用户访问时先判断走Stable还是Canary, 再在对应版本里选择具体Pod,所以下面两条不能实现第一步的版本绑定,最终仍然可以无法实现会话粘性    
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"    
    #下面配置可以让同一个用户粘在一个版本,不反复横跳,但需要配合上面两条配置才能实现会话粘性   
    nginx.ingress.kubernetes.io/affinity-canary-behavior: "sticky"    
  name: pod-test-canary-by-weight 
spec:
  ingressClassName: nginx
  rules:
  - host: www.ming.org
    http:
      paths:
      - backend:
          service:
            name: pod-test-v2
            port:
              number: 80 
        path: /
        pathType: Prefix

 

nginx.ingress.kubernetes.io/canary-weight: "0" #修改新版比例为0,完全回滚

 

kubectl apply -f canary-by-weight.yaml

#观察比例变化

while :; do curl -H"host: www.ming.org" 192.168.3.10;sleep 1;done

 回滚到旧版本

kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!
kubernetes pod-test v0.1!! ClientIP: 10.244.2.248, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.5!

 

cookie还是新版本 cookie可以设置有效期

root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!
[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org" -b'cookie.txt' 192.168.3.10 
kubernetes pod-test v0.2!! ClientIP: 10.244.2.248, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.4!

 

 

范例:基于 Cookie 实现金丝雀发布

 

#环境清理

kubectl delete -f canary-by-weight.yaml

#旧版应用
kubectl apply -f ingress-pod-test.yaml

#清单文件

[root@master1 ingress]# cat canary-by-cookie.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    #kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "vip_user" #cookie中vip_user=always时才用金丝雀发布下面新版本
    #下面配置可以让同一个用户粘在一个版本,不反复横跳,但需要配合上面两条配置才能实现会话粘性   
    nginx.ingress.kubernetes.io/affinity-canary-behavior: "sticky"      
  name: pod-test-canary-by-cookie
spec:
  ingressClassName: nginx
  rules:
  - host: www.ming.org
    http:
      paths:
      - backend:
          service:
            name: pod-test-v2
            port:
              number: 80
        path: /
        pathType: Prefix

 

 kubectl apply -f canary-by-cookie.yaml

[root@master1 ingress]# kubectl get ingress
NAME                        CLASS   HOSTS          ADDRESS        PORTS   AGE
pod-test                    nginx   www.ming.org   192.168.3.10   80      16h
pod-test-canary-by-cookie   nginx   www.ming.org   192.168.3.10   80      46s

 

客户端访问,当cookie中有vip_user=always时才用金丝雀发布新版

[root@node1 ~]# curl -H"host: www.ming.org" -b"vip_user=always" 192.168.3.10 
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!

 

[root@node1 ~]# curl -H"host: www.ming.org" -b"vip_user=always" 192.168.3.10 -v
*   Trying 192.168.3.10:80...
* Connected to 192.168.3.10 (192.168.3.10) port 80 (#0)
> GET / HTTP/1.1
> Host: www.ming.org
> User-Agent: curl/7.76.1
> Accept: */*
> Cookie: vip_user=always
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 27 May 2026 08:59:23 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 113
< Connection: keep-alive
< Set-Cookie: route=1779872364.004.22.798616|cccd1d5d90e2d025e6024ce40dbde635; Expires=Fri, 29-May-26 08:59:23 GMT; Max-Age=172800; Path=/; HttpOnly
< 
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!
* Connection #0 to host 192.168.3.10 left intact

 

客户端访问,当cookie中有vip_user!=always的其它值,或没有vip_user时则不使用金丝发布

[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org" -b"vip_user=alwaS" 192.168.3.10 
kubernetes pod-test v0.1!! ClientIP: 10.244.2.4, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.10!

#清理环境

kubectl delete -f canary-by-cookie.yaml

 

范例:基于请求 Header 固定值的金丝雀发布

#旧版应用

kubectl apply -f ingress-pod-test.yaml 

 

清单文件

[root@master1 ingress]# cat canary-by-header.yaml    
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    #kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true" 
    nginx.ingress.kubernetes.io/canary-by-header: "X-Canary" #X-Canary自定义的首部字段值为always时才使用金丝雀发布下面新版本,否则为旧版本
  name: pod-test-canary-by-header
spec:
  ingressClassName: nginx
  rules:
  - host: www.ming.org
    http:
      paths:
      - backend:
          service:
            name: pod-test-v2
            port: 
              number: 80
        path: /
        pathType: Prefix

 

kubectl apply -f canary-by-header.yaml

 

客户端访问,注意:always的小写的

#当X-Canary: always则访问v0.2新版

[root@node1 ~]# curl -H"host: www.ming.org" -H"X-Canary: always" 192.168.3.10                   
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!

 

[root@node1 ~]# curl -H"host: www.ming.org" -H"X-Canary: always" 192.168.3.10  -v
*   Trying 192.168.3.10:80...
* Connected to 192.168.3.10 (192.168.3.10) port 80 (#0)
> GET / HTTP/1.1
> Host: www.ming.org
> User-Agent: curl/7.76.1
> Accept: */*
> X-Canary: always
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 27 May 2026 09:12:16 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 113
< Connection: keep-alive
< Set-Cookie: route=1779873137.933.22.938894|cccd1d5d90e2d025e6024ce40dbde635; Expires=Fri, 29-May-26 09:12:16 GMT; Max-Age=172800; Path=/; HttpOnly
< 
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!
* Connection #0 to host 192.168.3.10 left intact

#当X-Canary 是其它值则访问v0.1旧版

#当没有首部字段X-Canary则访问v0.1旧版

[root@node1 ~]# curl -H"host: www.ming.org" -H"X-Canary: alway" 192.168.3.10  
kubernetes pod-test v0.1!! ClientIP: 10.244.2.4, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.10!
[root@node1 ~]# 
[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org"  192.168.3.10                     
kubernetes pod-test v0.1!! ClientIP: 10.244.2.4, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.10!

 

#清理环境

kubectl delete -f canary-by-header.yam

范例:基于请求 Header 精确匹配指定值的金丝雀发布

[root@master1 ingress]# cat  canary-by-header-value.yaml     
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    #kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "IsVIP"  #字段名大小写不敏感
    nginx.ingress.kubernetes.io/canary-by-header-value: "true" #IsVIP首部字段的值为true就使用金丝雀发布下面新版本,否则为旧版本,值大小写敏感
  name: pod-test-canary-by-header-value
spec:
  ingressClassName: nginx
  rules:
  - host: www.ming.org
    http:
      paths:
      - backend:
          service:
            name: pod-test-v2
            port: 
              number: 80
        path: /
        pathType: Prefix

 

kubectl apply -f canary-by-header-value.yaml

客户端访问,注意:IsVIP字段名大小写不敏感,true值大小写敏感
#当IsVIP: true,则访问v0.2新版

[root@node1 ~]# curl -H"host: www.ming.org" -H"IsVIP: true" 192.168.3.10                 
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!

 

#当IsVIP: 其它值,则访问v0.1旧版

root@node1 ~]# curl -H"host: www.ming.org" -H"IsVIP: tru" 192.168.3.10   
kubernetes pod-test v0.1!! ClientIP: 10.244.2.4, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.10!
[root@node1 ~]# curl -H"host: www.ming.org" -H"IsVIP: false" 192.168.3.10      
kubernetes pod-test v0.1!! ClientIP: 10.244.2.4, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.10!

 

#清理环境

kubectl delete -f canary-by-header-value.yaml

 

范例:基于请求 Header 正则表达式模式匹配的指定值的金丝雀发布

 

#清单文件

[root@master1 ingress]# cat canary-by-header-pattern.yaml
apiVersion: networking.k8s.io/v1 
kind: Ingress
metadata:
  annotations:
    #kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "Username" #字段名大小不敏感
    nginx.ingress.kubernetes.io/canary-by-header-pattern: "^(vip|VIP)_.*" #首部字段有Username且正则式匹配时使用新版,否则为旧版本
  name: pod-test-canary-by-header-pattern
spec:
  ingressClassName: nginx
  rules:
  - host: www.ming.org
    http:
      paths:
      - backend:
          service:
            name: pod-test-v2
            port:
              number: 80 
        path: /
        pathType: Prefix

 

kubectl apply -f canary-by-header-pattern.yaml

 

客户端访问
#符合正则表达式访问,则访问v0.2新版,字段名Username大小

[root@node1 ~]# curl -H"host: www.ming.org" -H"Username: vip_ss" 192.168.3.10  
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!
[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org" -H"Username: vip_xx" 192.168.3.10    
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!

 

[root@node1 ~]# curl -H"host: www.ming.org" -H"Username: VIP_xx" 192.168.3.10      
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!

 

#不符合正则表达式访问,则访问v0.1旧版

root@node1 ~]# curl -H"host: www.ming.org" -H"Username: Vip_xx" 192.168.3.10   
kubernetes pod-test v0.1!! ClientIP: 10.244.2.4, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.10!
[root@node1 ~]# 
[root@node1 ~]# curl -H"host: www.ming.org" -H"Username: ip_xx" 192.168.3.10   
kubernetes pod-test v0.1!! ClientIP: 10.244.2.4, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.10!

 

#清理环境

kubectl delete -f canary-by-header-pattern.yaml

 

范例:基于cookie和Header 同时存在的金丝雀发布比较优先级

#旧版应用

kubectl apply -f ingress-pod-test.yaml 

 

#同时应用两个ingress的清单文件

kubectl apply -f canary-by-cookie.yaml -f canary-by-header-pattern.yaml

 

[root@master1 ingress]# kubectl get ingress
NAME                                CLASS   HOSTS          ADDRESS        PORTS   AGE
pod-test                            nginx   www.ming.org   192.168.3.10   80      17h
pod-test-canary-by-cookie           nginx   www.ming.org   192.168.3.10   80      32s
pod-test-canary-by-header-pattern   nginx   www.ming.org   192.168.3.10   80      32s

 

#基于cookie访问,优先级低于header,所以不生效,访问旧版本

[root@node1 ~]# curl -H"host: www.ming.org" -b"vip_user=always" 192.168.3.10                     
kubernetes pod-test v0.1!! ClientIP: 10.244.2.4, ServerName: pod-test-v1-65cf4d8c45-d44t9, ServerIP: 10.244.1.10!

 

#基于header访问,优先级高于cookie,所以优先生效

[root@node1 ~]# curl -H"host: www.ming.org" -H"Username: vip_xx" 192.168.3.10  
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!

 

#删除header的ingress

kubectl delete -f canary-by-header-pattern.yaml

#再基于cookie访问,可以访问新版本

[root@node1 ~]# curl -H"host: www.ming.org" -b"vip_user=always" 192.168.3.10   
kubernetes pod-test v0.2!! ClientIP: 10.244.2.4, ServerName: pod-test-v2-54c45485c9-hj56g, ServerIP: 10.244.1.9!

 

 

 

 

posted @ 2026-05-27 17:37  minger_lcm  阅读(32)  评论(0)    收藏  举报