デュアルスタックKubernetesクラスタのサポート

デュアルスタックKubernetesクラスタの実験的サポート。

2023年3月10日 | Steve Zhang - Intel、Alex Xu - Intel、Iris Ding - Intel、Jacob Delgado - F5、Ying-chun Cai - 元F5

過去1年間、IntelとF5は、KubernetesデュアルスタックネットワークのIstioへのサポートを提供するため協力してきました。

背景

作業には予想以上に時間がかかり、まだやるべきことが残っています。チームは当初、F5のリファレンス実装に基づいた設計から始めました。この設計はRFCにつながり、アプローチの再検討を余儀なくされました。特に、コミュニティは実装前にメモリとパフォーマンスの問題に対処することを求めていました。元の設計では、リスナー、クラスタ、ルート、エンドポイントについてEnvoyの設定を複製する必要がありました。多くの人がすでにEnvoyのメモリとCPU消費の問題を経験していることを考慮すると、初期のフィードバックではこのアプローチを完全に再評価することが求められました。多くのプロキシは、トラフィックの発生元に関わらず、アウトバウンドのデュアルスタックトラフィックを透過的に処理します。初期のフィードバックの大部分は、IstioとEnvoyで同じ動作を実装することでした。

デュアルスタックサポートの再定義

元のRFCに対するコミュニティからのフィードバックの大部分は、Istio内でサポートするのではなく、Envoyを更新して内部的にデュアルスタックのユースケースをより適切にサポートすることでした。これにより、新しい設計に至り、得られた教訓とフィードバックを適用して、簡素化された設計を実現しました。

Istio 1.17でのデュアルスタックのサポート

デュアルスタックの有効化に時間がかかった理由の一つとして、Envoyコミュニティと協力して多くの問題に対処したことがあります。アウトバウンドリスナーのIPファミリのマッチングリスナーごとの複数のアドレスのサポートを実装しました。Alex Xuはまた、Envoyがデュアルスタックのエンドポイントをよりスマートに選択できるように、長年未解決の問題解決に熱心に取り組んできました。Envoyへのこれらの改善の一部、たとえば複数のアドレスでソケットオプションを有効にする機能は、Istio 1.17リリースに含まれています(例:インバウンドクラスタへの追加のソースアドレス)。

チームによって行われたEnvoy APIの変更は、そのサイトのリスナーアドレスバインド設定で確認できます。Envoyのダウンストリームとアップストリームの両方の接続で適切なサポートを確保することは、デュアルスタックサポートを実現するために重要です。

合計で、チームはEnvoyに12件以上のPRを提出しており、少なくとも6件以上のPRに取り組んで、Istioでのデュアルスタックの採用を容易にしています。

一方、Istio側では、Issue #40394で進捗状況を追跡できます。Envoyでのさまざまな問題に取り組んでいるため、最近進捗がやや遅れていますが、Istio 1.17でデュアルスタックの実験的サポートを発表できることを嬉しく思っています!

