Kubernetesを拡張する
Kubernetesは柔軟な設定が可能で、高い拡張性を持っています。 結果として、Kubernetesのプロジェクトソースコードをフォークしたり、パッチを当てて利用することは滅多にありません。 このガイドは、Kubernetesクラスターをカスタマイズするための選択肢を記載します。 管理しているKubernetesクラスターを、動作環境の要件にどのように適合させるべきかを理解したいクラスター管理者を対象にしています。 将来の プラットフォーム開発者 、またはKubernetesプロジェクトのコントリビューターにとっても、どのような拡張のポイントやパターンが存在するのか、また、それぞれのトレードオフや制限事項を学ぶための導入として役立つでしょう。
概要
カスタマイズのアプローチには大きく分けて、フラグ、ローカル設定ファイル、またはAPIリソースの変更のみを含んだ 設定 と、稼働しているプログラムまたはサービスも含んだ 拡張 があります。このドキュメントでは、主に拡張について説明します。
設定
設定ファイル と フラグ はオンラインドキュメントのリファレンスセクションの中の、各項目に記載されています:
ホスティングされたKubernetesサービスやマネージドなKubernetesでは、フラグと設定ファイルが常に変更できるとは限りません。変更可能な場合でも、通常はクラスターの管理者のみが変更できます。また、それらは将来のKubernetesバージョンで変更される可能性があり、設定変更にはプロセスの再起動が必要になるかもしれません。これらの理由により、この方法は他の選択肢が無いときにのみ利用するべきです。
ResourceQuota、PodSecurityPolicy、NetworkPolicy、そしてロールベースアクセス制御(RBAC)といった ビルトインポリシーAPI は、ビルトインのKubernetes APIです。APIは通常、ホスティングされたKubernetesサービスやマネージドなKubernetesで利用されます。これらは宣言的で、Podのような他のKubernetesリソースと同じ慣例に従っています。そのため、新しいクラスターの設定は繰り返し再利用することができ、アプリケーションと同じように管理することが可能です。さらに、安定版(stable)を利用している場合、他のKubernetes APIのような定義済みのサポートポリシーを利用することができます。これらの理由により、この方法は、適切な用途の場合、 設定ファイル や フラグ よりも好まれます。
拡張
拡張はKubernetesを拡張し、深く統合されたソフトウェアの構成要素です。 これは新しいタイプと、新しい種類のハードウェアをサポートするために利用されます。
ほとんどのクラスター管理者は、ホスティングされている、またはディストリビューションとしてのKubernetesを使っているでしょう。 結果として、ほとんどのKubernetesユーザーは既存の拡張を使えばよいため、新しい拡張を書く必要は無いと言えます。
拡張パターン
Kubernetesは、クライアントのプログラムを書くことで自動化ができるようにデザインされています。 Kubernetes APIに読み書きをするどのようなプログラムも、役に立つ自動化機能を提供することができます。 自動化機能 はクラスター上、またはクラスター外で実行できます。 このドキュメントに後述のガイダンスに従うことで、高い可用性を持つ頑強な自動化機能を書くことができます。 自動化機能は通常、ホスティングされているクラスター、マネージドな環境など、どのKubernetesクラスター上でも動きます。
Kubernetes上でうまく動くクライアントプログラムを書くために、コントローラー パターンという明確なパターンがあります。
コントローラーは通常、オブジェクトの .spec
を読み取り、何らかの処理をして、オブジェクトの .status
を更新します。
コントローラーはKubernetesのクライアントです。Kubernetesがクライアントとして動き、外部のサービスを呼び出す場合、それは Webhook と呼ばれます。 呼び出されるサービスは Webhookバックエンド と呼ばれます。コントローラーのように、Webhookも障害点を追加します。
Webhookのモデルでは、Kubernetesは外部のサービスを呼び出します。 バイナリプラグイン モデルでは、Kubernetesはバイナリ(プログラム)を実行します。 バイナリプラグインはkubelet(例、FlexVolumeプラグイン、ネットワークプラグイン)、またkubectlで利用されています。
下図は、それぞれの拡張ポイントが、Kubernetesのコントロールプレーンとどのように関わっているかを示しています。
拡張ポイント
この図は、Kubernetesにおける拡張ポイントを示しています。
- ユーザーは頻繁に
kubectl
を使って、Kubernetes APIとやり取りをします。Kubectlプラグインは、kubectlのバイナリを拡張します。これは個別ユーザーのローカル環境のみに影響を及ぼすため、サイト全体にポリシーを強制することはできません。 - APIサーバーは全てのリクエストを処理します。APIサーバーのいくつかの拡張ポイントは、リクエストを認可する、コンテキストに基づいてブロックする、リクエストを編集する、そして削除を処理することを可能にします。これらはAPIアクセス拡張セクションに記載されています。
- APIサーバーは様々な種類の リソース を扱います。
Pod
のような ビルトインリソース はKubernetesプロジェクトにより定義され、変更できません。ユーザーも、自身もしくは、他のプロジェクトで定義されたリソースを追加することができます。それは カスタムリソース と呼ばれ、カスタムリソースセクションに記載されています。カスタムリソースは度々、APIアクセス拡張と一緒に使われます。 - KubernetesのスケジューラーはPodをどのノードに配置するかを決定します。スケジューリングを拡張するには、いくつかの方法があります。それらはスケジューラー拡張セクションに記載されています。
- Kubernetesにおける多くの振る舞いは、APIサーバーのクライアントであるコントローラーと呼ばれるプログラムに実装されています。コントローラーは度々、カスタムリソースと共に使われます。
- kubeletはサーバー上で実行され、Podが仮想サーバーのようにクラスターネットワーク上にIPを持った状態で起動することをサポートします。ネットワークプラグインがPodのネットワーキングにおける異なる実装を適用することを可能にします。
- kubeletはまた、コンテナのためにボリュームをマウント、アンマウントします。新しい種類のストレージはストレージプラグインを通じてサポートされます。
もしあなたがどこから始めるべきかわからない場合、このフローチャートが役立つでしょう。一部のソリューションは、いくつかの種類の拡張を含んでいることを留意してください。
API拡張
ユーザー定義タイプ
新しいコントローラー、アプリケーションの設定に関するオブジェクト、また宣言型APIを定義し、それらをkubectl
のようなKubernetesのツールから管理したい場合、Kubernetesにカスタムリソースを追加することを検討して下さい。
カスタムリソースはアプリケーション、ユーザー、監視データのデータストレージとしては使わないで下さい。
カスタムリソースに関するさらなる情報は、カスタムリソースコンセプトガイドを参照して下さい。
新しいAPIと自動化機能の連携
カスタムリソースAPIと制御ループの組み合わせはオペレーターパターンと呼ばれています。オペレーターパターンは、通常ステートフルな特定のアプリケーションを管理するために利用されます。これらのカスタムAPIと制御ループは、ストレージ、またはポリシーのような他のリソースを管理するためにも利用されます。
ビルトインリソースの変更
カスタムリソースを追加し、KubernetesAPIを拡張する場合、新たに追加されたリソースは常に新しいAPIグループに分類されます。既存のAPIグループを置き換えたり、変更することはできません。APIを追加することは直接、既存のAPI(例、Pod)の振る舞いに影響を与えることは無いですが、APIアクセス拡張の場合、その可能性があります。
APIアクセス拡張
リクエストがKubernetes APIサーバーに到達すると、まず最初に認証が行われ、次に認可、その後、様々なAdmission Controlの対象になります。このフローの詳細はKubernetes APIへのアクセスをコントロールするを参照して下さい。
これらの各ステップごとに拡張ポイントが用意されています。
Kubdernetesはいくつかのビルトイン認証方式をサポートしています。それは認証プロキシの後ろに配置することも可能で、認可ヘッダーを通じて(Webhookの)検証のために外部サービスにトークンを送ることもできます。全てのこれらの方法は認証ドキュメントでカバーされています。
認証
認証は、全てのリクエストのヘッダーまたは証明書情報を、リクエストを投げたクライアントのユーザー名にマッピングします。
Kubernetesはいくつかのビルトイン認証方式と、それらが要件に合わない場合、認証Webhookを提供します。
認可
認可は特定のユーザーがAPIリソースに対して、読み込み、書き込み、そしてその他の操作が可能かどうかを決定します。それはオブジェクト全体のレベルで機能し、任意のオブジェクトフィールドに基づいての区別は行いません。もしビルトインの認可メカニズムが要件に合わない場合、認可Webhookが、ユーザー提供のコードを呼び出し認可の決定を行うことを可能にします。
動的Admission Control
リクエストが認可された後、もしそれが書き込み操作だった場合、リクエストはAdmission Controlのステップを通ります。ビルトインのステップに加え、いくつかの拡張が存在します:
- イメージポリシーWebhookは、コンテナでどのイメージを実行することができるかを制限する
- 任意のAdmission Controlの決定を行うには、一般的なAdmission webhookが利用できる。Admission Webhookは作成、更新を拒絶できる
インフラストラクチャ拡張
ストレージプラグイン
Flex Volumesは、Kubeletがバイナリプラグインを呼び出してボリュームをマウントすることにより、ユーザーはビルトインのサポートなしでボリュームタイプをマウントすることを可能にします。
デバイスプラグイン
デバイスプラグインを通じて、ノードが新たなノードのリソース(CPU、メモリなどのビルトインのものに加え)を見つけることを可能にします。
ネットワークプラグイン
他のネットワークファブリックがネットワークプラグインを通じてサポートされます。
スケジューラー拡張
スケジューラーは特別な種類のコントローラーで、Podを監視し、Podをノードに割り当てます。デフォルトのコントローラーを完全に置き換えることもできますが、他のKubernetesのコンポーネントの利用を継続する、または複数のスケジューラーを同時に動かすこともできます。
これはかなりの大きな作業で、ほとんど全てのKubernetesユーザーはスケジューラーを変更する必要はありません。
スケジューラはWebhookもサポートしており、Webhookバックエンド(スケジューラー拡張)を通じてPodを配置するために選択されたノードをフィルタリング、優先度付けすることが可能です。
次の項目
- カスタムリソースについてより深く学ぶ
- 動的Admission controlについて学ぶ
- インフラストラクチャ拡張についてより深く学ぶ
- kubectlプラグインについて学ぶ
- オペレーターパターンについて学ぶ