全部產品
Search
文件中心

Server Load Balancer:自建Nginx Ingress遷移ALB Ingress最佳實務

更新時間:Dec 07, 2024

相較於Nginx Ingress,ALB Ingress屬於全託管服務,免去了營運成本,並提供了更強大的彈性。從Nginx Ingress遷移至ALB Ingress時,ACK提供的遷移工具可自動將Nginx Ingress配置轉換為ALB Ingress的配置,免去了您手動轉換配置的過程。本文提供了一個遷移樣本:在將Nginx Ingress的配置轉換到ALB Ingress後,通過使用DNS解析,將流量逐漸轉移至ALB Ingress,完成對用戶端無感的遷移。

遷移流程

通過將一個網域名稱同時解析到Nginx Ingress和ALB Ingress並逐漸調整權重,可以實現對用戶端無感的遷移。下圖展示了通過DNS解析完成無感遷移的大致流程,各個步驟在下方的遷移樣本情境有更具體的樣本展示。

說明

通過DNS解析遷移並非是無感遷移的唯一方式,本文中的樣本僅供您參考。

遷移樣本情境

通過以下樣本,您可瞭解遷移流程中的具體操作細節和工作原理。

某企業在ACK叢集中安裝了Nginx Ingress Controller,並為Controller的Service選擇了公網LoadBalancer類型,使Controller自動關聯了一個公網類型CLB執行個體。該企業同時配置了DNS解析,用戶端訪問www.example.net時,用戶端請求將被解析到CLB,並經由CLB轉寄後到達後端Pod。

步驟一:配置ALB Ingress

隨著業務逐步上量,Nginx Ingress的效能已無法滿足業務需求,並且產生了較為高昂的營運成本。該企業決定從Nginx Ingress遷移至ALB Ingress。遷移過程中,該企業通過ACK提供的遷移工具將Nginx Ingress的配置轉換到了ALB Ingress中,並將ALB Ingress加入到了DNS解析中,給予了更低的權重。

重要

DNS協議不允許同一網域名稱被同時解析到A記錄與CNAME記錄。CLB執行個體通過IP接收請求,而ALB執行個體對外提供預設網域名稱(詳見什麼是應用型負載平衡ALB)。因此需要為CLB配置一個臨時網域名稱,以達到將客戶請求按權重同時分配到Nginx Ingress與ALB Ingress的效果。

步驟二:將流量逐漸轉移至ALB Ingress

經過一段時間的測試後,ALB Ingress工作正常,該企業隨即提高了ALB Ingress的DNS解析權重,使更多流量經由ALB Ingress轉寄。

步驟三:刪除Nginx Ingress相關資源

在將流量完全轉移至ALB Ingress後,該企業刪除了DNS解析中的Nginx Ingress相關條目,移除了Nginx Ingress相關資源,並卸載了Nginx Ingress Controller組件。至此,該企業已經完成了從Nginx Ingress遷移至ALB Ingress的過程,且全流程對用戶端無感。

前提條件

已通過kubectl工具串連叢集。具體操作,請參見擷取叢集KubeConfig並通過kubectl工具串連叢集

