K8S Nginx Ingress实现金丝雀发布

通过给 Ingress 资源指定 Nginx Ingress 所支持的 annotation 可实现金丝雀发布。

需给服务创建2个 Ingress,其中1个常规 Ingress,另1个为带 nginx.ingress.kubernetes.io/canary: "true" 固定的 annotation 的 Ingress,称为 Canary Ingress。

Canary Ingress 一般代表新版本的服务,结合另外针对流量切分策略的 annotation 一起配置即可实现多种场景的金丝雀发布。

以下为相关 annotation 的详细介绍:

  • nginx.ingress.kubernetes.io/canary-by-header
    表示如果请求头中包含指定的 header 名称,并且值为 always,就将该请求转发给该 Ingress 定义的对应后端服务。如果值为 never 则不转发,可以用于回滚到旧版。如果为其他值则忽略该 annotation。

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

    该 annotation 可以作为 canary-by-header 的补充,可指定请求头为自定义值,包含但不限于 alwaysnever。当请求头的值命中指定的自定义值时,请求将会转发给该 Ingress 定义的对应后端服务,如果是其它值则忽略该 annotation。

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

    canary-by-header-value 类似,区别为该 annotation 用正则表达式匹配请求头的值,而不是只固定某一个值。如果该 annotation 与 canary-by-header-value 同时存在,该 annotation 将被忽略。

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

    canary-by-header 类似,该 annotation 用于 cookie,仅支持 alwaysnever

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

    表示 Canary Ingress 所分配流量的比例的百分比,取值范围 [0-100]。例如,设置为10,则表示分配10%的流量给 Canary Ingress 对应的后端服务。

一、部署蓝环境版本服务

1、ConfigMap

bash 复制代码
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-blue-config
data:
  nginx.conf: |-
    worker_processes  1;

    events {
        accept_mutex on;
        multi_accept on;
        use epoll;
        worker_connections  1024;
    }

    http {
        ignore_invalid_headers off;
        server {
            listen 80;
            location / {
                access_by_lua '
                    local header_str = ngx.say("blue")
                ';
            }
        }
    }

2、Deployment

bash 复制代码
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx-blue
  labels:
    dce.daocloud.io/app: nginx-blue
  annotations:
    dce.daocloud.io/last-replicas: '1'
    deployment.kubernetes.io/revision: '3'
    kubernetes.io/change-cause: update YAML
spec:
  replicas: 1
  selector:
    matchLabels:
      dce.daocloud.io/component: nginx-blue
  template:
    metadata:
      name: nginx-blue
      labels:
        dce.daocloud.io/app: nginx-blue
        dce.daocloud.io/component: nginx-blue
      annotations:
        dce.daocloud.io/parcel.egress.burst: '0'
        dce.daocloud.io/parcel.egress.rate: '0'
        dce.daocloud.io/parcel.ingress.burst: '0'
        dce.daocloud.io/parcel.ingress.rate: '0'
        dce.daocloud.io/parcel.net.type: calico
    spec:
      volumes:
        - name: nginx-blue-config
          configMap:
            name: nginx-blue-config
            defaultMode: 420
      containers:
        - name: nginx-blue
          image: 'x.x.x.x/library/openresty:1.19.9.1-sw-r4'
          resources:
            limits:
              cpu: 500m
              memory: '314572800'
            requests:
              cpu: 200m
              memory: '314572800'
          volumeMounts:
            - name: nginx-blue-config
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf

3、Service

bash 复制代码
kind: Service
apiVersion: v1
metadata:
  name: nginx-blue-default
  labels:
    dce.daocloud.io/app: nginx-blue
  annotations:
    io.daocloud.dce.serviceSelectorType: service
spec:
  ports:
    - name: nginx-nginx-default-80680-80
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 31046
  selector:
    dce.daocloud.io/component: nginx-blue
  clusterIP: 172.31.69.137
  type: NodePort
  sessionAffinity: None
  externalTrafficPolicy: Cluster

4、修改pod内容

bash 复制代码
cd /usr/local/openresty/nginx/html/

ls
50x.html  index.html

echo "Hello Blue" > index.html

cat index.html 
Hello Blue

二、部署绿环境版本服务

1、ConfigMap

