IPv4/IPv6 対応、または単にデュアルスタックと呼ぶ Kubernetes リリースで利用可能だったものが、今月初め Kubernetes 1.23 のリリースで GA になった。
この作業は、Kubernetes Enhancement Proposal (KEP-563) で説明されたように、ほぼすべての Kubernetes コンポーネントに触れ、何年にもわたって作成されてきた。
InfoQ は、Microsoft の Khaled (Kal) Henidak 氏と Google の Tim Hockin 氏に話を聞いた。彼らは、デュアルスタックの設計者であり、SIG-NETWORK コミュニティと協力した実装者だ。彼らは、デュアルスタックの (動機、技術的な詳細、長い道のりとロードマップ、それがさまざまな Kubernetes コンポーネントとクラウド Kubernetes プロバイダに与える波及効果がどのように影響するか) について話している。
InfoQ: Kubernetes の ipv6 とデュアルスタックサポートは実際にはどのような意味がありますか?
Khaled (Kal) Henidak 氏: それに答えるために、私たちは少し時間を遡る必要があります。Kubernetes は、開始当初から、実行されているすべてのワークロードのインスタンス (Pod) に一意のネットワークアドレス (IP) を割り当てるという概念を導入してきました。この概念は当時は新しいものではありませんでした。これは、仮想マシン環境での標準的な運用方法でした。ただし、Kubernetes のような環境では斬新でした。これは、IP レベルでアドレス可能なワークロード、Service API を介した検出、複雑な入力制御 (ingress control)、ネットワークセキュリティポリシーなどのユースケースを開きました。
これが行われている間、業界は IoT、エッジコンピューティング、および (IPv6 でのみ実行される) 5G が急速に進歩していました。この急速な進歩により、残り僅かな IPv4 アドレスはさらに枯渇しました。これらの問題を回避するために IPv6 アドレスを使用することを検討している組織、または単にパフォーマンスのために IPv6 を使用することを検討している組織は、困難な状況の中にいました。彼らは、IPv6 クラスタとワークロードを間違いなく IPv4 でのみ実行されていた既存のシステムに接続できませんでした。利用可能だった唯一の解決策は、パフォーマンスの低下と運用の複雑さがセットになったある種のアドレス変換でした。
IPv4/IPv6 デュアルスタックネットワーキングで実行されている Kubernetes を使用すると、これらのワークロードは追加の複雑さやパフォーマンスの低下なしに、IPv4 と IPv6 の両方のエンドポイントにネイティブにアクセスできます。クラスタオペレータは、要件に合った任意の要求でアドレスファミリの一方または両方を使う外部エンドポイントを公開することも選択できます。Kubernetes は、実行されているネットワークについて強い仮定をしていません。たとえば、小さい IPv4 アドレス空間で実行しているユーザは、クラスタノードのサブセットでデュアルスタックを有効にし、残りを従来より大きな使用可能なアドレス空間を持つ IPv6 で実行することを選択できます。
ワークロードの大部分が IPv6 のみのネットワークに移動し、クラスタが IPv6 のみのネットワークで実行される将来を予測しています。しかしそれまでは、デュアルスタックは古いものと新しいものの2つの世界の接続を維持します。
Tim Hockin 氏: 単純な回答は、Kubernetes は IPv4 と IPv6 を同時に使用できるようになりました。Pod とサービスはどちらもいい方を選択できます。
より完全な回答は、1つだけではなく複数の IP アドレスを認識するように、一連のさまざまな API (Pod、サービス、ノード) を拡張しました。一連のコンポーネント (apiserver、controller-manager、kube-proxy、kubelet) を更新して、これらの拡張された API を使用し、ユーザがクラスタを構成して、Pod とサービスに IPv4 と IPv6 アドレスの両方を提供できるようにしました。可能な限り透過でリスクが低いものにするために、私たちは本当に懸命に努力しました。デュアルスタックが必要ない場合は、影響を受けることはありませんが、必要な場合は簡単にオンにできます。既存の Pod とサービスがある場合、自動的に変換されることはありませんが、簡単に変更できます。シングルスタックしか理解しないコントローラがある場合、これまで通りに機能し続けます。
デュアルスタックをサポートするようになり、いくつかのことが簡単になります。たとえば、IPv4 は32ビット (40億個の IP) に制限されています。「プライベート」IPv4 アドレスの範囲では、数百万の IP しか使用できません。通常の CIDR ベースのルーティングでは、スペースを大きなブロックに割り当てる必要があります。IPv6 は128ビット (数兆個の IP) があり、大きなブロックを事前に割り当てる危険性が低くなり「フラット」IP モードで Kubernetes の使用を始めやすくなります。
InfoQ: ネットワークのギーク以外でも完全に理解 (grok) できる実装の技術的な詳細を教えていただけますか?
Henidak 氏: 話は Pod から始まります。Kubernetes の Pod は API オブジェクトで表されます。オブジェクトには、特に割り当てられたネットワークアドレス IP を反映するステータスフィールドがあります。IP は、ノードの Container Runtime Interface (CRI) 実装を介して読み取る kubelet によって報告されます。CRI 自体は、Pod のデュアルスタックなどのネットワークのセットアップを担当する別個のコンポーネントである Container Network Interface (CNI) を呼び出すことによってネットワークをセットアップします。この API フィールドを拡張して、デュアルスタックアドレスを受け入れます。異なる IP ファミリから1つの IP アドレスまたは2つの IP アドレス (要求に応じて) です。これにより、これらのさまざまなコンポーネントを「やあ、この Pod はデュアルスタックだ」と言うように変更できます。
次に、Service API が同じ方法で拡張され、ユーザがサービスオブジェクトのデュアルスタックを設定できるようになりました。シングル IP または IP ファミリー、デュアルスタック IP または任意の要求したファミリーか、「可能な場合はデュアルスタックにする」と言うことを選択することができます。api-server は、ユーザのニーズに基づいて、ユーザが期待する要求で IP を予約またはサービスオブジェクトに割り当てます。
次の章の一部として、サービス仕様に一致するエンドポイント (pod) の検索を担当するコントローラについて説明します。つまり、Endpoint Controller とその後新しく導入されたより高性能な Endpoint-Slice コントローラです。これらのコンポーネントは、サービスの IP ファミリ仕様を理解し、それに応じた対応する Pod を見つけるように教えられました。
最後に、すべてのノードで実行され、サービス IP を負荷分散された Pod IP に変換を担当する kube-proxy を確認します。これらもデュアルスタックに変換する必要がありました。たとえば、ユーザが Linux マシンで iptables を使用するように kube-proxy を構成した場合、kube-proxy は IPv4 の iptables と iptables IPv6 を同時に使用して、ルールがユーザによって設定された仕様と一致するようにします。
Hockin 氏: IPv6 は、正確には「新しい」ものではありませんが、ネットワークのグローバルなデフォルトではありません。世界が IPv6 に近づき、真にユビキタスになるにつれて「デュアルスタック」ネットワーキングの概念がブリッジとして機能します。このモデルは、すべてのワークロードに古い IPv4 アドレスと新しい IPv6 アドレスの両方へのアクセスを提供します。IPv6 を使用する場合もあれば、IPv4 を使用する場合もあります。たとえば、多くの Web サイトはまだ IPv6 をサポートしていません。
Kubernetes は、Pod やサービスのようなものが単一の IP アドレスを持つことができるという不幸な普及したアイデアで構築されました。この取り組みで大変な作業の一部は、それらすべての場所を見つけて、安全で互換性のある方法で複数のアドレスをサポートするように更新することでした。ネットワークを多用するシステムであるため、処理する場所が多くあり、微妙なエッジケースが大量にありました。
例: Kubernetes サービスには歴史的に単一の IP アドレスがあります。デュアルスタックを追加するには、それを2つのアドレスに拡張するか、ユーザに2つの異なるサービス (IPのフレーバーごとに1つ) を作成するように指示する方がよいかどうかを検討する必要がありました。それぞれのアプローチにはメリットとデメリットがありました。
InfoQ: Kubernetes Enhancement Proposal - KEP-563 はすべての Kubernetes コンポーネントに影響を与えるようです。このような大規模な変更を伴う提案と課題についてお話しいただけますか?
Henidak 氏: 純粋なビルド、テスト、およびリリースシナリオの観点からこれに答えるのは魅力的です。しかし、私はいくつかの少し異なることに光を当てたいと思います。このような変化が真空中では起こらないことに気づいたとき、微妙な課題が現れます。変更の適用が進むにつれて、システムの他の部分も進行し、変更されていました。たとえば、Service API の変更に取り組んでいる間、Endpoint Slice コントローラはそれに並んで移行していました。つまり、Kubernetes の他の部分の実行中のコードを調整および変更する必要があります。そのためには、複数の飛行中の PR とメンテナ間の調整が必要です。ありがたいことに、メンテナはさまざまな機能の調整と正確さを確保するために緊密に協力していました。今後も長い間記憶すると思うもう一つの課題は「ネットの新しい API アプローチ」のアイデアです。Kubernetes は、API と API ガイドラインに関して強力な厳密さを維持しています。これらは、さまざまなリリース間で一貫性と前方/後方互換性を確保し、最終的に、API に対して CLI またはプログラムを使用するユーザを問わず、ユーザに改善された一貫性のある全体的な UX を提供します。API の変更に近づくにつれ、フィールドを複数形にする必要がありました。たとえば、Pod IP は単一値フィールドであり、古いクラスタ、さらに重要なことにスキューされたクラスタとの下位互換性を維持しながら、(Pod が IPv4 および IPv6 IP を持つことができることを表すために) 複数値フィールドにする必要がありました (つまり、一部はデュアルスタックであり、他の部分はそうではありません)。これは、Kubernetes API の設計では未知の領域でした。さまざまなアプローチをテストし、それに従ってガイドラインを更新する必要がありました。この課題は、Service API がフィールドの複数形化を導入しただけでなく、任意のフィールドが残りの依存フィールドの値を駆動できる相互依存フィールドも導入したことを考えると、さらに興味深いものになります。これは、私たちが先駆けなければならなかったもう1つの未知の領域です。
Hockin 氏: この KEP は、プロジェクトの歴史の中で最大かつ最も広くインパクトのあるものの1つでした。ただ飛び込んでハッキングを始めるのは気が進まないものでしたが、できる限り早くやらなければならないことはわかっていました。最初は比較的単純でしたが、アドレスを扱うすべての場所について議論するにつれて、ますます複雑になりました。更新が必要なもののリストを作成するには、長い時間と多くの人がかかりました。
とても大きかったので、私たちはそれをフェーズで分割しなければならず、そうしないと消化することはできませんでした。できそうな理解ができたと感じた後の開発作業ではまだ多くのことを見逃していることがわかりました。「alpha」と呼べるものがあると感じるまで、詳細化を繰り返しました。
それをみんなの手に渡した後、私たちはまだ多くの詳細のマークを見逃していることに気づき、さらにいくつか繰り返しました。みんなが追加の時間を費やしてそれを喜んで行ってくれてうれしいです - 私の意見では、結果ははるかに良いものになりました。
InfoQ: デュアルスタックは、開発者やアーキテクトが知っておくべき従来の ipv4 アプリでの予期しない下位互換性の問題を引き起こしますか? 採用を妨げる可能性のあるものは何でしょうか?
Henidak 氏: 互換性については厳しいです。特に、Kubernetes 構成のバリエーションが事実上無限にある場合は、予想される互換性の問題について包括的に説明することは不可能です。
私は、ユーザとメンテナコミュニティの間で責任を分担しながら、先行と事後の両方の観点からそれについて考えるのが好きです。先行的には、私たちは設計、実装、テストをうまく行ったと思います。特にテストで。「恐怖が退屈に変わるまでテストする」という言葉は、このジャーニーの間ずっと頻繁に言われたことを覚えています。安定して卒業の前に、私たちは、クラウド、Kubernetes Kind、kubeadm などによってエコシステム全体にその方法を見つけるデュアルスタックを注意深く観察し、問題があるかどうかを確認しました。また、リリースサイクル全体で安定した卒業の準備ができていても、テストと検証にもう一度時間をかけるために、意図的にベータ段階にとどまりました。事後的には、報告された問題や問題を注意深く監視し、デュアルスタックをデプロイしている人々と頻繁に連携しています。これはすべて、変更を容易にし、単に互換性の問題だけでなく、考えられる問題に対処することを目的として行われます。
API 互換性の作業には高い自信を持っています。既存のクラスタをデュアルスタックにアップグレードすることは、シームレスなプロセスでなければなりません。私が心配しているのは「戻す」ことです。クラスタをデュアルスタックにアップグレードすると、Service API が割り当てるアドレス空間が効果的に追加されます (つまり、IPv6 CIDR を既存の Service IPv4 CIDR に追加します)。これには、クラスタネットワークの構成方法に応じて、オプションで Pod の CIDR を含めることもできます。ユーザがシングルスタックに戻ることを決定した場合「Pod と Service CIDR の変更」として処理する必要があります。これは、クラスタに適用するにはすでに複雑な変更であり、通常はクラスタユーザによる手動の介入が必要です。
Hockin 氏: 私たちが正しく仕事をしていれば、後方互換性の問題を引き起こすことはないはずです。以前は機能していたものはすべて、引き続き機能するはずです。Pod にデュアルスタックアドレスが割り当てられている場合でも、特にデュアルスタックを要求しない限り、Services API はデフォルトでシングルスタックになります。
もちろん、問題があれば私たちはお聞きしたいと考えています。
InfoQ: さまざまなパブリッククラウドの Kubernetes サービスと Container Network Interface (CNI) に対するデュアルスタック実装のカスケード効果について話していただけますか?
Henidak 氏: パブリッククラウドはすでに従来の IaaS ワークロードでデュアルスタックを有効にするプロセスにあり、私たちが Kubernetes でデュアルスタックを有効にするために取り組んでいたのと同様でした。特に Kubernetes v1.23 がリリースされた今、デュアルスタッククラスタが最初に DIY クラスタとして示され、次にマネージドクラスタのサービスとして示されることを期待しなければならないと思います。私が注意深く見守っているもう1つのフロントは、非従来型のフォームファクタクラスタのデュアルスタックの使用法です。たとえば、クラスタノードの一部または大部分がエッジロケーションに配置され、コントロールプレーンがクラウドでホストされている場合です。これらのユースケースは、パブリック IPv4 アドレス空間が限られているため、最も要求の厳しいデュアルスタック機能の1つです。
Hockin 氏: Kubernetes がサポートしているからといって、すべてのプロバイダと環境がサポートしているわけではありません。クラウド環境を使用していて、デュアルスタックが必要な場合は、クラウドが実際にネットワークレベルでそれをサポートしていることを確認する必要があります。ホストされている Kubernetes 製品を使用している場合は、プロバイダがデュアルスタックをサポートしていることを確認する必要があります。
これは最初の非ベータリリースであり、ほとんどのプロバイダがデュアルスタックサポートがサポートされた製品として提供できるようになるまでには、しばらく時間がかかると思います。
InfoQ: 今後、ipv4 と ipv6 アドレスを混在させることはできますか? 一般的に、デュアルスタックと関連するエコシステムのロードマップは何でしょうか?
Henidak 氏: はい。デュアルスタックの Kubernetes 実装の設計、実装、テスト中に私たちが強く固執してきたことの1つは、まさにそれです。アドレスを混在させるだけでなく、Kubernetes が IP ファミリーの要求について何も想定していないことを確認します。たとえば、一部のユーザはデフォルトの IPv6 クラスタを好みますが、必要に応じてデュアルスタックをサポートする機能を備えています。他では別の好みを持っているかもしれません。Services API でさえ「可能な場合はデュアルスタックを使用する」構造をサポートしています。これにより、Kubernetes Operator、Chart、その他の種類の仕様を公開している開発者は、適切と思われるアプリケーションネットワーク要件を表現できます。
私がコミュニティ内で本当に尊敬していることの1つは、物事を「ロードマップ」と呼んでいることです。それは、私たちが終わりのないジャーニーをしているという共通の理解から来ています。やるべきことは常にたくさんあります。私たちは通常、中長期的な目標についてのアイデアを持っていますが、絶えず変化する要件や優先順位に対応するための計画と実行にも柔軟性があります。デュアルスタックの有効化は主要なマイルストーンですが、それは私たちの終わりのないジャーニーのマイルストーンにすぎません。短期的には、より多くの CNI プロバイダと Ingress Controller がデュアルスタックをサポートすることを期待しています。また、そのサポートがクラウド、ロードバランサ、ベアメタルデプロイメントに拡張されることを期待しています。
長期的には、マルチネットワーキングとマルチホームの Kubernetes Pod にますます焦点を当てているようです。単一の Pod に複数のネットワークからの複数の NIC が接続されている場合に、単一の Pod が1つ以上の IP ファミリからの複数のアドレスをレポートする場合があります。これにより、Network Virtual Appliances (NVA) プロバイダなどの重要なユースケースへと開き、マルチクラスタまたはマルチネットワーク環境でもうまく機能します。
Hockin 氏: 明確に言っておきますが、この作業は、実際に IPv6 サーバで IPv4 クライアントを使用できるようにすること (またはその逆) ではありません。これにより、特定のワークロードは、必要なものに応じて、いずれかの IP ファミリを使用してサーバにアクセスできることを表現できます。また、Kubernetes ユーザがニーズをより完全に表現できるようになります。たとえば、デュアルスタッククラスタがあり、サービスが1つの IP ファミリーのみを提供するようにしたい場合は、正確に使用する IP ファミリーを選択して表現できます。システムの他の部分は、その選択を尊重します。
これにより、以前は処理が困難だった、特にネットワーク指向のものである一部のクラスのアプリに扉が開かれますが、最終的にこれはかなり深いインフラストラクチャになります。ほとんどのユーザが気づいたり気にかけたりしないことを願っていますが、本当に必要なユーザが利用可能ですぐに使用できるようにします。
SIG-NETWORK コミュニティには、デュアルスタック実装の履歴など、Kubernetes のネットワーク全般に関する詳細情報がある。