步驟一:配置ALB Ingress

  1. 登入Container Service管理主控台,在需要執行遷移的叢集中,安裝ALB Ingress Controller組件。具體操作,請參見管理ALB Ingress Controller組件。遷移工具會自動轉換AlbConfigIngressClassIngress資源,因此在安裝組件時請為ALB雲原生網關執行個體來源選擇暫不建立

    重要

    如需在ACK專有叢集中通過ALB Ingress訪問服務,在部署服務前需要為ALB Ingress Controller授權。具體操作,請參見為ACK專有叢集授予ALB Ingress Controller存取權限

  2. 建立並複製下方YAML檔案至ingress2albconfig.yaml中。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: ingress2albconfig
      namespace: default
    spec:
      template:
        spec:
          containers:
          - name: ingress2albconfig
            image: registry.cn-hangzhou.aliyuncs.com/acs/ingress2albconfig:latest
            command: ["/bin/ingress2albconfig", "print"]
          restartPolicy: Never
          serviceAccount: ingress2albconfig
          serviceAccountName: ingress2albconfig
      backoffLimit: 4
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: system:ingress2albconfig
    rules:
    - apiGroups:
      - networking.k8s.io
      resources:
      - ingresses
      - ingressclasses
      verbs:
      - get
      - list
      - watch
      - update
      - create
      - patch
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ingress2albconfig
      namespace: default
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: system:ingress2albconfig
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:ingress2albconfig
    subjects:
      - kind: ServiceAccount
        name: ingress2albconfig
        namespace: default
  3. 執行以下命令,運行Job任務。該任務將會依據現有的Nginx Ingress Controller配置,自動轉化到AlbConfigIngressClassIngress等資源並輸出,後續可通過Log查看。

    kubectl apply -f ingress2albconfig.yaml

    預期輸出:

    job.batch/ingress2albconfig created
    clusterrole.rbac.authorization.k8s.io/system:ingress2albconfig created
    serviceaccount/ingress2albconfig created
    clusterrolebinding.rbac.authorization.k8s.io/system:ingress2albconfig created
  4. 查看Job所屬的Pod。

    kubectl get pod -l job-name=ingress2albconfig

    預期輸出:

    NAME                READY   STATUS      RESTARTS   AGE
    ingress2albconfig-vw***   0/1     Completed   0          16m
  5. 查看Pod日誌。

    kubectl logs ingress2albconfig-vw*** # 替換為上一步中得到的Pod名稱

    預期輸出如下,通過kubectl將下列資源部署到叢集中後,就完成了ALB Ingress的配置。

    apiVersion: alibabacloud.com/v1
    kind: AlbConfig
    metadata:
      creationTimestamp: null
      name: from_nginx
    spec:
      config:
        accessLogConfig: {}
        edition: Standard
        name: from_nginx
        tags:
        - key: converted/ingress2albconfig
          value: "true"
        zoneMappings:
        - vSwitchId: vsw-xxx #替換為VPC中的虛擬交換器ID
        - vSwitchId: vsw-xxx #替換為VPC中的虛擬交換器ID
      listeners:
      - port: 80
        protocol: HTTP
    ---
    apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
      creationTimestamp: null
      name: from_nginx
    spec:
      controller: ingress.k8s.alibabacloud/alb
      parameters:
        apiGroup: alibabacloud.com
        kind: AlbConfig
        name: from_nginx
        scope: null
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}]'
      creationTimestamp: null
      name: from_ingress1
      namespace: default
    spec:
      ingressClassName: from_nginx
      rules:
      - http:
          paths:
          - backend:
              service:
                name: nginx-svc-g1msr
                port:
                  number: 80
            path: /
            pathType: Prefix
    status:
      loadBalancer: {}

自動轉換的Annotation列表

遷移工具會將下表中的Nginx Ingress Annotation自動轉換為ALB Ingress中的Annotation。

重要

不在下表中的Nginx Ingress Annotation在轉換過程中會被忽略,請您在轉換完成後確認ALB Ingress的配置,以避免功能與預期不符。

Annotation列表

Nginx Ingress Annotation

ALB Ingress Annotation

nginx.ingress.kubernetes.io/canary

alb.ingress.kubernetes.io/canary

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

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

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

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

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

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

nginx.ingress.kubernetes.io/canary-weight

alb.ingress.kubernetes.io/canary-weight

nginx.ingress.kubernetes.io/use-regex

alb.ingress.kubernetes.io/use-regex

nginx.ingress.kubernetes.io/rewrite-target

alb.ingress.kubernetes.io/rewrite-target

nginx.ingress.kubernetes.io/ssl-redirect

alb.ingress.kubernetes.io/ssl-redirect

nginx.ingress.kubernetes.io/enable-cors

alb.ingress.kubernetes.io/enable-cors

nginx.ingress.kubernetes.io/cors-allow-origin

alb.ingress.kubernetes.io/cors-allow-origin

nginx.ingress.kubernetes.io/cors-allow-methods

alb.ingress.kubernetes.io/cors-allow-methods

nginx.ingress.kubernetes.io/cors-allow-headers

alb.ingress.kubernetes.io/cors-allow-headers

nginx.ingress.kubernetes.io/cors-expose-headers

alb.ingress.kubernetes.io/cors-expose-headers

nginx.ingress.kubernetes.io/cors-allow-credentials

alb.ingress.kubernetes.io/cors-allow-credentials

nginx.ingress.kubernetes.io/backend-protocol

alb.ingress.kubernetes.io/backend-protocol

nginx.ingress.kubernetes.io/load-balance

alb.ingress.kubernetes.io/backend-scheduler

nginx.ingress.kubernetes.io/upstream-hash-by

alb.ingress.kubernetes.io/backend-scheduler-uch-value

步驟二:將流量逐漸轉移至ALB Ingress

