Kubernetes Ingressコントローラーの移行で学んだこと Digital.ai

この記事では、 Digital.aiの CloudOps チームが、最近の Ingress 移行の背後にある決定とアプローチについての洞察を共有します。

顧客は安定性を期待しています。 Digital.ai 当社の標準MSAは99.5%の稼働率を保証しています。 予定外の停電が4時間弱 2025年の初め頃に、私たちは Kubernetes いくつかのカスタム機能をサポートするために、NGINXからTraefikへのIngressコントローラを導入しました。そのための方法を考え出す必要がありました。 safelyですが、柔軟性が生まれました。私たちは 重み付けDNS Amazon Route 53 のレコード。

重み付けDNS

重み付けDNS(または重み付けルーティング)は、完全修飾ドメイン名(例: www.digital.ai)は複数のレコードで構成され、それぞれに重み付けが行われます。重み付けが高いほど、特定のレコードにルーティングされるトラフィックが多くなります。重み付けされたDNSを使用すると、実験やリアルタイム調整の機能を犠牲にすることなく、リスクを最小限に抑えることができます。例えば、最初の重み付け変更の波では、トラフィックの10%を新しいエンドポイントにルーティングし、残りの90%は古いエンドポイントにルーティングしたまま、その後の波では新しいエンドポイントへの重み付けを増やすことができます。重み付けを波ごとに増減することで、トラフィックパターンを監視し、予期しない問題の発生を防ぎながら、影響範囲を最小限に抑えることができます。

監視

4xx/5xxエラーのトラフィックパターンを監視することで、重み付けの決定に役立ちます。新しいエンドポイントのエラーが増加している一方で、古いエンドポイントのエラー率は同程度に維持されている場合は、新しいエンドポイントの動作不良の原因を調査し、調整を行い、監視し、必要に応じて繰り返してください。

トレフィク

NGINXは十分に機能していましたが、将来的にはTraefikこそがIngressの未来のコントローラーになるだろうと確信に至りました。Traefikは本番環境での使用に耐えうる性能を備え、実戦でテストされ、多くの機能を備えています。Traefikの優れた可観測性により、問題の根本原因をより迅速に特定できます。

製品の導入

フェーズ1(セットアップ)

  • DeployNGINXと並行してTraefikをed
  • 同一のルーティングルールを設定
  • イングレスにアノテーションを作成して重み付けされた DNS レコードを作成しました
    • 最初は、トラフィックを NGINX のみに誘導するためにレコードに重み付けをします。

フェーズ2(移行)

  • Traefikで任意に低い重量(10%)から始める
  • スループット、エラー、レイテンシのメトリックを監視する
  • Traefikの入口の重量を増やす

外部DNS注釈

ExternalDNS によって提供されるアノテーションを使用して、Route53 で重み付けされた 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を指すセットをそれぞれ1つずつ作成できます。重み付けと組み合わせることで、トラフィックの一部を一方に、別の部分をもう一方に割り当てることができます。

技術的な実装

まず、トラフィックがすべて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

外部DNSはIngressのアノテーションを監視し、Route53に重み付けされたDNSレコードを作成します。手動のDNS管理は必要ありません。外部DNSを使用すると、アノテーションを更新することでトラフィックをシフトできます。

# 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コントローラを移行し、より高い可用性を実現できました。成功の鍵は、移行をバイナリスイッチではなく段階的なプロセスとして捉えたことです。これにより、移行の各フェーズを監視できました。段階的な移行によって、変更が大きな効果をもたらしていることを確信できました。

お勧めの関連ガジェット