日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

通過Nginx Ingress實現灰度發布和藍綠發布

當對服務進行版本更新升級時,需要使用到滾動升級、分批暫停發布、藍綠發布以及灰度發布等發布方式。本文將介紹在ACK集群中如何通過Nginx Ingress Controller來實現應用服務的灰度發布。

背景信息

灰度及藍綠發布是為新版本創建一個與老版本完全一致的生產環境,在不影響老版本的前提下,按照一定的規則把部分流量切換到新版本,當新版本試運行一段時間沒有問題后,將用戶的全量流量從老版本遷移至新版本。

其中藍綠發布就是一種灰度發布方式,一部分用戶繼續使用老版本的服務,將一部分用戶的流量切換到新版本,如果新版本運行穩定,則逐步將所有用戶遷移到新版本。

容器服務ACK控制臺調整了灰度發布功能的用法,分為兩種。

  • canary-*注解方式:使用canary-* Annotation配置藍綠發布與灰度發布,canary-* Annotation是社區官方實現的灰度發布方式。

  • service-*注解方式:使用service-* Annotation配置藍綠發布與灰度發布。service-* Annotation是ACK Nginx Ingress Controller早期實現灰度發布的方式。service-matchservice-weight功能已不再維護,并即將廢棄。service-* Annotation功能目前仍正常保留,不影響使用。

應用場景

基于客戶端請求的流量切分場景

假設當前線上環境,您已經有一套服務Service A對外提供7層服務,此時上線了一些新的特性,需要發布上線一個新的版本Service A'。但又不想直接替換Service A服務,而是希望將請求頭中包含foo=bar或者Cookie中包含foo=bar的客戶端請求轉發到Service A'服務中。待運行一段時間穩定后,可將所有的流量從Service A切換到Service A'服務中,再平滑地將Service A服務下線。

image

基于服務權重的流量切分場景

假設當前線上環境,您已經有一套服務Service B對外提供7層服務,此時修復了一些問題,需要發布上線一個新的版本Service B'。但又不想將所有客戶端流量切換到新版本Service B'中,而是希望將20%的流量切換到新版本Service B'中。待運行一段時間穩定后,再將所有的流量從Service B切換到Service B'服務中,再平滑地將Service B服務下線。

image

針對以上多種不同的應用發布需求,阿里云容器服務Ingress Controller支持了多種流量切分方式:

  • 基于Request Header的流量切分,適用于灰度發布以及AB測試場景。

  • 基于Cookie的流量切分,適用于灰度發布以及AB測試場景。

  • 基于Query Param的流量切分,適用于灰度發布以及AB測試場景。

  • 基于服務權重的流量切分,適用于藍綠發布場景。

canary-*注解方式

注解說明

Nginx Ingress Controller通過下列canary-* Annotation來支持應用服務的灰度發布機制。

Annotation

說明

適用的ACK Nginx Ingress Controller版本

nginx.ingress.kubernetes.io/canary

  • 必須設置該Annotation值為true,否則其他規則將不會生效。

  • 取值:

    • true:啟用canary功能。

    • false:不啟用canary功能。

≥v0.22.0

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

  • 表示基于請求頭的名稱進行灰度發布。

  • 請求頭名稱的特殊取值:

    • always:無論什么情況下,流量均會進入灰度服務。

    • never:無論什么情況下,流量均不會進入灰度服務。

  • 若沒有指定請求頭名稱的值,則只要該頭存在,都會進行流量轉發。

≥v0.22.0

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

  • 表示基于請求頭的值進行灰度發布。

  • 需要與canary-by-header頭配合使用。

≥v0.30.0

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

  • 表示基于請求頭的值進行灰度發布,并對請求頭的值進行正則匹配。

  • 需要與canary-by-header頭配合使用。

  • 取值為用于匹配請求頭的值的正則表達式。

≥v0.44.0

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

  • 表示基于Cookie進行灰度發布。例如,nginx.ingress.kubernetes.io/canary-by-cookie: foo

  • Cookie內容的取值:

    • always:當foo=always,流量會進入灰度服務。

    • never:當foo=never,流量不會進入灰度服務。

  • 只有當Cookie存在,且值為always時,才會進行流量轉發。

≥v0.22.0

nginx.ingress.kubernetes.io/canary-weight

  • 表示基于權重進行灰度發布。

  • 取值范圍:0~權重總值。

  • 若未設定總值,默認總值為100。

