このブログは、 SaaSサービスの構築と運用に必要だったさまざまな側面を取り上げているブログ シリーズの最初のものです。
以前のブログで説明したように、当社の顧客は、スマート製造、公共安全のためのビデオフォレンジック、アルゴリズム取引、通信事業者の 5G ネットワークなど、複雑で多様なビジネスソリューションを構築しているため、これらのアプリケーションとそのエンドユーザーに対して、常時接続で信頼性の高いエクスペリエンスを提供する必要があります。
これらのアプリケーションは、クラウド プロバイダーや顧客のエッジ ロケーションにまたがる複数のクラスターで実行される可能性があるため、当社のプラットフォーム チームは、複数のマルチテナント Kubernetes クラスターを展開、保護、運用するための分散コントロール プレーンと PaaS サービスを構築する必要がありました。 この分散コントロール プレーンは、運用、スケーリング、パフォーマンスの面で多くのメリットをもたらしました。これらのメリットについては、GitOps を使用して何千ものエッジ K8s クラスターを管理する方法など、プレゼンテーション(ビデオ リンク) で取り上げるほか、今後数週間以内に別のブログ投稿でも取り上げます。
当社が分散アプリケーションを管理するためのプラットフォームの中核として Kubernetes (K8s) を選択しました。これは、Kubernetes が過度に規範的になることなく豊富な機能セットを提供し、お客様にとって重要と思われるものに対して柔軟に革新をもたらしてくれるからです。 私たちはこれをサービス構築の基盤として使用し、K8s の人気が高まるにつれて、K8s に精通した開発者やオペレーターを見つけることも容易になりました。
とはいえ、ハイブリッド環境 (複数のクラウド、ネットワーク POP、エッジ ロケーション) にわたって多数の本番環境グレードの Kubernetes クラスターを展開して管理するのは、Kubernetes 向けの次のようなすぐに使用できるソリューションがないため、簡単ではありません。
GKE、AKS、EKS、RKE、OpenShift、Cloud Foundry などの複数のクラウド プロバイダーとオープンソース プラットフォームで概念実証を何度か行った結果、上記の 5 つの要件をすべて満たすものはないことがわかりました。 その結果、私たちは「バニラ」Kubernetes から始めて、アイデンティティ、ネットワーク、セキュリティ、マルチテナント、ログ記録、メトリックなど、いくつかの機能を追加した独自の PaaS を構築することにしました。 当社では社内のニーズを満たすために Kubernetes を使用していますが、これらの Kubernetes クラスターを社内ユーザーや顧客に直接公開してワークロードを実行させないなど、難しい決断を下さなければなりませんでした (マルチテナントが当社の主要目標であったため、これについては後で詳しく説明します)。
追加する必要のある複数の新機能に加えて、エッジ、ネットワーク、パブリック/プライベート クラウドのさまざまな場所で、顧客のワークロードと並行してワークロード/サービスを実行する必要もありました。 つまり、複数の環境にある複数のクラスターを管理するための追加機能を構築する必要がありました。これらはすべて、グローバル ネットワークと分散アプリケーション ゲートウェイを使用して接続され、これらのクラスター間でゼロ トラストとアプリケーション レベルの接続が提供されます。
単一の Kubernetes クラスターで実行されるアプリケーションの構築と運用は、クラウド プロバイダーが管理するクラスターを使用する場合でも、簡単な作業ではありません。 このため、DevOps チームや SRE チームではオーバーヘッドを最小限に抑え、多数のクラスターの複雑さに対処しないことが一般的です。 チームが 1 つの大規模な Kubernetes クラスターを構築し、すべての種類のリソースを同じクラスター内に配置するのはよくあることです。 これは、操作を簡素化し、クラスターを実行してコンピューティング効率とコストを最大化できるため、素晴らしいように思えますが、いくつかの理由から、これは最善のアイデアではありません。 まず、本番環境のワークロードのニーズは、開発/テストやステージングとは大きく異なります。不安定な開発ワークロードは、より安定した本番環境のワークロードに問題を引き起こす可能性があります。
さまざまなワークロードのニーズに加えて、K8 のセキュリティと分離の制限もマルチクラスターを推進するもう 1 つの要因です。 K8s のセキュリティとリソースの分離を解決するための一般的なアプローチは、マルチテナント モデルを使用して、テナントごとに独立したクラスターを起動することです。 これはクラウドでは実行可能かもしれませんが、エッジで複数のクラスターを実行することはできません。 エッジ サイトにはコンピューティング リソースとストレージ リソースの制限があり、各追加クラスターのログとメトリックを中央クラウドに送信するためのネットワーク帯域幅が制限されています。
複数の Kubernetes クラスターの問題に対処するために、Kubernetes クラスター (開始時には Anthos と Azure Arc は存在していませんでした) と KubeFed を集中管理するための Rancher を評価しました。 当時利用可能な 2 つのアプローチは次のとおりです (現在でも同じ状況です)。
GCP Anthos と Azure Arc の最近の発表を受けて、分散コントロール プレーンを構築するという当初の決定を再評価したところ、これら 2 つの新しいサービスでも分散クラスターの 2 つの重大な問題を解決できないという結論に達しました。 私たちのプラットフォームに必要な 2 つの主要な機能は次のとおりです。
これら 2 つの問題を解決するには、分散制御プレーンという新しい技術を考案して、「複数の」クラスターの運用オーバーヘッドを解決し、リソースが限られた環境でのマルチテナンシーに「複数のクラスター」と同等のものを提供する必要がありました。
私たちのプラットフォーム チームは、チームが使用できるように Kubernetes API を公開する Kubernetes 用の分散コントロール プレーンを構築することを決定しましたが、これらの API は、コントロール プレーン内にのみ存在する「仮想」クラスター、つまり仮想 K8s クラスター用の仮想 K8s (vK8s) API サーバーから提供されます (図 1を参照)。 このコントロール プレーンは、ユーザーの意図を、エッジ、ネットワーク POP、パブリック クラウドの場所で実行されている複数の物理 Kubernetes クラスターにマッピングします。 これらの物理クラスターは、分散コントロール プレーンからのみアクセス可能であり、個々のテナント/ユーザーはアクセスできません。
このコントロール プレーンは、各テナントに 1 つ以上の「仮想」アプリケーション クラスターを提供し、テナントはそこにアプリケーションをデプロイできます。また、コントロール プレーンは、構成に基づいて、複数の物理 Kubernetes クラスターにわたってアプリケーションを複製して管理します。 構成と展開の操作に加えて、監視操作もこの「仮想」クラスターに従います。複数の物理クラスターからデータを収集して分析するためのツールを構築する必要がありません。
productpage というサンプル UI アプリケーションを取り上げます。ユーザーの意図は、pa2-par、ny8-nyc、ams9-ams の 3 つの場所に分散して実行し、それぞれに 2 つのレプリカを作成することです。 ユーザーが vK8s オブジェクトを作成し、それを仮想クラスターに接続すると、標準の kubectl で使用できる vK8s API サーバーがすぐにプロビジョニングされます。
次のステップとして、ユーザーはこの仮想クラスターの kubeconfig をダウンロードし、productpage の K8s デプロイメントを記述する標準 yaml を作成します。
デプロイメント仕様の作成後、ユーザーはこの仮想クラスター上にデプロイメントを作成できます。
ここで、ユーザーがデプロイメントを確認すると、各場所に 2 つずつ、合計 6 つのレプリカが開始されていることがわかります (pa2-par、ny8-nyc、ams9-ams)。
次の出力は、特定の物理ノードにマッピングされた各場所で実行されている2つのポッドを示しています。
このシンプルな例は、インストールや管理の負担なしに、わずか数分であらゆるアプリのマルチクラスターレプリケーションを実現することがいかに簡単であるかを示しています。 分散コントロール プレーンは、意図をマッピングするだけでなく、個々のクラスター ベースではなく仮想クラスターの可観測性も提供します。
図 2に示すように、集中管理プレーンは 2 つのパブリック クラウド プロバイダー (それぞれ 1 つのリージョン) にまたがって実行されています。1 つは AWS で、もう 1 つは Azure (冗長性のため) です。 この管理プレーンにより、SRE はハード マルチテナントのテナントを作成できます。たとえば、VoltMesh サービスに取り組んでいる開発チームがテナントになり、顧客 POC に取り組んでいる顧客ソリューション チームが独自のユーザー セットを持つ独自のテナントになることができます。
これらの各テナントは、多数の名前空間を作成し、それらの名前空間で共同作業を行うユーザー グループを割り当てることができます。 これらの名前空間は Kubernetes 名前空間ではなく、ユーザー向けの RBAC ルールと IAM ポリシーを備えたプラットフォーム内の分離境界です。
名前空間内のユーザーがアプリケーション クラスターを作成したい場合、vK8s オブジェクトが作成され、それによって管理プレーンに vK8s API サーバーが作成されます。 この vK8s オブジェクトを使用すると、ユーザーはデプロイメント、ステートフル セット、PVC などを作成でき、コントロール プレーンは、vK8s オブジェクトに関連付けられているサイトに基づいて、1 つまたは複数の物理クラスターでこれらの操作が実行されるようにします。
各テナントとユーザーは標準の K8s 操作を変更せずに使用しているため、システムは Spinnaker、Helm、Jenkins など、オペレーターに人気のある多くのツールと互換性があります。
分散コントロール プレーンの大きな利点は、SRE チームと DevOps チームの運用オーバーヘッドが解決されたことです。 仮想クラスター全体で操作 (構成、展開、監視、ポリシーなど) を実行できるようになり、コントロール プレーンによって複数の物理クラスターに自動的にマッピングされます。 コントロール プレーンは、複数のクラスターの運用の簡素化に加えて、マルチテナントのセキュリティと分離の問題も解決しました。
この分散コントロール プレーンにより、プラットフォームに新しい機能を追加したい開発者の生産性も向上しました。複数のクラスターにわたる構成や操作に影響する新しい機能を追加するたびに、新しい自動化を構築する必要がなくなりました。 意図ベースの構成モデルを使用し、コントロール プレーンは何を行う必要があるかを認識します。 さらに、別の CLI ではなく kubectl を使用して、この分散された複数のクラスター オブジェクト (仮想 kubernetes) と対話し続けることができます。
これを開発テスト、ステージング、本番環境で 1 年以上実行した結果、このグローバルに分散されたコントロール プレーン (ネットワーク POP で実行) によって、スケール、パフォーマンス、信頼性の面で大きなメリットが得られることがわかりました。これは、初期の頃にはまったく想像もできなかったことです。 この調査結果については、今後数週間以内に開催される KubeCon プレゼンテーションと別のブログ投稿で取り上げる予定です。
このブログ シリーズでは、パブリック クラウド、プライベート ネットワーク PoP、エッジ サイト内の多数のアプリケーション クラスターを使用して、グローバルに分散された SaaS サービスを構築および運用するために必要なさまざまな側面について説明します。 次は、分散アプリケーション向けのグローバル サービス メッシュです。