Kubernetes のしくみ
Kubernetes インストールを正常に構成するには、Kubernetes システム アーキテクチャを確実に理解しておく必要があります。 ここでは、Kubernetes インストールを構成するすべてのコンポーネントを見ていきます。
コンピューター クラスターとは
クラスターは、連携して 1 つのシステムとして見なされるように構成するコンピューターのセットです。 クラスター内の構成済みコンピューターは、同じ種類のタスクを処理します。 たとえば、それらすべてで、Web サイトや API をホストしたり、コンピューティング集約型の作業を実行したりします。
クラスターにより、これらのタスクのスケジュール設定と制御を担当する一元化されたソフトウェアが使用されます。 タスクを実行するクラスター内のコンピューターは "ノード" と呼ばれ、スケジュール ソフトウェアを実行するコンピューターはコントロール "プレーン" と呼ばれます。
Kubernetes アーキテクチャ
前述のように、オーケストレーターは、アプリをデプロイして管理するシステムです。 また、クラスターが、連携して 1 つのシステムと見なされるコンピューターのセットであることも学習しました。 Kubernetes をオーケストレーションおよびクラスター ソフトウェアとして使用して、アプリをデプロイし、コンピューティング リソースのニーズの変化に対応します。
Kubernetes クラスターには、少なくとも 1 つのメイン プレーンと 1 つ以上のノードが含まれています。 コントロール プレーンとノード インスタンスは、どちらも、物理デバイス、仮想マシン、またはクラウド内のインスタンスです。 Kubernetes の既定のホスト OS は Linux で、Linux ベースのワークロードが既定でサポートされています。
クラスター ノードで Windows Server 2019 以降を使用して Microsoft ワークロードを実行することもできます。 たとえば、ドローン追跡アプリのデータ処理サービスが、特定の Windows OS API 呼び出しを使用する .NET 4.5 アプリとして記述されているとします。 このサービスは、Windows Server OS を実行しているノードでのみ実行できます。
ここでは、コントロール プレーンとワーカー ノードの両方と、それぞれで実行されるソフトウェアの詳細について見てみましょう。 各コンポーネントの役割と、各コンポーネントが実行されるクラスター内の場所を理解しておくと、Kubernetes をインストールする場合に役立ちます。
Kubernetes コントロール プレーン
Kubernetes クラスターの中のKubernetes コントロール プレーンにより、Kubernetes のオーケストレーション機能を管理するサービスのコレクションが実行されます。
学習の観点からは、Kubernetes の機能を調べる場合、テスト環境で 1 つのコントロール プレーンを使用するのが、わかりやすいです。 しかし、Azure Kubernetes Service (AKS) などの運用デプロイやクラウド デプロイでは、3 個から 5 個のレプリケートされたコントロール プレーンを持つ高可用性デプロイが好ましい構成であることにあなたは気付きます。
Note
コントロール プレーンは、クラスターの状態を維持するために特定のソフトウェアが実行されるからといって、他のコンピューティング ワークロードの実行から除外されるわけではありません。 しかし、通常は、重要でないユーザー アプリのワークロードの実行からコントロール プレーンを除外した方がよいでしょう。
Kubernetes のノード
Kubernetes クラスター内のノードは、コンピューティング ワークロードが実行される場所です。 各ノードは、API サーバーを介してコントロール プレーンと通信し、ノードの状態の変化について通知します。
コントロール プレーンで実行されるサービス
Kubernetes は、コントロール プレーンで実行されている複数の管理サービスに依存します。 これらのサービスにより、クラスターとコンポーネントの間の通信、ワークロードのスケジュール設定、クラスター状態の永続化などの側面が管理されます。
Kubernetes クラスターのコントロール プレーンは次のサービスで構成されます。
- API サーバー
- バッキング ストア
- スケジューラ
- コントローラー マネージャー
- クラウド コントローラー マネージャー
API サーバーとは
API サーバーは、Kubernetes クラスターのコントロール プレーンのフロント エンドと考えることができます。 Kubernetes 内のコンポーネント間のすべての通信は、この API を介して行われます。
たとえば、ユーザーは、Kubernetes クラスターの API サーバーに対してコマンドを実行できる kubectl
というコマンドライン アプリを使用します。 この API を提供するコンポーネントは kube-apiserver
と呼ばれます。このコンポーネントの複数のインスタンスをデプロイして、クラスターでのスケーリングをサポートすることができます。
この API では、コマンドまたは YAML ベースの構成ファイルを送信できる RESTful API が公開されています。 YAML は、プログラミング言語用の人間が判読できるデータ シリアル化標準です。 YAML ファイルを使用すると、Kubernetes クラスター内のすべてのオブジェクトの意図された状態を定義できます。
たとえば、あなたは、クラスター内のアプリのインスタンス数を増やす必要があるとします。 あなたは YAML ベースのファイルを使用して新しい状態を定義し、このファイルを API サーバーに送信します。 API サーバーは、構成を検証して、それをクラスターに保存し、最終的に構成された引き上げをアプリ デプロイで実行します。
バッキング ストアとは
バッキング ストアは、Kubernetes クラスターが自身の完全な構成を内部に保存する永続的なストレージです。 Kubernetes により、高可用性を備えた分散型で信頼性が高い etcd
というキー値ストアが使用されます。 このキー値ストアには、クラスター内のすべてのオブジェクトについて現在の状態と必要な状態が格納されます。
運用環境の Kubernetes クラスターで高可用性を実現するには、Kubernetes の公式ガイダンスにおいて、etcd
データベースのインスタンスを 3 個から 5 個使用することになっています。
Note
etcd
は、データ バックアップの責任を負いません。 etcd
データをバックアップするための効果的なバックアップ計画を確実に実行するのは、あなたの責任です。
スケジューラとは
スケジューラは、すべてのノードにわたってワークロードの割り当てを担当するコンポーネントです。 スケジューラによって、クラスターで新しく作成されたコンテナーの有無が監視され、それらのコンテナーがノードに割り当てられます。
コントローラー マネージャーとは
コントローラー マネージャーにより、API サーバーを介してクラスター用に構成されたコントローラーが起動され、監視されます。
Kubernetes ではコントローラーを使用して、クラスター内のオブジェクトの状態が追跡されます。 各コントローラーは、クラスター内のイベントを監視してそれに応答している間、終了しないループで実行されます。 たとえば、ノード、コンテナー、エンドポイントを監視するコントローラーがあります。
コントローラーは、API サーバーと通信することでオブジェクトの状態を判断します。 現在の状態がオブジェクトの望ましい状態と異なる場合、コントローラーは望ましい状態を実現するためのアクションを実行します。
クラスター内で実行中の 3 つのコンテナーの 1 つが応答しなくなり、障害が発生しているとします。 この場合、コントローラーによって、アプリが常に使用できる状態を確保するために新しいコンテナーを起動する必要があるかどうかが判断されます。 目的の状態が常に 3 つのコンテナーを実行することである場合、新しいコンテナーの実行がスケジュールされます。
クラウド コントローラー マネージャーとは
クラウド コントローラー マネージャーは、クラスターがクラウド環境で実行されている場合に、クラスター内の基盤となるクラウド テクノロジと統合されます。 これらのサービスの例として、ロード バランサー、キュー、ストレージがあります。
ノードで実行されるサービス
ワークロードの実行方法を制御する、Kubernetes ノードで実行されるサービスがいくつかあります。
Kubernetes ノードによって、次のサービスが実行されます。
- kubelet
- kube-proxy
- コンテナー ランタイム
kubelet とは
kubelet は、クラスター内の各ノードで実行されるエージェントで、API サーバーからの作業要求を監視します。 要求された作業単位が実行されていて正常であることを確認します。
kubelet でノードを監視し、各ノードにスケジュールされているコンテナーが想定どおりに実行されるようにします。 kubelet は、Kubernetes によって作成されたコンテナーのみを管理します。 現在のノードで作業を実行できない場合、他のノードで実行するように作業が再スケジュールされることはありません。
kube-proxy とは
kube-proxy コンポーネントはローカル クラスター ネットワークを担当し、各ノードで実行されます。 これにより、各ノードが一意の IP アドレスを確実に持つようになります。 また、iptables と IPVS を使用したトラフィックのルーティングと負荷分散を処理する規則も実装されます。
このプロキシ自体は DNS サービスを提供しません。 CoreDNS に基づく DNS クラスター アドオンが推奨され、既定でインストールされます。
コンテナー ランタイムとは
コンテナー ランタイムは、Kubernetes クラスター上でコンテナーを実行する基盤のソフトウェアです。 Runtime は、コンテナー イメージのフェッチ、開始、および停止を担当します。 Kubernetes は、Docker、containerd、rkt、CRI-O、frakti など、いくつかのコンテナー ランタイムをサポートしています。 多くのコンテナー ランタイムの種類のサポートは、Container Runtime Interface (CRI) に基づいています。 CRI は、kubelet と利用可能なコンテナー ランタイムとの通信を可能にするプラグインの設計です。
AKS の既定のコンテナー ランタイムは、業界標準のコンテナー ランタイムである containerd です。
Kubernetes クラスターとやり取りする
Kubernetes には、クラスターを管理するための kubectl
という名前のコマンドライン ツールが用意されています。 コマンドをクラスターのコントロール プレーンに送信するか、API サーバーを介してすべての Kubernetes オブジェクトに関する情報をフェッチするには、kubectl
を使用します。
kubectl
によって、次の構成情報を含む構成ファイルが使用されます。
- Cluster 構成では、クラスター名、証明書情報、クラスターに関連付けられたサービス API エンドポイントが指定されます。 この定義により、単一のワークステーションから複数のクラスターに接続できるようになります。
- User 構成では、ユーザーと、構成されたクラスターにアクセスするときのユーザーのアクセス許可レベルが指定されます。
- Context 構成では、フレンドリ名を使用してクラスターとユーザーがグループ化されます。 たとえば、開発クラスターと運用クラスターを識別するための "dev-cluster" と "prod-cluster" があるとします。
コマンドライン構文の一部として正しいコンテキストを提供することにより、複数のクラスターに接続するように kubectl
を構成できます。
Kubernetes のポッド
ポッドは、Kubernetes で実行されているアプリの 1 つのインスタンスを表します。 Kubernetes で実行するワークロードは、コンテナー化されたアプリです。 Docker 環境とは異なり、Kubernetes でコンテナーを直接実行することはできません。 コンテナーを、ポッドと呼ばれる Kubernetes オブジェクトにパッケージ化します。 ポッドは、Kubernetes で作成できる最小のオブジェクトです。
1 つのポッドで 1 または複数のコンテナーのグループを保持することができます。 ただし、通常、ポッドに同じアプリが複数含まれることはありません。
ポッドには、共有ストレージとネットワーク構成に関する情報、およびパッケージ化されたコンテナーの実行方法に関する仕様が含まれます。 ポッド テンプレートを使用すると、クラスターで実行されるポッドに関する情報を定義できます。 ポッド テンプレートは、ポッドのデプロイを管理するために他のオブジェクトに含めて再利用する YAML コード ファイルです。
たとえば、Web サイトを Kubernetes クラスターにデプロイするとします。 この場合、アプリのコンテナー イメージと構成を指定するポッド定義ファイルを作成します。 次に、ポッド定義ファイルを Kubernetes にデプロイします。
Web アプリがソリューションの唯一のコンポーネントとして Web サイトを持つことは、ほとんどありません。 通常、Web アプリには何らかの種類のデータストアとその他のサポート要素があります。 Kubernetes のポッドに複数のコンテナーを含めることもできます。
サイトでデータベースを使用しているとします。 Web サイトはメイン コンテナーにパッケージされ、データベースはサポート コンテナーにパッケージされています。 複数のコンテナーが環境を介して相互に通信します。 コンテナーには、ホスト OS、ネットワーク スタック、カーネル名前空間、共有メモリ、ストレージ ボリュームのサービスが含まれます。 ポッドは、これらすべてのサービスをアプリに提供するサンドボックス環境です。 ポッドでは、コンテナーに割り当てられた IP アドレスを共有することもできます。
多くのノード上で実行されるポッドが多数作成されることがあるため、その場合は識別が困難になる可能性があります。 ポッドを定義するときに指定した文字列ラベルを使用して、ポッドを認識し、グループ化することができます。
Kubernetes のポッドのライフサイクル
Kubernetes のポッドには、ポッドのデプロイ、実行、更新の方法に影響する個別のライフ サイクルがあります。 まず、ポッドの YAML マニフェストをクラスターに送信します。 マニフェスト ファイルが発行されてクラスターに永続化された後、それによってポッドの望ましい状態が定義されます。 スケジューラは、ポッドを実行するのに十分なリソースを持つ正常なノードにポッドをスケジュールします。
ポッドのライフサイクルのフェーズを次に示します。
フェーズ | 説明 |
---|---|
保留中 | ポッドはクラスターを受け入れますが、クラスター内のすべてのコンテナーが設定済みで実行する準備ができているわけではありません。 保留状態は、ポッドがスケジュールされるのを待機している時間と、コンテナー イメージのダウンロードに費やされる時間を意味しています。 |
実行中 | ポッド内のすべてのリソースが準備できた後、ポッドは実行中状態に遷移します。 |
成功 | ポッドが目的のタスクを完了し、実行が正常に終了した後、ポッドが成功状態に遷移します。 |
失敗 | ポッドが失敗するのにはさまざまな理由があります。 ポッド内のコンテナーで障害が発生し、そのために他のすべてのコンテナーが終了した可能性や、ポッド コンテナーの準備中にイメージが見つからなかった可能性があります。 このような場合、ポッドは失敗状態に移行する場合があります。 ポッドは、保留状態または実行状態から失敗状態に移行することがあります。 特定のエラーによってポッドが保留中状態に戻ることもあります。 |
Unknown | ポッドの状態を特定できない場合、ポッドは不明状態になります。 |
ポッドは、コントローラー、コントロール プレーン、またはユーザーによって明示的に削除されるまで、クラスター上に保持されます。 ポッドが削除されると、その直後に新しいポッドが作成されます。 新しいポッドは、ポッド マニフェストに基づくまったく新しいインスタンスと見なされます。 正確なコピーではないので、削除されたポッドとは異なります。
ポッドの状態または動的に割り当てられた構成はクラスターに保存されません。 たとえば、ポッドの ID または IP アドレスは保存されません。 この側面は、ポッドのデプロイ方法と、アプリの設計方法に影響します。 たとえば、ポッドの割り当て済の IP アドレスに依存することができません。
コンテナーの状態
フェーズは、ポッドがライフサイクル内でどの状態にあるかの概要です。 ポッドを調べるとき、ポッド内のコンテナーを追跡するためにクラスターで使用される状態は 3 つあります。
State | 説明 |
---|---|
待機中 | コンテナーの既定の状態です。コンテナーが実行中または終了以外の状態でもあります。 |
実行中 | コンテナーは予期したとおりに問題なく実行されています。 |
終了 | コンテナーが実行されなくなりました。 理由は、すべてのタスクが完了したか、または何らかの理由でコンテナーが失敗したことです。 理由と終了コードは、両方のケースのデバッグに利用できます。 |