≥v0.22.0

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

  • 表示設定的權重總值。

  • 若未設定總值,默認總值為100。

≥v1.1.2

不同灰度方式的優先級由高到低為:

canary-by-header>canary-by-cookie>canary-weight

說明

目前每個Ingress規則只支持同時指定一個Canary Ingress,大于一個的Canary Ingress將會被忽略。

步驟一:部署服務

部署Nginx服務并通過Nginx Ingress Controller對外提供7層域名訪問。

  1. 創建Deployment和Service。

    1. 創建nginx.yaml

      展開查看YAML文件

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: old-nginx
      spec:
        replicas: 2
        selector:
          matchLabels:
            run: old-nginx
        template:
          metadata:
            labels:
              run: old-nginx
          spec:
            containers:
            - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
              imagePullPolicy: Always
              name: old-nginx
              ports:
              - containerPort: 80
                protocol: TCP
            restartPolicy: Always
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: old-nginx
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 80
        selector:
          run: old-nginx
        sessionAffinity: None
        type: NodePort
    2. 執行以下命令,創建Deployment和Service。

      kubectl apply -f nginx.yaml
  2. 部署Ingress。

    1. 創建ingress.yaml

      1.19版本之前集群

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: gray-release
      spec:
        rules:
        - host: www.example.com
          http:
            paths:
            # 老版本服務。
            - path: /
              backend:
                serviceName: old-nginx
                servicePort: 80

      1.19及之后版本集群

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: gray-release
      spec:
        rules:
        - host: www.example.com
          http:
            paths:
            # 老版本服務。
            - path: /
              backend:
                service: 
                  name: old-nginx
                  port:
                    number: 80
              pathType: ImplementationSpecific
    2. 執行以下命令,部署Ingress。

      kubectl apply -f ingress.yaml
  3. 測試訪問情況。

    1. 執行以下命令,獲取外部IP。

      kubectl get ingress
    2. 執行以下命令,查看路由訪問情況。

      curl -H "Host: www.example.com"  http://<EXTERNAL_IP>

      預期輸出:

      old

步驟二:灰度發布新版本服務

