我們在遷移 Kubernetes Ingress 控制器流程中學到了什麼 Digital.ai

在這篇文章中, Digital.aiCloudOps 團隊分享了最近 Ingress 遷移背後的決策和方法。

客戶期望穩定。 Digital.ai 我們的標準MSA提供99.5%的正常運作時間或 近四小時的非計劃性停電 每月。 2025年初,我們改變了我們的 Kubernetes 為了支援一些自訂功能,我們需要將 NGINX 的 Ingress 控制器遷移到 Traefik。為此,我們需要找到一種方法。 safe但這給了我們靈活性。我們最終決定使用 加權DNS 與亞馬遜 Route 53 有紀錄。

加權DNS

加權 DNS(或加權路由)的工作原理是將完全限定網域名稱(例如)與 DNS 伺服器關聯起來。 www.digital.ai加權 DNS 包含多筆記錄,每筆記錄都被賦予一個權重。權重越高,表示路由到特定記錄的流量越多。加權 DNS 讓您在不犧牲試驗和動態調整能力的前提下,最大限度地降低風險。例如,第一波權重調整可能將 10% 的流量路由到新的端點,而 90% 的流量仍流向舊的端點;後續的權重調整可能會增加新端點的權重。分階段地增加和減少權重,使您能夠監控流量模式,發現意外問題,同時最大限度地減少影響範圍。

監控

監控 4xx/5xx 錯誤的流量模式將有助於您選擇合適的權重。如果新端點的錯誤率不斷上升,而舊端點的錯誤率卻保持穩定,請調查新端點出現異常的原因,進行調整,持續監控,並根據需要重複上述步驟。

特拉菲克

儘管 NGINX 一直以來都表現出色,但我們最終認為 Traefik 是我們未來 Ingress 控制器的理想選擇。 Traefik 已做好生產部署準備,久經考驗,並提供了許多功能。 Traefik 更強大的可觀測性使我們能夠更快地找到問題的根本原因。

實施

第一階段(準備階段)

  • Deployed Traefik 與 NGINX 並行
  • 配置了相同的路由規則
  • 在 Ingress 上建立註解以建立加權 DNS 記錄
    • 最初對記錄進行加權,以將流量完全引導至 NGINX。

第二階段(遷移)

  • 在 Traefik 上,先設定一個非常低的權重(10%)。
  • 監控吞吐量、錯誤和延遲指標
  • 在 Traefik 入口處增加體重

外部DNS註釋

利用 ExternalDNS 提供的註釋,我們可以在 Routs53 中建立加權 DNS 記錄。

external-dns.alpha.kubernetes.io/aws-weight 指示 ExternalDNS 建立一筆加權記錄並為其指派權重。 AWS 允許加權記錄的值介於 0 到 255 之間。如果您希望將極少量流量傳送到某個端點,可以將權重設為 1,這樣會將 (1/(1+255)) 的流量傳送到測試端點,並將剩餘的 (255/(1+255)) 流量傳送到另一個端點。這樣,就可以使用不同的權重來平衡流向不同端點的流量。為簡單起見,我們使用 100 作為權重。

external-dns.alpha.kubernetes.io/set-identifier 是一個特定於服務商的註解,用於建立集合標識符。集合標識符允許區分類型和網域相同的多個 DNS 記錄。例如,您可以建立一個指向 Nginx 的集合,另一個指向 Traefik 的集合。結合權重,您可以將一部分流量定向到一個服務商,另一部分流量定向到另一個服務提供者。

技術實施

我們先來看所有流量都流向 nginx 的情況,可以看到我們已經創建了一個 set-identifier 名為 nginx。我們創建了另一個 set-identifier traefik 網站顯示沒有車輛通行。

# NGINX example
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-nginx
  annotations:
    external-dns.alpha.kubernetes.io/aws-weight: "100"
    external-dns.alpha.kubernetes.io/set-identifier: "nginx"
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
# Traefik example
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-traefik
  annotations:
    external-dns.alpha.kubernetes.io/aws-weight: "0"
    external-dns.alpha.kubernetes.io/set-identifier: "traefik"
spec:
  ingressClassName: traefik
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

ExternalDNS 會監控 Ingress 上的註解,並在 Route 53 中建立加權 DNS 記錄,無需手動管理 DNS。 ExternalDNS 允許我們透過更新註解來轉移流量。

# Shift to 50/50 traffic split
kubectl patch ingress api-nginx -p '{"metadata":{"annotations":{"external-dns.alpha.kubernetes.io/aws-weight":"50"}}}'
kubectl patch ingress api-traefik -p '{"metadata":{"annotations":{"external-dns.alpha.kubernetes.io/aws-weight":"50"}}}'

# Both endpoints should now be handling half the traffic.
# Monitor traffic to ensure that traffic is behaving as expected.
# Use additional waves to update the balance of traffic until you feel confident.

# Switch to 100% Traefik
kubectl patch ingress api-nginx -p '{"metadata":{"annotations":{"external-dns.alpha.kubernetes.io/aws-weight":"0"}}}'
kubectl patch ingress api-traefik -p '{"metadata":{"annotations":{"external-dns.alpha.kubernetes.io/aws-weight":"100"}}}'

經驗教訓

在從 NGINX 遷移到 Traefik 的過程中,我們實現了零停機時間,同時提高了可用性。我們認為這項成功歸功於以下因素:

  1. 交通逐漸轉移加權 DNS 使我們能夠在監控過渡的同時輕鬆地轉移流量。
  2. 監控:對新舊基礎設施的了解使我們對轉移重心的能力更有信心。
  3. 外部DNS使用 ExternalDNS 使我們能夠無需親自幹預 DNS 的處理方式。

遷移最佳實踐

我們給那些考慮走類似道路的人的建議是:

  • 從小事做起首先從非關鍵服務開始遷移。
  • 自動化盡可能實現自動化,使用 GitOps 方法變更權重。
  • 把你的時間給自己足夠的時間進行改變
  • 持續監控設定警報,確保您能及時收到任何潛在問題的通知。
  • 文档:記錄遷移每個階段的流程、程序和操作手冊。

結語

遷移 Ingress 控制器無需計劃內停機。我們利用加權 DNS 記錄成功遷移了 Ingress 控制器,並實現了更高的可用性。成功的關鍵在於將遷移視為漸進的過程,而非簡單的二元切換。這使我們能夠監控遷移的每個階段。分階段遷移讓我們確信,我們的更改正在產生顯著的影響。

你可能還喜歡