bash 复制代码
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-green-config
data:
  nginx.conf: |-
    worker_processes  1;

    events {
        accept_mutex on;
        multi_accept on;
        use epoll;
        worker_connections  1024;
    }

    http {
        ignore_invalid_headers off;
        server {
            listen 80;
            location / {
                access_by_lua '
                    local header_str = ngx.say("green")
                ';
            }
        }
    }

2、Deployment

bash 复制代码
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx-green
  labels:
    dce.daocloud.io/app: nginx-green
  annotations:
    deployment.kubernetes.io/revision: '5'
    kubernetes.io/change-cause: update YAML
spec:
  replicas: 1
  selector:
    matchLabels:
      dce.daocloud.io/component: nginx-green
  template:
    metadata:
      name: nginx-green
      labels:
        dce.daocloud.io/app: nginx-green
        dce.daocloud.io/component: nginx-green
        env: green
      annotations:
        dce.daocloud.io/parcel.egress.burst: '0'
        dce.daocloud.io/parcel.egress.rate: '0'
        dce.daocloud.io/parcel.ingress.burst: '0'
        dce.daocloud.io/parcel.ingress.rate: '0'
        dce.daocloud.io/parcel.net.type: calico
        dce.daocloud.io/parcel.net.value: default-ipv4-ippool
    spec:
      volumes:
        - name: nginx-green-config
          configMap:
            name: nginx-green-config
            defaultMode: 420
      containers:
        - name: nginx-green
          image: 'x.x.x.x/library/openresty:1.19.9.1-sw-r4'
          resources:
            limits:
              cpu: 500m
              memory: '314572800'
            requests:
              cpu: 200m
              memory: '314572800'
          volumeMounts:
            - name: nginx-green-config
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf

3、Service

bash 复制代码
kind: Service
apiVersion: v1
metadata:
  name: nginx-green-default
  labels:
    dce.daocloud.io/app: nginx-green
  annotations:
    io.daocloud.dce.serviceSelectorType: service
spec:
  ports:
    - name: nginx-nginx-default-15833-80
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 35218
  selector:
    dce.daocloud.io/component: nginx-green
  clusterIP: 172.31.207.22
  type: NodePort
  sessionAffinity: None
  externalTrafficPolicy: Cluster

4、修改pod内容

bash 复制代码
cd /usr/local/openresty/nginx/html/

ls
50x.html  index.html

echo "Hello Green" > index.html

cat index.html 
Hello Green

三、设置Ingress

1、blue环境Ingress

bash 复制代码
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: nginx-blue-ingress
  labels:
    dce.daocloud.io/app: nginx-blue
  annotations:
    nginx.ingress.kubernetes.io/use-port-in-redirects: 'true'
spec:
  rules:
    - host: nginx.ms-sit.xxxxxx.net
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              serviceName: nginx-blue-default
              servicePort: 80

2、green环境Ingress

bash 复制代码
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: nginx-green-ingress
  labels:
    dce.daocloud.io/app: nginx-green
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: 'true'
    nginx.ingress.kubernetes.io/canary-by-header: env
    nginx.ingress.kubernetes.io/canary-by-header-pattern: green
spec:
  rules:
    - host: nginx.ms-sit.xxxxxx.net
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              serviceName: nginx-green-default
              servicePort: 80

四、测试

相关推荐
蝎子莱莱爱打怪3 天前
Centos7中一键安装K8s集群以及Rancher安装记录
运维·后端·kubernetes
何中应3 天前
Nginx转发请求错误
前端·后端·nginx
芝士雪豹只抽瑞克五4 天前
Nginx 高性能Web服务器笔记
服务器·nginx
阿里云云原生4 天前
Kubernetes 官方再出公告,强调立即迁移 Ingress NGINX
kubernetes
失重外太空啦4 天前
nginx
运维·nginx
至此流年莫相忘4 天前
Kubernetes实战篇之配置与存储
云原生·容器·kubernetes
天蓝不会忘记024 天前
lvs,haproxy,keepalived,nginx,tomcat介绍和实验
nginx·tomcat·lvs
feng68_4 天前
Nginx高性能Web服务器
linux·运维·服务器·nginx
unfeeling_4 天前
Nginx实验
运维·nginx