發布一個新版本的Nginx服務并配置路由規則。

  1. 部署新版本的Deployment和Service。

    1. 創建nginx1.yaml

      展開查看YAML文件

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: new-nginx
      spec:
        replicas: 1
        selector:
          matchLabels:
            run: new-nginx
        template:
          metadata:
            labels:
              run: new-nginx
          spec:
            containers:
            - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
              imagePullPolicy: Always
              name: new-nginx
              ports:
              - containerPort: 80
                protocol: TCP
            restartPolicy: Always
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: new-nginx
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 80
        selector:
          run: new-nginx
        sessionAffinity: None
        type: NodePort
    2. 執行以下命令,部署新版本的Deployment和Service。

      kubectl apply -f nginx1.yaml
  2. 設置訪問新版本服務的路由規則。

    ACK支持設置以下三種路由規則,您可以根據實際情況選擇路由規則。

    • 設置滿足特定規則的客戶端才能訪問新版本服務。以下示例僅請求頭中滿足foo=bar的客戶端請求才能路由到新版本服務。

      1. 按照以上條件,在ingress1.yaml文件中創建新的Ingress資源gray-release-canary

        1.19版本之前集群

        apiVersion: networking.k8s.io/v1beta1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # 開啟Canary。
            nginx.ingress.kubernetes.io/canary: "true"
            # 請求頭為foo。
            nginx.ingress.kubernetes.io/canary-by-header: "foo"
            # 請求頭foo的值為bar時,請求才會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 新版本服務。
              - path: /
                backend:
                  serviceName: new-nginx
                  servicePort: 80

        1.19及之后版本集群

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # 開啟Canary。
            nginx.ingress.kubernetes.io/canary: "true"
            # 請求頭為foo。
            nginx.ingress.kubernetes.io/canary-by-header: "foo"
            # 請求頭foo的值為bar時,請求才會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
            
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 新版本服務。
              - path: /
                backend:
                  service: 
                    name: new-nginx
                    port:
                      number: 80
                pathType: ImplementationSpecific
      2. 執行以下命令,部署Ingress1。

        kubectl apply -f ingress1.yaml
      3. 執行以下命令,獲取外部IP。

        kubectl get ingress
      4. 查看路由訪問情況。

        1. 執行以下命令,訪問服務。

          curl -H "Host: www.example.com"  http://<EXTERNAL_IP>

          預期輸出:

          old
        2. 執行以下命令,請求頭中滿足foo=bar的客戶端請求訪問服務。

          curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>

          預期輸出:

          new

        重復執行以上命令,可以看到,僅請求頭中滿足foo=bar的客戶端請求才能路由到新版本服務。

    • 在特定規則未被滿足時,再按照一定比例將請求路由到新版本服務中。以下示例要求請求頭中滿足foo=bar的客戶端請求,若不包含該請求頭,會將50%的流量路由到新版本服務中。

      1. 按照以下內容,修改步驟2中創建的Ingress。

        1.19版本之前集群

        apiVersion: networking.k8s.io/v1beta1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # 開啟Canary。
            nginx.ingress.kubernetes.io/canary: "true"
            # 請求頭為foo。
            nginx.ingress.kubernetes.io/canary-by-header: "foo"
            # 請求頭foo的值為bar時,請求才會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
            # 在未滿足上述匹配規則的基礎上僅允許50%的流量會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/canary-weight: "50"
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 新版本服務。
              - path: /
                backend:
                  serviceName: new-nginx
                  servicePort: 80

        1.19及之后版本集群

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # 開啟Canary。
            nginx.ingress.kubernetes.io/canary: "true"
            # 請求頭為foo。
            nginx.ingress.kubernetes.io/canary-by-header: "foo"
            # 請求頭foo的值為bar時,請求才會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
            # 在未滿足上述匹配規則的基礎上僅允許50%的流量會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/canary-weight: "50"
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 新版本服務。
              - path: /
                backend:
                  service: 
                    name: new-nginx
                    port:
                      number: 80
                pathType: ImplementationSpecific
      2. 執行以下命令,部署Ingress。

        kubectl apply -f ingress.yaml
      3. 執行以下命令,獲取外部IP。

        kubectl get ingress
      4. 查看路由訪問情況。

        1. 執行以下命令,訪問服務。

          curl -H "Host: www.example.com"  http://<EXTERNAL_IP>

          預期輸出:

          old

        2. 執行以下命令,請求頭中滿足foo=bar的客戶端請求訪問服務。

          curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>

          預期輸出:

          new
        • foo=bar請求頭:

          請求流量100%會路由到新版本new-nginx服務中,由canary-by-headercanary-by-header-value控制。

        • 沒有foo=bar請求頭:

          請求流量50%會路由到新版本new-nginx服務中,由canary-weight控制。

    • 設置一定比例的請求被路由到新版本服務中,以下示例中僅50%的流量被路由到新版本服務中。

      1. 按照以下內容,修改步驟2創建的Ingress。

        1.19版本之前集群

        apiVersion: networking.k8s.io/v1beta1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # 開啟Canary。
            nginx.ingress.kubernetes.io/canary: "true"
            # 僅允許50%的流量會被路由到新版本服務new-nginx中。
            # 默認總值為100。
            nginx.ingress.kubernetes.io/canary-weight: "50"
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 新版本服務。
              - path: /
                backend:
                  serviceName: new-nginx
                  servicePort: 80

        1.19及之后版本集群

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # 開啟Canary。
            nginx.ingress.kubernetes.io/canary: "true"
            # 僅允許50%的流量會被路由到新版本服務new-nginx中。
            # 默認總值為100。
            nginx.ingress.kubernetes.io/canary-weight: "50"
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 新版本服務。
              - path: /
                backend:
                  service: 
                    name: new-nginx
                    port:
                      number: 80
                pathType: ImplementationSpecific
      2. 執行以下命令,部署Ingress。

        kubectl apply -f ingress.yaml

      3. 執行以下命令,獲取外部IP。

        kubectl get ingress

      4. 執行以下命令,查看路由訪問情況。

        curl -H "Host: www.example.com" http://<EXTERNAL_IP>

      重復執行以上命令,可以看到僅50%的流量路由到新版本服務。

步驟三:刪除老版本服務