警告
  • 流量切換前,請比對您的Nginx Ingress和ALB Ingress的轉寄策略,並進行測試以確保二者的功能完全一致,以免在切換過程中對您的業務產生非預期的影響。

  • 建議在業務低穀期進行流量的切換。

為CLB執行個體配置臨時網域名稱

因為DNS協議並不支援將一個網域名稱同時解析到A記錄與CNAME記錄,且ALB執行個體對外提供預設網域名稱,因此您需要為CLB配置臨時網域名稱。

  1. 登入網域名稱解析控制台

  2. 網域名稱解析頁面,找到指向待遷移CLB執行個體的DNS網域名稱www.example.net,單擊該網域名稱。

  3. 解析設定頁面,單擊添加記錄,在添加記錄面板,完成以下參數的配置,然後單擊確認

    配置

    說明

    記錄類型

    在下拉式清單中選擇CNAME

    主機記錄

    網域名稱的首碼,在本樣本中輸入www

    解析請求來源

    選擇預設。

    記錄值

    輸入臨時網域名稱,在本樣本中輸入web0.example.net

    TTL

    全稱Time To Live,表示DNS記錄在DNS伺服器上的緩衝時間,保持預設。

  4. 解析設定頁面,找到由www.example.net指向CLB執行個體IP的A記錄,在操作列單擊修改

  5. 在彈出的修改記錄面板,修改主機記錄,然後單擊確認。本文修改主機記錄為web0,其餘參數保持不變。

    說明

    完成配置後,www.example.net將被CNAME條目解析到web0.example.net,而web0.example.net將被A條目解析到CLB執行個體的IP地址。

為ALB執行個體添加CNAME解析

  1. 執行以下命令,找到ALB執行個體的網域名稱。

    kubectl get albconfig

    預期輸出如下,其中的alb-a8mmh2tqbmrm11****.cn-hangzhou.alb.aliyuncs.com即為ALB執行個體的網域名稱。

    NAME         ALBID                    DNSNAME                                               PORT&PROTOCOL   CERTID   AGE
    from_nginx   alb-a8mmh2tqbmrm11****   alb-a8mmh2tqbmrm11****.cn-hangzhou.alb.aliyuncs.com                            20m
  2. 解析設定頁面,單擊添加記錄,在添加記錄面板,完成以下參數的配置,然後單擊確認

    配置

    說明

    記錄類型

    在下拉式清單中選擇CNAME

    主機記錄

    網域名稱的首碼,在本樣本中輸入www

    解析請求來源

    選擇預設。

    記錄值

    輸入ALB執行個體的網域名稱。

    TTL

    全稱Time To Live,表示DNS記錄在DNS伺服器上的緩衝時間,保持預設。

設定流量權重

  1. 解析設定頁面, 單擊左側導覽列的權重配置

  2. 權重配置頁面,在操作列單擊開啟權重,然後單擊設定權重

  3. 設定權重面板,分別為CLB和ALB執行個體的解析記錄設定權重。將CLB執行個體對應的解析記錄的權重設為100,同時將ALB執行個體對應的解析記錄的權重設定為0。

    網域名稱權重設定

  4. 在觀察業務沒有影響的情況下,逐步減少CLB執行個體解析記錄的權重值,同時逐步增加ALB執行個體解析記錄的權重值。

  5. 登入對應Service的後端Pod所在Worker節點上,多次執行dig命令,驗證流量轉場效果。

    流量測試1流量測試2

  6. 根據流量切換的驗證結果,逐步將CLB執行個體解析記錄的權重值減小至0,同時逐步增加ALB執行個體解析記錄的權重值至100。

如果您的DNS服務解析商不支援CNAME解析的權重配置,請單擊此處查看流量切換方案。

臨時流量切換方案

步驟三:刪除Nginx Ingress相關資源

當Nginx Ingress長串連全部處理完成,且Nginx Ingress沒有新增流量時,您可以根據業務情境靜默觀察一段時間後釋放冗餘資源。

  1. 通過網域名稱解析控制台刪除Nginx Ingress相關DNS條目。

  2. 卸載Nginx Ingress Controller組件。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 在叢集管理頁左側導覽列中,選擇網路 > 路由

    3. 在Nginx Ingress右側操作欄,選擇image > 刪除,在彈出的對話方塊,單擊確定

    4. 在左側導覽列中選擇營運管理 > 組件管理頁面,單擊網路頁簽,在Nginx Ingress Controller卡片,單擊卸載

    5. 在彈出的對話方塊中,單擊確定

      說明

      Nginx Ingress Controller所使用的CLB會隨著組件卸載自動釋放,不會繼續產生計費。

相關文檔