Kubernetesがデータベースに似ている理由とは - 宣言型アプリケーション管理の基礎知識


この記事ではAlibaba Cloudのスタッフエンジニアであり、KubernetesのメンテナでもあるZhang Lei氏が、Kubernetesがデータベースと似ている点について考えを述べています。

最近、「Kubernetesは新しいデータベースだ」という主張がKubernetesコミュニティで注目を集めています。正確に言うと、この主張は、Kubernetesがデータベースとして使われるというよりも、Kubernetes自体がデータベースのように機能するという意味です。

一見すると、Kubernetesをデータベースと比較することは奇妙に思えるかもしれません。結局のところ、コントローラパターンや宣言型APIといったKubernetesの動作原理は、「データベース」という概念とは直接的な関係がないように思えるのです。しかし、ここでは、Kubernetesの最も基本的な理論にまで遡ることができる本質を明らかにしています。

Kubernetesにおける宣言型アプリケーション管理の基礎知識

Kubernetesに関する議論になると、「宣言型アプリケーション管理」という概念がよく出てきます。この概念は、Kubernetesを他のインフラプロジェクトと区別するデザインでもあり、Kubernetesに特有の機能でもあります。では、Kubernetesにおける宣言型アプリケーション管理とは何でしょうか。

宣言型アプリケーション管理は "宣言型API "だけではない

Kubernetesの中核となる動作原理によれば、kubeletによるコンテナの実行、kube-proxyによるiptablesルールの実行、kube-schedulerによるポッドのスケジューリング、DeploymentによるReplicaSetの管理など、Kubernetesのほとんどの機能が、これまで強調してきたコントローラパターンに従っていることが明らかになりました。つまり、ユーザーがYAMLファイルで希望の状態を主張すると、Kubernetesの各コンポーネントがクラスタ全体の状態をユーザーの主張した希望の状態に近づけ、最終的には同じ状態にするというものです。このように、実際の状態が望ましい状態に徐々に近づいていく過程を「リコンシリエーション」と呼びます。この原則は、Kubernetes Operatorsやカスタムコントローラにも適用されます。

宣言的な記述によってコントローラが2つの状態を調整するように仕向けられる方法は、宣言的なアプリケーション管理を最も直感的に体現しています。なお、このプロセスには2つの意味があります。

宣言的記述の望ましい状態とは、その記述がユーザーの望む最終的な状態でなければならないということです。この記述に中間的な状態を使用したり、この望ましい状態を動的に調整したい場合、この宣言的セマンティクスは正確に実行できません。

Reconciliation-based state approximation(調整ベースの状態近似):システムの実際の状態が望ましい状態と一貫性を保てるように、調整プロセスが行われます。具体的には、リコンシリエーション・プロセスは、「チェック→Diff→実行」のループを回し続けることで、システムの実際の状態と望ましい状態の違いに常に対処できるようにします。つまり、宣言的な記述だけでは不十分なのです。なぜなら、最初に記述を提出した時点で、システムは望ましい状態を実現しているからです。しかし、1時間後には必ずしもそうなっているとは限りません。宣言型アプリケーション管理と宣言型APIを混同している人が多いのは、リコンサイルの必要性を正しく理解できていないからです。

この宣言型アプリケーション管理システムがKubernetesにどのようなメリットをもたらしたのか、気になりますよね。

データとしてのインフラストラクチャが宣言型アプリケーション管理の本質である

宣言型アプリケーション管理システムの理論的な基盤となっているのが、Infrastructure as Data(IaD)と呼ばれる概念です。この概念によると、インフラストラクチャ管理は、特定のプログラミング言語や設定方法と結びつけるべきではなく、ユーザーが期待するシステムの状態を完全に表すことができる、純粋でフォーマットされたシステム読み取り可能なデータに依存すべきであるとしています。

注:Infrastructure as DataはConfiguration as Dataとも言います。

その利点は、インフラに対するあらゆる操作が、最終的にデータに対するCURD(create, update, retrieve, and delete)操作と同等であることです。さらに重要なことは、データを「作成、更新、取得、削除」する方法は、インフラ自体とは関係ないということです。したがって、インフラとのやりとりは、プログラミング言語、リモートコールプロトコル、ソフトウェア開発キット(SDK)などに縛られることはありません。対応するフォーマットの "データ "さえ生成できれば、インフラに対して思い通りの操作を行うことができるのです。

Kubernetesに関しては、Kubernetes上で操作を行いたい場合、KubernetesのRESTful APIやSDKを使うのではなく、YAMLファイルを送信して、そのファイルをCURDするだけです。なお、YAMLファイルの内容は、IaDシステムやKubernetesのデータに対応しています。