デュアルスタックを使用した簡単な実験

  1. 次のコマンドを使用して、Istio 1.17.0以降でデュアルスタックの実験的サポートを有効にします。

    $ istioctl install -y -f - <<EOF
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    spec:
      meshConfig:
        defaultConfig:
          proxyMetadata:
            ISTIO_DUAL_STACK: "true"
      values:
        pilot:
          env:
            ISTIO_DUAL_STACK: "true"
    EOF
    
  2. 3つの名前空間を作成します。

    • dual-stack: tcp-echoはIPv4とIPv6の両方のアドレスでリスンします。
    • ipv4: tcp-echoはIPv4アドレスのみでリスンします。
    • ipv6: tcp-echoはIPv6アドレスのみでリスンします。
    $ kubectl create namespace dual-stack
    $ kubectl create namespace ipv4
    $ kubectl create namespace ipv6
    
  3. これらの名前空間とデフォルトの名前空間すべてで、サイドカーインジェクションを有効にします。

    $ kubectl label --overwrite namespace default istio-injection=enabled
    $ kubectl label --overwrite namespace dual-stack istio-injection=enabled
    $ kubectl label --overwrite namespace ipv4 istio-injection=enabled
    $ kubectl label --overwrite namespace ipv6 istio-injection=enabled
    
  4. 名前空間にtcp-echoデプロイメントを作成します。

    $ kubectl apply --namespace dual-stack -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/tcp-echo/tcp-echo-dual-stack.yaml
    $ kubectl apply --namespace ipv4 -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/tcp-echo/tcp-echo-ipv4.yaml
    $ kubectl apply --namespace ipv6 -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/tcp-echo/tcp-echo-ipv6.yaml
    
  5. デフォルトの名前空間にsleepデプロイメントを作成します。

    $ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/sleep/sleep.yaml
    
  6. トラフィックを確認します。

    $ kubectl exec -it "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- sh -c "echo dualstack | nc tcp-echo.dual-stack 9000"
    hello dualstack
    $ kubectl exec -it "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- sh -c "echo ipv4 | nc tcp-echo.ipv4 9000"
    hello ipv4
    $ kubectl exec -it "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- sh -c "echo ipv6 | nc tcp-echo.ipv6 9000"
    hello ipv6
    

これで、環境でデュアルスタックサービスを試すことができます!

リスナーとエンドポイントの重要な変更点

上記の実験では、リスナーとルートに変更が加えられていることに気付くでしょう。

$ istioctl proxy-config listeners "$(kubectl get pod -n dual-stack -l app=tcp-echo -o jsonpath='{.items[0].metadata.name}')" -n dual-stack --port 9000

リスナーは複数のアドレスにバインドされるようになりましたが、デュアルスタックサービスの場合のみです。他のサービスは、単一のIPアドレスでのみリスンします。

"name": "fd00:10:96::f9fc_9000",
"address": {
    "socketAddress": {
        "address": "fd00:10:96::f9fc",
        "portValue": 9000
    }
},
"additionalAddresses": [
    {
        "address": {
            "socketAddress": {
                "address": "10.96.106.11",
                "portValue": 9000
            }
        }
    }
],

仮想インバウンドアドレスも、0.0.0.0[::]の両方でリスンするように構成されるようになりました。

"name": "virtualInbound",
"address": {
    "socketAddress": {
        "address": "0.0.0.0",
        "portValue": 15006
    }
},
"additionalAddresses": [
    {
        "address": {
            "socketAddress": {
                "address": "::",
                "portValue": 15006
            }
        }
    }
],

Envoyのエンドポイントは、IPv4とIPv6の両方にルーティングするように構成されるようになりました。

$ istioctl proxy-config endpoints "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" --port 9000
ENDPOINT                 STATUS      OUTLIER CHECK     CLUSTER
10.244.0.19:9000         HEALTHY     OK                outbound|9000||tcp-echo.ipv4.svc.cluster.local
10.244.0.26:9000         HEALTHY     OK                outbound|9000||tcp-echo.dual-stack.svc.cluster.local
fd00:10:244::1a:9000     HEALTHY     OK                outbound|9000||tcp-echo.dual-stack.svc.cluster.local
fd00:10:244::18:9000     HEALTHY     OK                outbound|9000||tcp-echo.ipv6.svc.cluster.local

参加方法

まだ多くの作業が残っており、デュアルスタックサポートをアルファ版にするために必要な残りのタスクに協力していただけます。こちら

たとえば、Iris Ding(Intel)とLi Chun(Intel)はすでにコミュニティと協力して、アンビエントのネットワークトラフィックのリダイレクトに取り組んでおり、Istio 1.18の今後のアルファリリースでアンビエントサポートデュアルスタックを提供することを期待しています。

フィードバックをいただければ幸いです。ご協力いただければ、Istio Slackの#dual-stackチャンネルにお越しください。

Istioデュアルスタックに取り組んでくれたチームに感謝します!

この投稿を共有