Kubernetesの仮想クラスタについてとりとめもなく語る

7 min read読了の目安(約6500字

KubeCon EU 2021というイベントが先日行われ、その基調講演の中でRed Hatの人によるThe Hybrid Control Plane という短いセッションがあった。

内容をかいつまんで紹介すれば、①Kubernetesのコンテナ管理機能をコンテナに限らず汎用的に使えるように拡張したら、②リソースやクラスタの管理で生じる問題が解決できるのではないか?という問いかけだ。

①Kubernetesのコンテナ管理機能とは、マニフェストファイルによる宣言的な設定や、状況に応じて自動的にコンテナが再配置されるリコンサイルループによる自動調整機能だ。説明はKubernetesがいかに自動化の考え方を変えたか?という記事が詳しい。

②リソースやクラスタの管理で生じる問題とは、マルチテナントやマルチクラウドを考えると分かりやすい。複数の動作環境、複数のチームを横断的に監視、管理するための組織がいなくなればどうなるか想像がつきやすいのではないか。

そのためにkcp というプロトタイプを作ったよとセッションは締めくくられて終わった。

初見では、正直Kubernetesの機能をコンテナ以外に拡張するという話は、以前自分が紹介したKubernetes CloudService Operatorがもたらす未来についてにあるように以前からあったアイディアだし、そのために作ったkcpも、軽量という側面を突き詰めるならk3sのような先達があるしなーとスルーしていた。

しかし、kcpのドキュメントを読み込み、@superbrothersさんのツイートを拝見した中で、仮想クラスタ(あるいは論理クラスタ)というジャンルが見えてきた。Operatorを推進しているRed Hatがkcpを開発したモチベーションもなんとなく見えてきたので取り留めもなく残す。

仮想クラスタとは Kubernetesの namespace を拡張し、Kubernetes自体を仮想化する技術だ。

仮想クラスタのOSSの一つである、vclusterの開発者&プロダクトオーナーのFabian Krammさんはこのように説明する。

Kubernetesの namespace とは、一つのKubernetesクラスタを多くのユーザーが複数のチームまたはプロジェクトに分散した環境で使用するために考えられた仕組みだ。Kubernetes上のリソースを論理的に区分し、それぞれに適切な権限を付与することでマルチテナントを構成する仕組みだ。一つのKubernetesクラスタを共有することで、Kubernetesの管理というコストの削減や運用負担の軽減、リソースの効率的な利用を可能にしている。

しかし、Kubernetesの namespace ではマルチテナントを実現するために足りない側面が見えてきた。その一つが権限管理だ。

Kubernetesの権限管理は大きく namespace にまたがってリソースにアクセスできる ClusterRolenamespace 内に閉じる Role の二種類が存在する。マルチテナントを考慮するなら、Role権限のみで運用したいところだが、それではできないことが存在する。

代表例がストレージの管理だ。Kubernetes上のアプリケーションが新規の外部ストレージサーバーにアタッチしたり、リソースを要求するためには Storage Resourceや PersistentVolume ResourceをKubernetesにデプロイする必要があるが、これらは ClusterRole 権限を持つユーザーやサービスアカウントでしか行うことができない。必然的に namespace で仕切られた境界を破り、異なるテナント間のアプリケーションの分離が適切に行えなくなってしまうとFabian Krammさんは主張する。

Operatorもこの権限問題が関わっており、マルチテナントでの運用は注意が必要だ。例えば、Admission Webhook(etcdサーバーに保存する前にKubernetesリソースを編集もしくは検証するための仕組み)やIngress Controllerを利用する場合、ClusterRoleが必要であり、ほかのテナントに秘匿すべき情報が見えてしまう。したがって、各テナントオーナーではなく、プラットフォームの提供者側が管理しなくてはいけないのだが、それはそれでテナントオーナーの責務を離れることになり、ややこしいことになる。

また、OpenShift Hiveという、クラウドのManaged OpenShiftクラスタを新規に払い出したり制御するための管理ツール(そしてそれはOpenShiftのOperatorとして動く)を開発しているDevan Goodwin氏は、自身の経験からKubernetesのフェールセーフやetcdのバックアップという観点からも論理クラスタ(=仮想クラスタ)は大事だという。

OperatorはCRDなどの動作に必要な設定データをOperatorが動くKubernetesのetcdサーバーに格納する。ここで、OpenShift Hiveのような大規模な管理ツールがスケールして性能限界に突き当たったらどうなったか。etcdサーバーを巻き込んでOpenShiftクラスタが丸ごと落ちてしまったらしい。サーバーのサイジングが適切に行われていなかっただけではなく、OpenShift上のほかのOperatorによっても"限界"が左右されたので、Operatorを分離するための仕組みを要したという。

派生する形で、落ちたetcdサーバーの復旧作業においても困ったことになった。etcdクラスタはシャーディングなどにより冗長性が担保されており、etcdクラスタの内のサーバーが故障しても復旧は容易だ(CKAでやった)。だが、etcdクラスタがすべて落ちた場合に個別のetcdサーバーのスナップショットから再度クラスタを構築しようとすると、クラスタやノード、証明書などの情報が含まれているのでリストアできない。したがって、何らかのバックアップソリューションを活用するか、独自に設計する必要がある。後者の選択肢の場合、考慮事項は多く安易な決断は難しい。(注釈: したがって、Operatorが動くためのetcdサーバーとOperatorで制御したいアプリケーションを制御するためのetcdサーバーを分離するために仮想クラスタが必要なのかなと自分は捉えた。最後に原文のリンクを張ったのでご参照ください。)

主にDay2 Operationにかかわる課題を仮想クラスタが解決してくれる話を取り上げたが、Operatorの開発を行うアプリケーション開発者にとっても仮想クラスタは嬉しい。

この他にも色々なモチベーションが各ドキュメントに提示されていた。それら仮想クラスタで解決したい課題を雑にまとめるとこんな感じか。

  • Kubernetesをマルチテナントのプラットフォームとして運用したいときにnamespace という粒度ではOperatorやストレージに関する分離が不十分などでもっと上位の論理区分が欲しい
  • Kubernetesのコントローラープレーンに関して耐障害性を高め、ディザスタリカバリに備えたい
  • Operatorの開発にあたり、バージョン違いのOperatorを並行して動かすために個別のKubernetesクラスタを手軽に払い出せる手段が欲しい
  • されど、Kubernetesクラスタを並行して複数運用するのは無駄が多く、コントローラープレーンを中央集権的に管理する仕組みが欲しい

さて、ここまで仮想クラスタが解決したい課題について説明してきたが、これらの機能は透過的なマルチクラスタが解決しようとしている問題と重複するところが多い。

透過的なマルチクラスタとは何だろうか?Tencentがvirtual-kubeletを用いて開発しているtensile-kubeが、個人的に推しプロジェクトなので紹介したい。

このプロダクトはKubernetesのマルチクラスタを実現するソリューションだ。virtual-kubeletを利用することで複数のKubernetes(図ではLower Kubernetes)にデプロイされたアプリケーションが一つのKubernetes(Upper Kubernetes)で動いているように見せる。

これにより、複数のKubernetesクラスタを中央集権的に管理しつつ、一方でUpper Kubernetesが死んだときに個別のKubernetesが独立して運用できるような高い冗長性を確保している。それを可能にしているのは、KubernetesのAPIを叩くためのエンドポイントが複数あるからだ。仮想クラスタが透過的なマルチクラスタとも共通する理由はこのあたりにある。

そもそも、透過的なマルチクラスタに限定せず、マルチクラスタという広義で見た場合、どうだろう。

Kubernetes完全ガイドの著者である青山さんがマルチクラスタで解決したい問題について次のように解説している。

複数クラスタで構成するには下記のような理由があるのではないでしょうか。 何がしたいかによっては、選択できる手法も限られてくるでしょう。
・耐障害性、信頼性向上、ディザスタリカバリ
・マルチクラウド・ハイブリッドクラウド対応
・ジオロケーションによるパフォーマンス問題の解消
・機密データのローカリティを確保する
・In-place クラスタアップグレードを避ける
・スケーラビリティの確保
・エッジ・フォグ環境に適用する

仮想クラスタが解決している課題でもあり、副作用で解決できてしまうけど主題としている課題でないものもあり...多分、仮想クラスタの個別ソリューションに従って解決できる課題かチェックしていく必要があるだろう。

仮想クラスタのソリューション

  • VirtualCluster
    • Kubernetesのコミュニティである、マルチテナントSIGグループが開発しているプロダクト
    • マルチテナントSIGグループの名前からわかるように、Kubernetesでマルチテナント運用しようとしたときに生じる諸問題を解決したいというモチベーションから始まっている
    • 物理的なKubernetesクラスタは一つで、その上に仮想的なKubernetesクラスタを実現している...はず
  • vcluster
    • Loft Labs社が開発しているプロダクト
    • 物理的なKubernetesクラスタは一つで、その上にk3sをベースとしたコントローラープレーンなどを構築し、仮想的なKubernetesクラスタを実現している
    • minishiftをDocker pluginでデプロイした場合、コントローラーノードやワーカーノードがDocker上にコンテナとして配置されるが、あれに近いと思う
  • kcp
    • 正確にはkcp自体はリコンサイルループを行うコア機能を最小化しようぜというソリューションであり、仮想クラスタを実現しているのは同じリポジトリ内にある cluster-controller operator
    • 前述の二つと異なり、仮想クラスタのコントローラープレーンはKubernetesAPIServerやetcdなどの最小構成でしかなく、実際のコンテナは他のKubernetesクラスタで動作する。マルチクラスタと仮想クラスタのあいの子みたいなソリューション
    • コンテナランタイムと組み合わせることで、Operatorをアプリケーションとして実行するためのプラットフォームにもなるのは面白いと思った
    • ただ、Kubernetesなら当然あるだろう Serivce Resourceや ReplicaSets Resourceがないなど非常に尖ってるので、既存のKubernetes Operatorを持ってきてもまず動かないので注意

参考文献

https://techstep.hatenablog.com/entry/2020/09/06/160435
https://amsy810.hateblo.jp/entry/2020/06/17/090000
https://loft.sh/blog/introduction-into-virtual-clusters-in-kubernetes/
https://rm-rf.ca/posts/2021/kcp-kube-without-nodes-and-why/
https://www.cncf.io/blog/2019/06/20/virtual-cluster-extending-namespace-based-multi-tenancy-with-a-cluster-view/