その意味で、Kubernetesは設立当初から、すべての機能を「APIオブジェクト」つまりデータの断片として定義してきました。Kubernetesのユーザーは、特定のプログラミング言語やSDKに縛られることなく、このようなデータをCURDすることで好きなことができます。さらに重要なことは、独自の命令型APIやSDKと比較して、YAMLベースの宣言型データは基盤となる実装をより簡単にシールドできるため、既存のインフラ機能との接続や統合が容易になります。これはまた、Kubernetesのエコシステムが驚くべきスピードで繁栄するための秘密兵器でもあります。IaDがもたらした宣言型APIとコントローラパターンにより、コミュニティ全体がKubernetes用のプラグインを書いたり、様々な機能を集約したりすることに積極的です。さらに、これらのプラグインや機能は非常にユニバーサルでポータブルです。これらのメリットは、MesosやOpenStackといった他のプロジェクトでは得られないものです。IaDは、Kubernetesが「The Platform for Platform」という目標を達成するためのコアとなる競争力だと言っていいでしょう。

さて、このIaD設計におけるデータとは、Kubernetesにおける宣言型APIオブジェクトのことであり、Kubernetesの制御ループは、システムがそのようなデータによって記述された状態と常に整合性を保つことができることを保証するものである、と理解できるだろう。この観点から見ると、Kubernetesは本質的に、システムの設定値をデータとして表現し、コントローラのアクションによって設定値との整合性を維持する調整システムと言えます。

「システムの設定値との整合性を保つ」という理屈に聞き覚えはありませんか?

エンジニア出身の方であれば、Control Theoryという講座でKubernetesの基礎を学んだことがあるかもしれません。

Kubernetesのエッセンスを学んだ後は、Kubernetesがどのように機能しているのかを理解しやすくなるかもしれません。

たとえば、KubernetesでYAMLファイルをたくさん書くのは、Kubernetes、つまり制御システムにデータを送信する手段が必要だからです。このプロセスにおいて、YAMLはフォーマットされたデータを書くためのキャリアに過ぎません。

さて、Kubernetesがそのようなデータを簡単に解析・処理できるように、データに決まった「フォーマット」があるのかどうか気になりますよね。このようなフォーマットは、KubernetesではAPIオブジェクトスキーマと呼ばれています。カスタムコントローラをよく書く人は、このスキーマを深く理解しているかもしれません。CRDは、このスキーマを定義するための特別なAPIオブジェクトです。

YAML vs データベース

IaDは、Kubernetesが伝統的な分散型システムではなく、データベースのように動作すると判断しています。これは、Kubernetesの学習曲線が高いことの根本的な理由の1つです。

この観点から見ると、Kubernetesが公開するAPIオブジェクトはあらかじめ定義されたスキーマを持つテーブルです。私たちはこれらのテーブルのデータをCURDするためにYAMLファイルを書きます。SQLのように、YAMLはデータベース内のデータを操作するためのツールであり、キャリアでもあります。Kubernetesと従来のデータベースの唯一の違いは、Kubernetesは取得したデータを永続化せず、データを使ってコントローラを駆動して操作を行い、データで宣言された最終的な状態と一致するシステムの状態を徐々に調整していくことです。さて、ここで先ほどの「制御理論」に戻ります。

Kubernetesでは、システム全体が「データ」に基づいています。そのため、Kubernetesのエンジニアにとっては、YAMLファイルを書いたり実行したりすることがほぼ唯一の日常業務となっています。しかし、今回の記事でIaDを学んだ後は、「YAMLエンジニア」よりも適切な肩書きである「データベースエンジニア」を名乗ることができます。

Kubernetesの "ビューレイヤー"

前述したように、Kubernetesの設計を「データベース」という観点から再検討すると、設計の背景にある多くの独創的なアイデアをより深く理解することができます。例えば、以下のようなものです。

  • データモデル:APIオブジェクトとKubernetesのCRD(Custom Resource Definition)の仕組み
  • データの傍受、検証、修正の仕組み:Kubernetesのアドミッションフック
  • データ駆動型の実行0のメカニズム:Kubernetesのコントローラとオペレータ
  • データ変更の監視とインデックスのメカニズム:Kubernetesのインフォーマー

Kubernetesのインフラがますます複雑になり、サードパーティのプラグインや機能が増えるにつれ、Kubernetesコミュニティは、データベース的なKubernetesに組み込まれたデータテーブルが、規模的にも複雑さ的にも爆発的に増加していることに気づき始めました。そのため、Kubernetesコミュニティでは以前から、Kubernetesの「データビュー」をどのように設計するかを議論してきました。

CREATE VIEW <Native Kubernetes object> AS <View-layer object of Kubernetes>;

このようなKubernetes APIリソースの上に構築された「ビューレイヤー」のメリットは、データベースの「ビュー」とよく似ています。例えば、以下のようなものです。

1)データ形式・表現の簡素化と変更

Kubernetesのビュー層は、元々のインフラ層のAPIオブジェクトではなく、簡略化・抽象化されたアプリケーション層のAPIオブジェクトを開発者やオペレータに公開することができます。ユーザーは、基盤となるKubernetesオブジェクトのスキーマに制限されることなく、ビュー層のオブジェクトを自由に定義することができます。

2)複雑なデータ操作の簡略化(SQLの簡略化)