系統運行一段時間后,當新版本服務已經穩定并且符合預期后,需要下線老版本的服務 ,僅保留新版本服務在線上運行。為了達到該目標,需要將舊版本的Service指向新版本服務的Deployment,并且刪除舊版本的Deployment和新版本的Service。

  1. 修改舊版本Service文件nginx.yaml,使其指向新版本服務。

    展開查看YAML文件

    apiVersion: v1
    kind: Service
    metadata:
      name: old-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        # 指向新版本服務。
        run: new-nginx
      sessionAffinity: None
      type: NodePort
  2. 執行以下命令,部署舊版本服務。

    kubectl apply -f nginx.yaml
  3. 執行以下命令,獲取外部IP。

    kubectl get ingress
  4. 執行以下命令,查看路由訪問情況。

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    預期輸出:

    new

    重復執行以上命令,可以看到請求全部被路由到了新版本的服務。

  5. 執行以下命令,刪除Canary Ingress資源gray-release-canary

    kubectl delete ingress gray-release-canary
  6. 刪除舊版本的Deployment和新版本的Service。

    1. 執行以下命令,刪除舊版本的Deployment。

      kubectl delete deploy old-nginx
    2. 執行以下命令,刪除新版本的Service。

      kubectl delete svc new-nginx

service-*注解方式

注解說明

Nginx Ingress Controller通過下列Annotation來支持應用服務的灰度發布機制。

  • nginx.ingress.kubernetes.io/service-match

    該注解用來配置新版本服務的路由匹配規則。

    nginx.ingress.kubernetes.io/service-match: | 
        <service-name>: <match-rule>
    # 參數說明:
    # service-name:服務名稱,滿足match-rule的請求會被路由到該服務中。
    # match-rule:路由匹配規則
    #
    # 路由匹配規則:
    # 1. 支持的匹配類型
    # - header:基于請求頭,支持正則匹配和完整匹配。
    # - cookie:基于cookie,支持正則匹配和完整匹配。
    # - query:基于請求參數,支持正則匹配和完整匹配。
    #
    # 2. 匹配方式
    # - 正則匹配格式:/{regular expression}/,使用反斜杠(//)表明采用正則方式匹配。
    # - 完整匹配格式:"{exact expression}",使用引號("")表明采用完整方式匹配。

    路由匹配規則配置示例:

    # 請求頭中滿足foo正則匹配^bar$的請求被轉發到新版本服務new-nginx中。
    new-nginx: header("foo", /^bar$/)
    # 請求頭中滿足foo完整匹配bar的請求被轉發到新版本服務new-nginx中。
    new-nginx: header("foo", "bar")
    # cookie中滿足foo正則匹配^sticky-.+$的請求被轉發到新版本服務new-nginx中。
    new-nginx: cookie("foo", /^sticky-.+$/)
    # query param中滿足foo完整匹配bar的請求被轉發到新版本服務new-nginx中。
    new-nginx: query("foo", "bar")
  • nginx.ingress.kubernetes.io/service-weight

    該注解用來配置新舊版本服務的流量權重。

    nginx.ingress.kubernetes.io/service-weight: | 
        <new-svc-name>:<new-svc-weight>, <old-svc-name>:<old-svc-weight>
    參數說明:
    new-svc-name:新版本服務名稱
    new-svc-weight:新版本服務權重
    old-svc-name:舊版本服務名稱
    old-svc-weight:舊版本服務權重

    服務權重配置示例:

    nginx.ingress.kubernetes.io/service-weight: | 
        new-nginx: 20, old-nginx: 60

步驟一:部署服務

部署Nginx服務并通過Nginx Ingress Controller對外提供7層域名訪問。

  1. 創建Deployment和Service。

    1. 創建nginx.yaml

      展開查看YAML文件

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: old-nginx
      spec:
        replicas: 2
        selector:
          matchLabels:
            run: old-nginx
        template:
          metadata:
            labels:
              run: old-nginx
          spec:
            containers:
            - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
              imagePullPolicy: Always
              name: old-nginx
              ports:
              - containerPort: 80
                protocol: TCP
            restartPolicy: Always
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: old-nginx
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 80
        selector:
          run: old-nginx
        sessionAffinity: None
        type: NodePort
    2. 執行以下命令,創建Deployment和Service。

      kubectl apply -f nginx.yaml
  2. 部署Ingress。

    1. 創建ingress.yaml

      1.19版本之前集群

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: gray-release
      spec:
        rules:
        - host: www.example.com
          http:
            paths:
            # 老版本服務。
            - path: /
              backend:
                serviceName: old-nginx
                servicePort: 80

      1.19及之后版本集群

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: gray-release
      spec:
        rules:
        - host: www.example.com
          http:
            paths:
            # 老版本服務。
            - path: /
              backend:
                service: 
                  name: old-nginx
                  port:
                    number: 80
              pathType: ImplementationSpecific
    2. 執行以下命令,部署Ingress。

      kubectl apply -f ingress.yaml
  3. 測試訪問情況。

    1. 執行以下命令,獲取外部IP。

      kubectl get ingress
    2. 執行以下命令,查看路由訪問情況。

      curl -H "Host: www.example.com"  http://<EXTERNAL_IP>

      預期輸出:

      old

