デュアルスタックKubernetesクラスタのサポート
デュアルスタックKubernetesクラスタの実験的サポート。
過去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でデュアルスタックの実験的サポートを発表できることを嬉しく思っています!
デュアルスタックを使用した簡単な実験
次のコマンドを使用して、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
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
これらの名前空間とデフォルトの名前空間すべてで、サイドカーインジェクションを有効にします。
$ 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
名前空間に
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
デフォルトの名前空間にsleepデプロイメントを作成します。
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/sleep/sleep.yaml
トラフィックを確認します。
$ 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デュアルスタックに取り組んでくれたチームに感謝します!
- Intel: Steve Zhang、Alex Xu、Iris Ding
- F5: Jacob Delgado
- Yingchun Cai(元F5)