抽象化されたビュー層オブジェクトは、より簡素化されたUIを必要とし、また、Kubernetesにおける複雑なAPIリソースのトポロジーを定義し、管理することができる必要があります。これにより、Kubernetesアプリケーションを管理する際の複雑さや負担が軽減されます。

3) 基盤となるデータテーブルの保護
開発者やオペレーターはビュー層のオブジェクトを直接操作するため、Kubernetesの元となるオブジェクトは保護されています。これにより、Kubernetesの元となるオブジェクトは、ユーザーに知覚されることなく変更やアップグレードが可能となります。

4)データ操作の再利用(SQLの再利用)

ビュー層オブジェクトは、基盤となるインフラから完全に切り離されているため、ビュー層オブジェクトによって宣言されたアプリケーションや運用能力は、Kubernetesクラスタがサポートする能力に関係なく、Kubernetesクラスタ全体で使用することができます。

5)ビューでの標準的なテーブル操作のサポート

Kubernetesのビュー層オブジェクトは、APIオブジェクトのすべての操作とプリミティブペアがビュー層オブジェクトに適用されるように、標準的なKubernetesオブジェクトでなければなりません。これにより、KubernetesのAPIモデルのユーザーに余計な精神的負担をもたらすことを避けることができます。

ビュー層の概念はKubernetesにはネイティブに実装されていませんが、コミュニティの大規模なメンバーの多くは、ビュー層が常識となっています。例えば、PinterestはPinterestアプリケーションを記述・定義するために、KubernetesでPinterestService CRDを開発しました。このCRDは、要するにビュー層オブジェクトです。しかし、このやり方はほとんどの企業にとってはまだ初歩的すぎます。データビューは、データの抽象化や変換以上のものです。実際の本番環境でビュー層を広範囲に使用するには、以下の重要な課題を解決しなければなりません。

1、ビュー層のオブジェクトと基盤となるKubernetesオブジェクトの間のマッピング関係をどのように定義し、管理することができますか?これは単純な1対1のマッピングではないことに注意してください。1つのビュー層オブジェクトが複数のKubernetesオブジェクトに対応することもあります。
2、「運用能力」はどのようにモデル化され、抽象化されますか?実際のアプリケーションでは、単純なDeploymentやK8s Operatorの方が多いです。例えば、コンテナ化されたアプリケーションとそのスケールアウトポリシーのように、プログラムとそれに対応する運用能力の組み合わせであることがほとんどです。これらの運用能力は、アプリケーションの中でどのように定義されていますか?これらの能力をすべてアノテーションとして定義することは可能でしょうか?
3、運用能力とプログラムの間の結合関係はどのように管理されますか?Kubernetesでは、結合関係はどのように実際の実行関係に変換されるのでしょうか?
4、Alibaba Cloud RDSインスタンスのような標準的なクラウドリソースは、ビュー層のオブジェクトを通じてどのように定義されますか?

前述の問題は、Kubernetesがネイティブな「ビュー層」を実装していない理由の一部であり、Kubernetesのアプリケーション層におけるOAM(Open Application Model)などのオープンソースプロジェクトにおいても大きな懸念材料となっています。注目すべきは、OAMの「仕様」だけでは、これらの問題をすべて解決することはできないということです。Kubernetesの「データビュー」がもたらすメリットや利便性をユーザーが真に享受できるようにするためには、標準的なビュー層の依存ライブラリを実装層で使用する必要があります。現在、コミュニティ内でKubernetesビュー層のためのかなり強力な依存ライブラリとなっているのが、OAM Kubernetes runtime プロジェクトです。

概要

IaDをベースとしたデータベースのようなKubernetesのデザインは、一方ではこのコミュニティの繁栄と発展を支えています。その一方で、IaDは、無数の「独立した」コントローラやオペレータ、そしてこれらのコントローラによって組み立てられた非常に複雑なKubernetesクラスタの出現にもつながります。本番環境でこのような複雑さを持つKubernetesクラスターは、開発者や運用者が喜んで受け入れるクラウドネイティブなアプリケーション管理プラットフォームとは程遠いものです。

過去5年間のKubernetesの成功は、宣言型APIを用いてインフラ機能(ネットワーク、ストレージ、コンテナなど)を徐々に標準化・統一化していったことに起因しています。OAMのようなKubernetesのアプリケーション層の技術が普及したことで、標準的なアプリケーション層のエコシステムが生まれつつあります。より使いやすいデータビュー層を通じてエンドユーザーにAPIを公開する一方で、インフラエンジニアにはより強力なモジュール化された水平接続されたプラットフォーム機能を提供しようとするチームが増えています。

一方で、データベース的なKubernetesが足りない他の分野は、間違いなく今後のコミュニティの注目分野になるでしょう。例えば、急速に成熟しているOPA(Open Policy Agent)プロジェクトは、「データの傍受、検証、修正の仕組み」の進化の結果であると考えられます。また、アリババが「1万ノード」のクラスターで実施したコントロールリンクのパフォーマンス最適化の理論的根拠と実践は、データベースのパフォーマンス最適化のそれと似ています。

IaDについてのご意見、ご感想をぜひコメントでお寄せください。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