步驟二:灰度發布新版本服務

發布一個新版本的Nginx服務并配置路由規則。

  1. 部署新版本的Deployment和Service。

    1. 創建nginx1.yaml

      展開查看YAML文件

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: new-nginx
      spec:
        replicas: 1
        selector:
          matchLabels:
            run: new-nginx
        template:
          metadata:
            labels:
              run: new-nginx
          spec:
            containers:
            - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
              imagePullPolicy: Always
              name: new-nginx
              ports:
              - containerPort: 80
                protocol: TCP
            restartPolicy: Always
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: new-nginx
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 80
        selector:
          run: new-nginx
        sessionAffinity: None
        type: NodePort
    2. 部署新版本的Deployment和Service。

      kubectl apply -f nginx1.yaml
  2. 設置訪問新版本服務的路由規則。

    ACK支持設置以下三種路由規則,您可以根據實際情況選擇路由規則。

    • 設置滿足特定規則的客戶端才能訪問新版本服務。以下示例僅請求頭中滿足foo=bar的客戶端請求才能路由到新版本服務。

      1. 按照以下內容,修改步驟2創建的Ingress。

      1.19版本之前集群

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: gray-release
        annotations:
          # 請求頭中滿足正則匹配foo=bar的請求才會被路由到新版本服務new-nginx中。
          nginx.ingress.kubernetes.io/service-match: | 
            new-nginx: header("foo", /^bar$/)
      spec:
        rules:
        - host: www.example.com
          http:
            paths:
            # 老版本服務。
            - path: /
              backend:
                serviceName: old-nginx
                servicePort: 80
            # 新版本服務。
            - path: /
              backend:
                serviceName: new-nginx
                servicePort: 80

      1.19及之后版本集群

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: gray-release
        annotations:
          # 請求頭中滿足正則匹配foo=bar的請求才會被路由到新版本服務new-nginx中。
          nginx.ingress.kubernetes.io/service-match: | 
            new-nginx: header("foo", /^bar$/)
      spec:
        rules:
        - host: www.example.com
          http:
            paths:
            # 老版本服務。
            - path: /
              backend:
                service: 
                  name: old-nginx
                  port:
                    number: 80
              pathType: ImplementationSpecific
            # 新版本服務。
            - path: /
              backend:
                service: 
                  name: new-nginx
                  port:
                    number: 80
              pathType: ImplementationSpecific
      1. 執行以下命令,部署Ingress。

        kubectl apply -f ingress.yaml
      2. 執行以下命令,獲取外部IP。

        kubectl get ingress
      3. 查看路由訪問情況。

        1. 執行以下命令,訪問服務。

          curl -H "Host: www.example.com"  http://<EXTERNAL_IP>

          預期輸出:

          old

        2. 執行以下命令,請求頭中滿足foo=bar的客戶端請求訪問服務。

          curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>

          預期輸出:

          new

      重復執行以上命令,可以看到,僅請求頭中滿足foo=bar的客戶端請求才能路由到新版本服務。

    • 在滿足特定規則的基礎上設置一定比例的請求被路由到新版本服務中。以下示例要求請求頭中滿足foo=bar的客戶端請求,且僅允許其中50%的流量被路由到新版本服務中。

      1. 按照以下內容,修改步驟2創建的Ingress。

        1.19版本之前集群

        apiVersion: networking.k8s.io/v1beta1
        kind: Ingress
        metadata:
          name: gray-release
          annotations:
            # 請求頭中滿足正則匹配foo=bar的請求才會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/service-match: |
                new-nginx: header("foo", /^bar$/)
            # 在滿足上述匹配規則的基礎上僅允許50%的流量會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/service-weight: |
                new-nginx: 50, old-nginx: 50
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 老版本服務。
              - path: /
                backend:
                  serviceName: old-nginx
                  servicePort: 80
              # 新版本服務。
              - path: /
                backend:
                  serviceName: new-nginx
                  servicePort: 80
         servicePort: 80

        1.19及之后版本集群

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release
          annotations:
            # 請求頭中滿足正則匹配foo=bar的請求才會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/service-match: |
                new-nginx: header("foo", /^bar$/)
            # 在滿足上述匹配規則的基礎上僅允許50%的流量會被路由到新版本服務new-nginx中。
            nginx.ingress.kubernetes.io/service-weight: |
                new-nginx: 50, old-nginx: 50
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 老版本服務。
              - path: /
                backend:
                  service: 
                    name: old-nginx
                    port:
                      number: 80
                pathType: ImplementationSpecific
              # 新版本服務。
              - path: /
                backend:
                  service: 
                    name: new-nginx
                    port:
                      number: 80
                pathType: ImplementationSpecific
      2. 執行以下命令,部署Ingress。

        kubectl apply -f ingress.yaml
      3. 執行以下命令,獲取外部IP。

        kubectl get ingress

      4. 查看路由訪問情況。

        1. 執行以下命令,訪問服務。

          curl -H "Host: www.example.com"  http://<EXTERNAL_IP>

          預期輸出:

          old

        2. 執行以下命令,請求頭中滿足foo=bar的客戶端請求訪問服務。

          curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>

          預期輸出:

          new

        重復執行以上命令。可以看到,僅請求頭中滿足foo=bar的客戶端請求,且只有50%的流量才能路由到新版本服務。

    • 設置一定比例的請求被路由到新版本服務中,以下示例中僅50%的流量被路由到新版本服務中。

      1. 按照以下內容,修改步驟2創建的Ingress。

        1.19版本之前集群

        apiVersion: networking.k8s.io/v1beta1
        kind: Ingress
        metadata:
          name: gray-release
          annotations:
              # 允許50%的流量被路由到新版本服務new-nginx中。
              nginx.ingress.kubernetes.io/service-weight: |
                  new-nginx: 50, old-nginx: 50
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 老版本服務。
              - path: /
                backend:
                  serviceName: old-nginx
                  servicePort: 80
              # 新版本服務。
              - path: /
                backend:
                  serviceName: new-nginx
                  servicePort: 80

        1.19及之后版本集群

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release
          annotations:
              # 允許50%的流量被路由到新版本服務new-nginx中。
              nginx.ingress.kubernetes.io/service-weight: |
                  new-nginx: 50, old-nginx: 50
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # 老版本服務。
              - path: /
                backend:
                  service: 
                    name: old-nginx
                    port:
                      number: 80
                pathType: ImplementationSpecific
              # 新版本服務。
              - path: /
                backend:
                  service: 
                    name: new-nginx
                    port:
                      number: 80
                pathType: ImplementationSpecific
      2. 執行以下命令,部署Ingress。

        kubectl apply -f ingress.yaml
      3. 執行以下命令,獲取外部IP。

        kubectl get ingress

      4. 執行以下命令,查看路由訪問情況。

        curl -H "Host: www.example.com" http://<EXTERNAL_IP>

        重復執行以上命令,可以看到僅50%的流量路由到新版本服務。

步驟三:刪除老版本服務

系統運行一段時間后,當新版本服務已經穩定并且符合預期后,需要下線老版本的服務 ,僅保留新版本服務在線上運行。

  1. 按照以下內容,修改步驟2創建的Ingress。

    1.19版本之前集群

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          # 新版本服務。
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    1.19及之后版本集群

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          # 新版本服務。
          - path: /
            backend:
              service: 
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
  2. 執行以下命令,部署Ingress。

    kubectl apply -f ingress.yaml
  3. 執行以下命令,獲取外部IP。

    kubectl get ingress

  4. 執行以下命令,查看路由訪問情況。

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    預期輸出:

    new

    重復執行以上命令,可以看到請求全部被路由到了新版本的服務。

  5. 刪除舊版本的Deployment和Service。

    1. 執行以下命令,刪除舊版本的Deployment。

      kubectl delete deploy <Deployment名稱>
    2. 執行以下命令,刪除舊版本的Service。

      kubectl delete svc <Service名稱>