Pod
Pod は、Kubernetes内で作成・管理できるコンピューティングの最小のデプロイ可能なユニットです。
Pod (Podという名前は、たとえばクジラの群れ(pod of whales)やえんどう豆のさや(pea pod)などの表現と同じような意味です)は、1つまたは複数のコンテナ のグループであり、ストレージやネットワークの共有リソースを持ち、コンテナの実行方法に関する仕様を持っています。同じPodに含まれるリソースは、常に同じ場所で同時にスケジューリングされ、共有されたコンテキストの中で実行されます。Podはアプリケーションに特化した「論理的なホスト」をモデル化します。つまり、1つのPod内には、1つまたは複数の比較的密に結合されたアプリケーションコンテナが含まれます。クラウド外の文脈で説明すると、アプリケーションが同じ物理ホストや同じバーチャルマシンで実行されることが、クラウドアプリケーションの場合には同じ論理ホスト上で実行されることに相当します。
アプリケーションコンテナと同様に、Podでも、Podのスタートアップ時に実行されるinitコンテナ を含めることができます。また、クラスターで利用できる場合には、エフェメラルコンテナ を注入してデバッグすることもできます。
Podとは何か?
備考: KubernetesはDockerだけでなく複数の
コンテナランタイム をサポートしていますが、
Docker が最も一般的に知られたランタイムであるため、Docker由来の用語を使ってPodを説明するのが理解の助けとなります。
Podの共有コンテキストは、Dockerコンテナを隔離するのに使われているのと同じ、Linuxのnamespaces、cgroups、場合によっては他の隔離技術の集合を用いて作られます。Podのコンテキスト内では、各アプリケーションが追加の準隔離技術を適用することもあります。
Dockerの概念を使って説明すると、Podは共有の名前空間と共有ファイルシステムのボリュームを持つDockerコンテナのグループに似ています。
Podを使用する 以下は、nginx:1.14.2イメージが実行されるコンテナからなるPodの例を記載しています。
apiVersion : v1
kind : Pod
metadata :
name : nginx
spec :
containers :
- name : nginx
image : nginx:1.14.2
ports :
- containerPort : 80
上記のようなPodを作成するには、以下のコマンドを実行します:
kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml
Podは通常、直接作成されず、ワークロードリソースで作成されます。ワークロードリソースでPodを作成する方法の詳細については、Podを利用する を参照してください。
Podを管理するためのワークロードリソース 通常、たとえ単一のコンテナしか持たないシングルトンのPodだとしても、自分でPodを直接作成する必要はありません。その代わりに、Deployment やJob などのワークロードリソースを使用してPodを作成します。もしPodが状態を保持する必要がある場合は、StatefulSet リソースを使用することを検討してください。
Kubernetesクラスター内のPodは、主に次の2種類の方法で使われます。
単一のコンテナを稼働させるPod 。「1Pod1コンテナ」構成のモデルは、Kubernetesでは最も一般的なユースケースです。このケースでは、ユーザーはPodを単一のコンテナのラッパーとして考えることができます。Kubernetesはコンテナを直接管理するのではなく、Podを管理します。
協調して稼働させる必要がある複数のコンテナを稼働させるPod 。単一のPodは、密に結合してリソースを共有する必要があるような、同じ場所で稼働する複数のコンテナからなるアプリケーションをカプセル化することもできます。これらの同じ場所で稼働するコンテナ群は、単一のまとまりのあるサービスのユニットを構成します。たとえば、1つのコンテナが共有ボリュームからファイルをパブリックに配信し、別のサイドカー コンテナがそれらのファイルを更新するという構成が考えられます。Podはこれらの複数のコンテナ、ストレージリソース、一時的なネットワークIDなどを、単一のユニットとしてまとめます。
備考: 複数のコンテナを同じ場所で同時に管理するように単一のPod内にグループ化するのは、比較的高度なユースケースです。このパターンを使用するのは、コンテナが密に結合しているような特定のインスタンス内でのみにするべきです。
各Podは、与えられたアプリケーションの単一のインスタンスを稼働するためのものです。もしユーザーのアプリケーションを水平にスケールさせたい場合(例: 複数インスタンスを稼働させる)、複数のPodを使うべきです。1つのPodは各インスタンスに対応しています。Kubernetesでは、これは一般的にレプリケーション と呼ばれます。レプリケーションされたPodは、通常ワークロードリソースと、それに対応するコントローラー によって、作成・管理されます。
Kubernetesがワークロードリソースとそのコントローラーを活用して、スケーラブルで自動回復するアプリケーションを実装する方法については、詳しくはPodとコントローラー を参照してください。
Podが複数のコンテナを管理する方法 Podは、まとまりの強いサービスのユニットを構成する、複数の協調する(コンテナとして実行される)プロセスをサポートするために設計されました。単一のPod内の複数のコンテナは、クラスター内の同じ物理または仮想マシン上で、自動的に同じ場所に配置・スケジューリングされます。コンテナ間では、リソースや依存関係を共有したり、お互いに通信したり、停止するときにはタイミングや方法を協調して実行できます。
たとえば、あるコンテナが共有ボリューム内のファイルを配信するウェブサーバーとして動作し、別の「サイドカー」コンテナがリモートのリソースからファイルをアップデートするような構成が考えられます。この構成を以下のダイアグラムに示します。
Podによっては、appコンテナ に加えてinitコンテナ を持っている場合があります。initコンテナはappコンテナが起動する前に実行・完了するコンテナです。
Podは、Podを構成する複数のコンテナに対して、ネットワーク とストレージ の2種類の共有リソースを提供します。
Podを利用する 通常Kubernetesでは、たとえ単一のコンテナしか持たないシングルトンのPodだとしても、個別のPodを直接作成することはめったにありません。その理由は、Podがある程度一時的で使い捨てできる存在として設計されているためです。Podが作成されると(あなたが直接作成した場合でも、コントローラー が間接的に作成した場合でも)、新しいPodはクラスター内のノード 上で実行されるようにスケジューリングされます。Podは、実行が完了するか、Podオブジェクトが削除されるか、リソース不足によって強制退去 されるか、ノードが停止するまで、そのノード上にとどまります。
備考: Pod内のコンテナの再起動とPodの再起動を混同しないでください。Podはプロセスではなく、コンテナが実行するための環境です。Podは削除されるまでは残り続けます。
Podオブジェクトのためのマニフェストを作成したときは、指定したPodの名前が有効なDNSサブドメイン名 であることを確認してください。
Pod OS
FEATURE STATE:
GA since Kubernetes v1.25
.spec.os.nameフィールドでwindowsかlinuxのいずれかを設定し、Podを実行させたいOSを指定する必要があります。Kubernetesは今のところ、この2つのOSだけサポートしています。将来的には増える可能性があります。
Kubernetes v1.37では、このフィールドに設定した値はPodのスケジューリング に影響を与えません。.spec.os.nameを設定することで、Pod OSに権限を認証することができ、バリデーションにも使用されます。kubeletが実行されているノードのOSが、指定されたPod OSと異なる場合、kubeletはPodの実行を拒否します。
Podセキュリティの標準 もこのフィールドを使用し、指定したOSと関係ないポリシーの適用を回避しています。
Podとコンテナコントローラー ワークロードリソースは、複数のPodを作成・管理するために利用できます。リソースに対応するコントローラーが、複製やロールアウトを扱い、Podの障害時には自動回復を行います。たとえば、あるノードに障害が発生した場合、コントローラーはそのノードの動作が停止したことを検知し、代わりのPodを作成します。そして、スケジューラーが代わりのPodを健全なノード上に配置します。
以下に、1つ以上のPodを管理するワークロードリソースの一例をあげます。
Podテンプレート workload リソース向けのコントローラーは、PodをPodテンプレート を元に作成し、あなたの代わりにPodを管理してくれます。
PodTemplateはPodを作成するための仕様で、Deployment 、Job 、DaemonSet などのワークロードリソースの中に含まれています。
ワークロードリソースに対応する各コントローラーは、ワークロードオブジェクト内にあるPodTemplateを使用して実際のPodを作成します。PodTemplateは、アプリを実行するために使われるワークロードリソースがどんな種類のものであれ、その目的の状態の一部を構成するものです。
以下は、単純なJobのマニフェストの一例で、1つのコンテナを実行するtemplateがあります。Pod内のコンテナはメッセージを出力した後、一時停止します。
apiVersion : batch/v1
kind : Job
metadata :
name : hello
spec :
template :
# これがPodテンプレートです
spec :
containers :
- name : hello
image : busybox:1.28
command : [ 'sh' , '-c' , 'echo "Hello, Kubernetes!" && sleep 3600' ]
restartPolicy : OnFailure
# Podテンプレートはここまでです
Podテンプレートを修正するか新しいPodに切り替えたとしても、すでに存在するPodには直接の影響はありません。ワークロードリソース内のPodテンプレートを変更すると、そのリソースは更新されたテンプレートを使用して代わりとなるPodを作成する必要があります。
たとえば、StatefulSetコントローラーは、各StatefulSetごとに、実行中のPodが現在のPodテンプレートに一致することを保証します。Podテンプレートを変更するためにStatefulSetを編集すると、StatefulSetは更新されたテンプレートを元にした新しいPodを作成するようになります。最終的に、すべての古いPodが新しいPodで置き換えられ、更新は完了します。
各ワークロードリソースは、Podテンプレートへの変更を処理するための独自のルールを実装しています。特にStatefulSetについて更に詳しく知りたい場合は、StatefulSetの基本チュートリアル内のアップデート戦略 を読んでください。
ノード上では、kubelet はPodテンプレートに関する詳細について監視や管理を直接行うわけではありません。こうした詳細は抽象化されています。こうした抽象化や関心の分離のおかげでシステムのセマンティクスが単純化され、既存のコードを変更せずにクラスターの動作を容易に拡張できるようになっているのです。
Podの更新と取替 前のセクションで述べたように、ワークロードリソースのPodテンプレートが変更されると、コントローラーは既存のPodを更新したりパッチを適用したりするのではなく、更新されたテンプレートに基づいて新しいPodを作成します。
KubernetesはPodを直接管理することを妨げません。実行中のPodの一部のフィールドをその場で更新することが可能です。しかし、patch とreplace といった、Podのアップデート操作にはいくつかの制限があります:
Podのメタデータのほとんどは固定されたものです。たとえばnamespace、name、uidまたはcreationTimestampフィールドは変更できません。generationフィールドは特別で、現在の値を増加させる更新のみを受け付けます。
metadata.deletionTimestampが設定されている場合、metadata.finalizersリストに新しい項目を追加することはできません。
Podの更新ではspec.containers[*].image、spec.initContainers[*].image、spec.activeDeadlineSecondsまたはspec.tolerations以外のフィールドを変更してはなりません。
spec.tolerationsについては新しい項目のみを追加することができます。
spec.activeDeadlineSecondsフィールドを更新する場合、2種類の更新が可能です:
未割り当てのフィールドに正の数を設定する
現在の値から負の数でない、より小さい数に更新する
リソースの共有と通信 Podは、データの共有と構成するコンテナ間での通信を可能にします。
Pod内のストレージ Podでは、共有ストレージであるボリューム の集合を指定できます。Pod内のすべてのコンテナは共有ボリュームにアクセスできるため、それら複数のコンテナでデータを共有できるようになります。また、ボリュームを利用すれば、Pod内のコンテナの1つに再起動が必要になった場合にも、Pod内の永続化データを保持し続けられるようにできます。Kubernetesの共有ストレージの実装方法とPodで利用できるようにする方法に関するさらに詳しい情報は、ストレージ を読んでください。
Podネットワーク 各Podには、各アドレスファミリーごとにユニークなIPアドレスが割り当てられます。Pod内のすべてのコンテナは、IPアドレスとネットワークポートを含むネットワーク名前空間を共有します。Podの中では(かつその場合にのみ )、そのPod内のコンテナはlocalhostを使用して他のコンテナと通信できます。Podの内部にあるコンテナがPodの外部にある エンティティと通信する場合、(ポートなどの)共有ネットワークリソースの使い方をコンテナ間で調整しなければなりません。Pod内では、コンテナはIPアドレスとポートの空間を共有するため、localhostで他のコンテナにアクセスできます。また、Pod内のコンテナは、SystemVのセマフォやPOSIXの共有メモリなど、標準のプロセス間通信を使って他のコンテナと通信することもできます。異なるPod内のコンテナは異なるIPアドレスを持つため、特別な設定をしない限り、OSレベルIPCで通信することはできません。異なるPod上で実行中のコンテナ間でやり取りをしたい場合は、IPネットワークを使用して通信できます。
Pod内のコンテナは、システムのhostnameがPodに設定したnameと同一であると考えます。ネットワークについての詳しい情報は、ネットワーク で説明しています。
コンテナの特権モード Linuxでは、Pod内のどんなコンテナも、privilegedフラグをコンテナのspecのsecurity context に設定することで、特権モード(privileged mode)を有効にできます。これは、ネットワークスタックの操作やハードウェアデバイスへのアクセスなど、オペレーティングシステムの管理者の権限が必要なコンテナの場合に役に立ちます。
WindowsHostProcessContainers機能を有効にしたクラスターの場合、Pod仕様のsecurityContextにwindowsOptions.hostProcessフラグを設定することで、Windows HostProcess Pod を作成することが可能です。これらのPod内のすべてのコンテナは、Windows HostProcessコンテナとして実行する必要があります。HostProcess Podはホスト上で直接実行され、Linuxの特権コンテナで行われるような管理作業を行うのにも使用できます。
備考: この設定を有効にするには、
コンテナランタイム が特権コンテナの概念をサポートしていなければなりません。
static Pod static Pod は、APIサーバー には管理されない、特定のノード上でkubeletデーモンによって直接管理されるPodのことです。大部分のPodはコントロールプレーン(たとえばDeployment )によって管理されますが、static Podの場合はkubeletが各static Podを直接管理します(障害時には再起動します)。
static Podは常に特定のノード上の1つのKubelet に紐付けられます。static Podの主な用途は、セルフホストのコントロールプレーンを実行すること、言い換えると、kubeletを使用して個別のコントロールプレーンコンポーネント を管理することです。
kubeletは自動的にKubernetes APIサーバー上に各static Podに対応するミラーPod の作成を試みます。つまり、ノード上で実行中のPodはAPIサーバー上でも見えるようになるけれども、APIサーバー上から制御はできないということです。
コンテナのProbe Probe はkubeletがコンテナに対して行う定期診断です。診断を実行するために、kubeletはさまざまなアクションを実行できます:
ExecAction (コンテナランタイムの助けを借りて実行)
TCPSocketAction (kubeletにより直接チェック)
HTTPGetAction (kubeletにより直接チェック)
更に詳しく知りたい場合は、PodのライフサイクルドキュメントにあるProbe を読んでください。
次の項目
Kubernetesが共通のPod APIを他のリソース内(たとえばStatefulSet やDeployment など)にラッピングしている理由の文脈を理解するためには、Kubernetes以前から存在する以下のような既存技術について読むのが助けになります。
1 - Podのライフサイクル
このページではPodのライフサイクルについて説明します。Podは定義されたライフサイクルに従い Pendingフェーズ から始まり、少なくとも1つのプライマリーコンテナが正常に開始した場合はRunningを経由し、次に失敗により終了したコンテナの有無に応じて、SucceededまたはFailedフェーズを経由します。
Podの実行中、kubeletはコンテナを再起動して、ある種の障害を処理できます。Pod内で、Kubernetesはさまざまなコンテナのステータス を追跡して、回復させるためのアクションを決定します。
Kubernetes APIでは、Podには仕様と実際のステータスの両方があります。Podオブジェクトのステータスは、PodのCondition のセットで構成されます。カスタムのReadiness情報 をPodのConditionデータに挿入することもできます。
Podはその生存期間に1回だけスケジューリング されます。PodがNodeにスケジュール(割り当て)されると、Podは停止または終了 するまでそのNode上で実行されます。
Podのライフタイム 個々のアプリケーションコンテナと同様に、Podは(永続的ではなく)比較的短期間の存在と捉えられます。Podが作成されると、一意のID(UID )が割り当てられ、(再起動ポリシーに従って)終了または削除されるまでNodeで実行されるようにスケジュールされます。
ノード が停止した場合、そのNodeにスケジュールされたPodは、タイムアウト時間の経過後に削除 されます。
Pod自体は、自己修復しません。Podがnode にスケジュールされ、その後に失敗した場合、Podは削除されます。同様に、リソースの不足またはNodeのメンテナンスによりPodはNodeから立ち退きます。Kubernetesは、比較的使い捨てのPodインスタンスの管理作業を処理する、controller と呼ばれる上位レベルの抽象化を使用します。
特定のPod(UIDで定義)は新しいNodeに"再スケジュール"されません。代わりに、必要に応じて同じ名前で、新しいUIDを持つ同一のPodに置き換えることができます。
volume など、Podと同じ存続期間を持つものがあると言われる場合、それは(そのUIDを持つ)Podが存在する限り存在することを意味します。そのPodが何らかの理由で削除された場合、たとえ同じ代替物が作成されたとしても、関連するもの(例えばボリューム)も同様に破壊されて再作成されます。
Podの図
file puller(ファイル取得コンテナ)とWebサーバーを含むマルチコンテナのPod。コンテナ間の共有ストレージとして永続ボリュームを使用しています。
Podのフェーズ Podのstatus項目はPodStatus オブジェクトで、それはphaseのフィールドがあります。
Podのフェーズは、そのPodがライフサイクルのどの状態にあるかを、簡単かつ高レベルにまとめたものです。このフェーズはコンテナやPodの状態を包括的にまとめることを目的としたものではなく、また包括的なステートマシンでもありません。
Podの各フェーズの値と意味は厳重に守られています。ここに記載されているもの以外にphaseの値は存在しないと思ってください。
これらがphaseの取りうる値です。
値
概要
Pending
PodがKubernetesクラスターによって承認されましたが、1つ以上のコンテナがセットアップされて稼働する準備ができていません。これには、スケジュールされるまでの時間と、ネットワーク経由でイメージをダウンロードするための時間などが含まれます。
Running
PodがNodeにバインドされ、すべてのコンテナが作成されました。少なくとも1つのコンテナがまだ実行されているか、開始または再起動中です。
Succeeded
Pod内のすべてのコンテナが正常に終了し、再起動されません。
Failed
Pod内のすべてのコンテナが終了し、少なくとも1つのコンテナが異常終了しました。つまり、コンテナはゼロ以外のステータスで終了したか、システムによって終了されました。
Unknown
何らかの理由によりPodの状態を取得できませんでした。このフェーズは通常はPodのホストとの通信エラーにより発生します。
備考: Podの削除中に、kubectlコマンドには
Terminatingが出力されることがあります。この
Terminatingステータスは、Podのフェーズではありません。Podには、正常に終了するための期間を与えられており、デフォルトは30秒です。
--forceフラグを使用して、
Podを強制的に削除する ことができます。
Nodeが停止するか、クラスターの残りの部分から切断された場合、Kubernetesは失われたNode上のすべてのPodのPhaseをFailedに設定するためのポリシーを適用します。
コンテナのステータス Pod全体のフェーズ と同様に、KubernetesはPod内の各コンテナの状態を追跡します。container lifecycle hooks を使用して、コンテナのライフサイクルの特定のポイントで実行するイベントをトリガーできます。
Podがscheduler によってNodeに割り当てられると、kubeletはcontainer runtime を使用してコンテナの作成を開始します。コンテナの状態はWaiting、RunningまたはTerminatedの3ついずれかです。
Podのコンテナの状態を確認するにはkubectl describe pod [POD_NAME]のコマンドを使用します。Pod内のコンテナごとにStateの項目として表示されます。
各状態の意味は次のとおりです。
WaitingコンテナがRunningまたはTerminatedのいずれの状態でもない場合コンテナはWaitingの状態になります。Waiting状態のコンテナは引き続きコンテナイメージレジストリからイメージを取得したりSecret を適用したりするなど必要な操作を実行します。Waiting状態のコンテナを持つPodに対してkubectlコマンドを使用すると、そのコンテナがWaitingの状態である理由の要約が表示されます。
RunningRunning状態はコンテナが問題なく実行されていることを示します。postStartフックが構成されていた場合、それはすでに実行が完了しています。Running状態のコンテナを持つPodに対してkubectlコマンドを使用すると、そのコンテナがRunning状態になった時刻が表示されます。
TerminatedTerminated状態のコンテナは実行されて、完了したときまたは何らかの理由で失敗したことを示します。Terminated状態のコンテナを持つPodに対してkubectlコマンドを使用すると、いずれにせよ理由と終了コード、コンテナの開始時刻と終了時刻が表示されます。
コンテナがTerminatedに入る前にpreStopフックがあれば実行されます。
コンテナの再起動ポリシー Podのspecには、Always、OnFailure、またはNeverのいずれかの値を持つrestartPolicyフィールドがあります。デフォルト値はAlwaysです。
restartPolicyは、Pod内のすべてのコンテナに適用されます。restartPolicyは、同じNode上のkubeletによるコンテナの再起動のみを参照します。Pod内のコンテナが終了した後、kubeletは5分を上限とする指数バックオフ遅延(10秒、20秒、40秒...)でコンテナを再起動します。コンテナが10分間実行されると、kubeletはコンテナの再起動バックオフタイマーをリセットします。
PodのCondition PodにはPodStatusがあります。それにはPodが成功したかどうかの情報を持つPodCondition の配列が含まれています。kubeletは、下記のPodConditionを管理します:
PodScheduled: PodがNodeにスケジュールされました。
PodHasNetwork: (アルファ版機能; 明示的に有効 にしなければならない) Podサンドボックスが正常に作成され、ネットワークの設定が完了しました。
ContainersReady: Pod内のすべてのコンテナが準備できた状態です。
Initialized: すべてのInitコンテナ が正常に終了しました。
Ready: Podはリクエストを処理でき、一致するすべてのサービスの負荷分散プールに追加されます。
フィールド名
内容
type
このPodの状態の名前です。
status
その状態が適用可能かどうか示します。可能な値は"True"、"False"、"Unknown"のうちのいずれかです。
lastProbeTime
Pod Conditionが最後に確認されたときのタイムスタンプが表示されます。
lastTransitionTime
最後にPodのステータスの遷移があった際のタイムスタンプが表示されます。
reason
最後の状態遷移の理由を示す、機械可読のアッパーキャメルケースのテキストです。
message
ステータスの遷移に関する詳細を示す人間向けのメッセージです。
PodのReadiness
FEATURE STATE:
GA since Kubernetes v1.14
追加のフィードバックやシグナルをPodStatus:Pod readiness に注入できるようにします。これを使用するには、PodのspecでreadinessGatesを設定して、kubeletがPodのReadinessを評価する追加の状態のリストを指定します。
ReadinessゲートはPodのstatus.conditionsフィールドの現在の状態によって決まります。KubernetesがPodのstatus.conditionsフィールドでそのような状態を発見できない場合、ステータスはデフォルトでFalseになります。
以下はその例です。
Kind : Pod
...
spec :
readinessGates :
- conditionType : "www.example.com/feature-1"
status :
conditions :
- type : Ready # これはビルトインのPodCondition
status : "False"
lastProbeTime : null
lastTransitionTime : 2018-01-01T00:00:00Z
- type : "www.example.com/feature-1" # 追加のPodCondition
status : "False"
lastProbeTime : null
lastTransitionTime : 2018-01-01T00:00:00Z
containerStatuses :
- containerID : docker://abcd...
ready : true
...
PodのConditionは、Kubernetesのlabel key format に準拠している必要があります。
PodのReadinessの状態 kubectl patchコマンドはオブジェクトステータスのパッチ適用をまだサポートしていません。Podにこれらのstatus.conditionsを設定するには、アプリケーションとoperators はPATCHアクションを使用する必要があります。Kubernetes client library を使用して、PodのReadinessのためにカスタムのPodのConditionを設定するコードを記述できます。
カスタムのPodのConditionが導入されるとPodは次の両方の条件に当てはまる場合のみ 準備できていると評価されます:
Pod内のすべてのコンテナが準備完了している。
ReadinessGatesで指定された条件が全てTrueである。
Podのコンテナは準備完了ですが、少なくとも1つのカスタムのConditionが欠落しているか「False」の場合、kubeletはPodのCondition をContainersReadyに設定します。
PodのネットワークのReadiness
FEATURE STATE:
Alpha since Kubernetes v1.25
Podがノードにスケジュールされた後、kubeletによって承認され、任意のボリュームがマウントされる必要があります。これらのフェーズが完了すると、kubeletはコンテナランタイム(コンテナランタイムインターフェース(CRI) を使用)と連携して、ランタイムサンドボックスのセットアップとPodのネットワークを構成します。もしPodHasNetworkConditionフィーチャーゲート が有効になっている場合、kubeletは、Podがこの初期化の節目に到達したかどうかをPodのstatus.conditionsフィールドにあるPodHasNetwork状態を使用して報告します。
ネットワークが設定されたランタイムサンドボックスがPodにないことを検出すると、PodHasNetwork状態は、kubelet によってFalseに設定されます。これは、以下のシナリオで発生します:
Podのライフサイクルの初期で、kubeletがコンテナランタイムを使用してPodのサンドボックスのセットアップをまだ開始していないとき
Podのライフサイクルの後期で、Podのサンドボックスが以下のどちらかの原因で破壊された場合:
Podを退去させず、ノードが再起動する
コンテナランタイムの隔離に仮想マシンを使用している場合、Podサンドボックスの仮想マシンが再起動し、新しいサンドボックスと新しいコンテナネットワーク設定を作成する必要があります
ランタイムプラグインによるサンドボックスの作成とPodのネットワーク設定が正常に完了すると、kubeletによってPodHasNetwork状態がTrueに設定されます。PodHasNetwork状態がTrueに設定された後、kubeletはコンテナイメージの取得とコンテナの作成を開始することができます。
initコンテナを持つPodの場合、initコンテナが正常に完了すると(ランタイムプラグインによるサンドボックスの作成とネットワーク設定が正常に行われた後に発生)、kubeletはInitialized状態をTrueに設定します。initコンテナがないPodの場合、サンドボックスの作成およびネットワーク設定が開始する前にkubeletはInitialized状態をTrueに設定します。
コンテナのProbe Probe はkubelet により定期的に実行されるコンテナの診断です。診断を行うために、kubeletはコンテナ内でコードを実行するか、ネットワークリクエストします。
チェックのメカニズム probeを使ってコンテナをチェックする4つの異なる方法があります。
各probeは、この4つの仕組みのうち1つを正確に定義する必要があります:
exec
コンテナ内で特定のコマンドを実行します。コマンドがステータス0で終了した場合に診断を成功と見なします。
grpc
gRPC を使ってリモートプロシージャコールを実行します。
ターゲットは、gRPC health checks を実装する必要があります。
レスポンスのstatusがSERVINGの場合に診断を成功と見なします。
gRPCはアルファ版の機能のため、GRPCContainerProbeフィーチャーゲート が
有効の場合のみ利用可能です。
httpGet
PodのIPアドレスに対して、指定されたポートとパスでHTTP GETのリクエストを送信します。
レスポンスのステータスコードが200以上400未満の際に診断を成功とみなします。
tcpSocket
PodのIPアドレスに対して、指定されたポートでTCPチェックを行います。
そのポートが空いていれば診断を成功とみなします。
オープンしてすぐにリモートシステム(コンテナ)が接続を切断した場合、健全な状態としてカウントします。
Probeの結果 各Probe 次の3つのうちの一つの結果を持ちます:
Success
コンテナの診断が成功しました。
Failure
コンテナの診断が失敗しました。
Unknown
コンテナの診断自体が失敗しました(何も実行する必要はなく、kubeletはさらにチェックを行います)。
Probeの種類 kubeletは3種類のProbeを実行中のコンテナで行い、また反応することができます:
livenessProbe
コンテナが動いているかを示します。
livenessProbeに失敗すると、kubeletはコンテナを殺します、そしてコンテナはrestart policy に従います。
コンテナにlivenessProbeが設定されていない場合、デフォルトの状態はSuccessです。
readinessProbe
コンテナがリクエスト応答する準備ができているかを示します。
readinessProbeに失敗すると、エンドポイントコントローラーにより、ServiceからそのPodのIPアドレスが削除されます。
initial delay前のデフォルトのreadinessProbeの初期値はFailureです。
コンテナにreadinessProbeが設定されていない場合、デフォルトの状態はSuccessです。
startupProbe
コンテナ内のアプリケーションが起動したかどうかを示します。
startupProbeが設定された場合、完了するまでその他のすべてのProbeは無効になります。
startupProbeに失敗すると、kubeletはコンテナを殺します、そしてコンテナはrestart policy に従います。
コンテナにstartupProbeが設定されていない場合、デフォルトの状態はSuccessです。
livenessProbe、readinessProbeまたはstartupProbeを設定する方法の詳細については、Liveness Probe、Readiness ProbeおよびStartup Probeを使用する を参照してください。
livenessProbeをいつ使うべきか?
FEATURE STATE:
GA since Kubernetes v1.0
コンテナ自体に問題が発生した場合や状態が悪くなった際にクラッシュすることができればlivenessProbeは不要です。
この場合kubeletが自動でPodのrestartPolicyに基づいたアクションを実行します。
Probeに失敗したときにコンテナを殺したり再起動させたりするには、livenessProbeを設定しrestartPolicyをAlwaysまたはOnFailureにします。
readinessProbeをいつ使うべきか?
FEATURE STATE:
GA since Kubernetes v1.0
Probeが成功したときにのみPodにトラフィックを送信したい場合は、readinessProbeを指定します。
この場合readinessProbeはlivenessProbeと同じになる可能性がありますが、readinessProbeが存在するということは、Podがトラフィックを受けずに開始され、Probe成功が開始した後でトラフィックを受け始めることになります。
コンテナがメンテナンスのために停止できるようにするには、livenessProbeとは異なる、特定のエンドポイントを確認するreadinessProbeを指定することができます。
アプリがバックエンドサービスと厳密な依存関係にある場合、livenessProbeとreadinessProbeの両方を実装することができます。アプリ自体が健全であればlivenessProbeはパスしますが、readinessProbeはさらに、必要なバックエンドサービスが利用可能であるかどうかをチェックします。これにより、エラーメッセージでしか応答できないPodへのトラフィックの転送を避けることができます。
コンテナの起動中に大きなデータ、構成ファイル、またはマイグレーションを読み込む必要がある場合は、startupProbe を使用できます。ただし、失敗したアプリと起動データを処理中のアプリの違いを検出したい場合は、readinessProbeを使用した方が良いかもしれません。
備考: Podが削除されたときにリクエストを来ないようにするためには必ずしもreadinessProbeが必要というわけではありません。Podの削除時にはreadinessProbeが存在するかどうかに関係なくPodは自動的に自身をunreadyにします。Pod内のコンテナが停止するのを待つ間Podはunreadyのままです。
startupProbeをいつ使うべきか?
FEATURE STATE:
GA since Kubernetes v1.20
startupProbeは、サービスの開始に時間がかかるコンテナを持つPodに役立ちます。livenessProbeの間隔を長く設定するのではなく、コンテナの起動時に別のProbeを構成して、livenessProbeの間隔よりも長い時間を許可できます。
コンテナの起動時間が、initialDelaySeconds + failureThreshold x periodSecondsよりも長い場合は、livenessProbeと同じエンドポイントをチェックするためにstartupProbeを指定します。periodSecondsのデフォルトは10秒です。次に、failureThresholdをlivenessProbeのデフォルト値を変更せずにコンテナが起動できるように、十分に高い値を設定します。これによりデッドロックを防ぐことができます。
Podの終了 Podは、クラスター内のNodeで実行中のプロセスを表すため、不要になったときにそれらのプロセスを正常に終了できるようにすることが重要です(対照的なケースは、KILLシグナルで強制終了され、クリーンアップする機会がない場合)。
ユーザーは削除を要求可能であるべきで、プロセスがいつ終了するかを知ることができなければなりませんが、削除が最終的に完了することも保証できるべきです。ユーザーがPodの削除を要求すると、システムはPodが強制終了される前に意図された猶予期間を記録および追跡します。強制削除までの猶予期間がある場合、kubelet 正常な終了を試みます。
通常、コンテナランタイムは各コンテナのメインプロセスにTERMシグナルを送信します。多くのコンテナランタイムは、コンテナイメージで定義されたSTOPSIGNAL値を尊重し、TERMシグナルの代わりにこれを送信します。猶予期間が終了すると、プロセスにKILLシグナルが送信され、PodはAPI server から削除されます。プロセスの終了を待っている間にkubeletかコンテナランタイムの管理サービスが再起動されると、クラスターは元の猶予期間を含めて、最初からリトライされます。
フローの例は下のようになります。
ユーザーがデフォルトの猶予期間(30秒)でPodを削除するためにkubectlコマンドを送信する。
API server内のPodは、猶予期間を越えるとPodが「死んでいる」と見なされるように更新される。
削除中のPodに対してkubectl describeコマンドを使用すると、Podは「終了中」と表示される。
Podが実行されているNode上で、Podが終了しているとマークされている(正常な終了期間が設定されている)とkubeletが認識するとすぐに、kubeletはローカルでPodの終了プロセスを開始します。
Pod内のコンテナの1つがpreStopフック を定義している場合は、コンテナの内側で呼び出される。猶予期間が終了した後もpreStopフックがまだ実行されている場合は、一度だけ猶予期間を延長される(2秒)。
備考: preStopフックが完了するまでにより長い時間が必要な場合は、terminationGracePeriodSecondsを変更する必要があります。
kubeletはコンテナランタイムをトリガーして、コンテナ内のプロセス番号1にTERMシグナルを送信する。
備考: Pod内のすべてのコンテナが同時にTERMシグナルを受信するわけではなく、シャットダウンの順序が問題になる場合はそれぞれにpreStopフックを使用して同期することを検討する。
kubeletが正常な終了を開始すると同時に、コントロールプレーンは、終了中のPodをEndpointSlice(およびEndpoints)オブジェクトから削除します。これらのオブジェクトは、selector が設定されたService を表します。ReplicaSets とその他のワークロードリソースは、終了中のPodを有効なサービス中のReplicaSetとして扱いません。ゆっくりと終了するPodは、(サービスプロキシのような)ロードバランサーが終了猶予期間が始まる とエンドポイントからそれらのPodを削除するので、トラフィックを継続して処理できません。
猶予期間が終了すると、kubeletは強制削除を開始する。コンテナランタイムは、Pod内でまだ実行中のプロセスにSIGKILLを送信する。kubeletは、コンテナランタイムが非表示のpauseコンテナを使用している場合、そのコンテナをクリーンアップします。
kubeletは猶予期間を0(即時削除)に設定することでAPI server上のPodの削除を終了する。
API serverはPodのAPIオブジェクトを削除し、クライアントからは見えなくなります。
Podの強制削除
注意: 強制削除は、Podによっては潜在的に危険な場合があるため、慎重に実行する必要があります。
デフォルトでは、すべての削除は30秒以内に正常に行われます。kubectl delete コマンドは、ユーザーがデフォルト値を上書きして独自の値を指定できるようにする --grace-period=<seconds> オプションをサポートします。
--grace-periodを0に設定した場合、PodはAPI serverから即座に強制的に削除されます。PodがNode上でまだ実行されている場合、その強制削除によりkubeletがトリガーされ、すぐにクリーンアップが開始されます。
備考: 強制削除を実行するために --grace-period=0 と共に --force というフラグを追加で指定する必要があります。
強制削除が実行されると、API serverは、Podが実行されていたNode上でPodが停止されたというkubeletからの確認を待ちません。API内のPodは直ちに削除されるため、新しいPodを同じ名前で作成できるようになります。Node上では、すぐに終了するように設定されるPodは、強制終了される前にわずかな猶予期間が与えられます。
注意: 即時削除では、実行中のリソースの終了を待ちません。
リソースはクラスター上で無期限に実行し続ける可能性があります。
StatefulSetのPodについては、StatefulSetからPodを削除するためのタスクのドキュメント を参照してください。
終了したPodのガベージコレクション 失敗したPodは人間またはcontroller が明示的に削除するまで存在します。
コントロールプレーンは終了状態のPod(SucceededまたはFailedのphaseを持つ)の数が設定された閾値(kube-controller-manager内のterminated-pod-gc-thresholdによって定義される)を超えたとき、それらのPodを削除します。これはPodが作成されて時間とともに終了するため、リソースリークを避けます。
次の項目
2 - Pod Condition
Kubernetesでは、多くのオブジェクトに Condition があります。
Conditionは、オブジェクトが表す対象の実際の状態における、ある側面を示すマーカーです。
PodにもConditionがあり、KubernetesのPodのConditionは、コントローラー(やトラブルシューティングを行う人)がPodの健全性を理解するための重要な要素です。
Podのフェーズ は、Podがライフサイクル上のどこに位置するかを大まかにまとめたものですが、単一の値ですべてを表現することはできません。
例えば、PodがRunningフェーズにあっても、まだトラフィックを処理する準備が整っていない場合があります。
PodのConditionは、Podがスケジュールされたかどうか、コンテナが準備完了かどうか、リサイズが進行中かどうか、taint によってPodが中断されようとしているかなど、Podの状態の複数の側面を独立して追跡することでフェーズを補完します。
Pod Conditionの構造 Podのステータスには、Podが特定のチェックポイントを通過したかどうかを示すPodCondition の配列が含まれています。
PodCondition配列の各要素には、以下のフィールドがあります:
PodConditionのフィールド
フィールド名
説明
type
このPodのConditionの名前です。
status
このConditionが適用可能かどうかを示します。可能な値は"True"、"False"、"Unknown"のいずれかです。
lastProbeTime
Pod Conditionが最後に確認されたときのタイムスタンプです。
lastTransitionTime
Podのステータスが、あるステータスから別のステータスへ最後に遷移したときのタイムスタンプです。
reason
Conditionの最後の遷移理由を示す、機械可読のアッパーキャメルケースのテキストです。
message
最後のステータス遷移に関する詳細を示す人間向けのメッセージです。
observedGeneration
Conditionが記録された時点のPodの.metadata.generationです。Pod generation を参照してください。
ビルトインのPod Condition Kubernetesは以下のPod Conditionを管理します:
ライフサイクル上のCondition : Podがライフサイクルを進む過程で、おおよそPodScheduled、PodReadyToStartContainers、Initialized、ContainersReady、Readyの順に設定されます。
その他のCondition : 特定の操作やイベントに応じて、DisruptionTarget、PodResizePending、PodResizeInProgressが設定されます。
上記のビルトインのConditionに加えて、PodのReadinessゲート を使用してカスタムのConditionを定義することもできます。
ライフサイクル上のPod Condition Podがライフサイクルを進むにつれて、kubeletは以下のConditionをおおよそ次の順序で設定します:
PodScheduled: Podがノードにスケジュールされたことを示します。
PodReadyToStartContainers: Podのサンドボックスが正常に作成され、ネットワークが構成されたことを示します。
サンドボックスとネットワークは、コンテナランタイム とCNI プラグインによってセットアップされます。
Initialized: すべてのInitコンテナ が正常に完了したことを示します。
Initコンテナを持たないPodでは、サンドボックスの作成前にTrueに設定されます。
ContainersReady: Pod内のすべてのコンテナが準備完了であることを示します。
コンテナのReadinessは、設定されている場合はReadiness Probe によって判定されます。
Ready: Podがリクエストを処理でき、一致するすべてのService の負荷分散プールに追加されるべきであることを示します。
ReadyでないPodはServiceのエンドポイントから削除されます。
備考: Ready Conditionは
ContainersReadyだけに依存しているわけではありません。
Podが
readinessGatesを指定している場合、Podが
Readyになるためには、それらのカスタムConditionもすべて
Trueである必要があります。
詳細は
PodのReadiness を参照してください。
kubectlを使用してPodのConditionを確認できます:
kubectl get pod <pod-name> -o yaml
実行中のPodのstatus.conditionsは次のようになります:
status :
conditions :
- type : PodScheduled
status : "True"
lastProbeTime : null
lastTransitionTime : "2026-03-29T08:52:21Z"
observedGeneration : 1
- type : PodReadyToStartContainers
status : "True"
lastProbeTime : null
lastTransitionTime : "2026-04-11T06:02:16Z"
observedGeneration : 1
- type : Initialized
status : "True"
lastProbeTime : null
lastTransitionTime : "2026-03-29T08:52:21Z"
observedGeneration : 1
- type : ContainersReady
status : "True"
lastProbeTime : null
lastTransitionTime : "2026-04-11T06:02:45Z"
observedGeneration : 1
- type : Ready
status : "True"
lastProbeTime : null
lastTransitionTime : "2026-04-11T06:02:45Z"
observedGeneration : 1
PodReadyToStartContainers
FEATURE STATE:
GA since Kubernetes v1.37
More information about this feature
This is a stable feature in Kubernetes, and has been since version v1.37. It was first available in the v1.28 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate PodReadyToStartContainersCondition , Kubernetes ignores it but does not report any error.
備考: このConditionは、開発初期にはPodHasNetworkという名前でした。
Podがノードにスケジュールされた後、kubeletに受け入れられ、必要なストレージボリュームがマウントされる必要があります。
これらのフェーズが完了すると、kubeletは(コンテナランタイムインターフェース(CRI) を使用して)コンテナランタイムと連携し、ランタイムサンドボックスをセットアップしてPodのネットワークを構成します。
PodReadyToStartContainersConditionフィーチャーゲートが有効な場合(Kubernetes 1.37ではデフォルトで有効)、PodReadyToStartContainers ConditionがPodのstatus.conditionsフィールドに追加されます。
PodReadyToStartContainers Conditionは、Podにネットワーク構成済みのランタイムサンドボックスがないことをkubeletが検出すると、Falseに設定されます。
これは以下のシナリオで発生します:
Podのライフサイクルの初期で、kubeletがコンテナランタイムを使用してPodのサンドボックスのセットアップをまだ開始していないとき。
Podのライフサイクルの後期で、Podのサンドボックスが以下のいずれかの原因で破棄されたとき:
Podが退避させられずに、ノードが再起動した。
隔離に仮想マシンを使用するコンテナランタイムにおいて、Podサンドボックスの仮想マシンが再起動し、新しいサンドボックスと新しいコンテナネットワーク設定の作成が必要になった。
ランタイムプラグインによるPodのサンドボックスの作成とネットワーク構成が正常に完了すると、kubeletはPodReadyToStartContainers ConditionをTrueに設定します。
PodReadyToStartContainers ConditionがTrueに設定された後、kubeletはコンテナイメージの取得とコンテナの作成を開始できます。
Initコンテナを持つPodでは、kubeletはInitコンテナが正常に完了した後(これはランタイムプラグインによるサンドボックスの作成とネットワーク構成が成功した後に発生します)、Initialized ConditionをTrueに設定します。
Initコンテナを持たないPodでは、kubeletはサンドボックスの作成とネットワーク構成が開始する前に、Initialized ConditionをTrueに設定します。
その他のPod Condition 以下のConditionは、通常のPodのライフサイクルの進行には含まれません。
これらは特定の操作やイベントに応じて設定されます。
DisruptionTarget Disruption によりPodが削除されようとしていることを示すために、専用のPod DisruptionTarget Conditionが追加されます。
このConditionのreasonフィールドは、Podの終了理由として以下のいずれかを示します:
PreemptionByScheduler
より高い優先度を持つ新しいPodを受け入れるために、スケジューラーによってPodがプリエンプト されようとしています。
詳細はPodの優先度とプリエンプション を参照してください。
DeletionByTaintManager
Podが許容しないNoExecuteのtaintにより、Taint Manager(kube-controller-manager内のノードライフサイクルコントローラーの一部)によってPodが削除されようとしています。
taint ベースの退避を参照してください。
EvictionByEvictionAPI
PodがKubernetes APIを使用した退避 の対象としてマークされました。
DeletionByPodGC
既に存在しないノードにバインドされているPodが、Podのガベージコレクション によって削除されようとしています。
TerminationByKubelet
ノードの圧迫による退避 、ノードのグレースフルシャットダウン 、またはシステムにとってクリティカルなPod のためのプリエンプションのいずれかにより、Podがkubeletによって終了されました。
Podのコンテナの制限 を超過したことによる退避のようなその他すべてのDisruptionシナリオでは、Disruptionの原因がPod自体にある可能性が高く、リトライしても再発するため、PodはDisruptionTarget Conditionを受け取りません。
備考: PodのDisruptionは中断される可能性があります。
コントロールプレーンは、同じPodのDisruptionを継続しようと再試行する場合がありますが、保証はされていません。
その結果、DisruptionTarget ConditionがPodに追加されても、そのPodが実際には削除されないことがあります。
このような場合、しばらくすると、PodのDisruptionのConditionはクリアされます。
Podのガベージコレクター(PodGC)は、Podをクリーンアップするとともに、Podが非終了フェーズにある場合はそれらをfailedとしてマークします(Podのガベージコレクション も参照してください)。
Job(またはCronJob)を使用する場合、これらのPodのDisruptionのConditionを、JobのPod失敗ポリシー の一部として活用したい場合があります。
詳細については、Disruption を参照してください。
PodResizePendingとPodResizeInProgress kubeletは、リサイズリクエストの状態を示すために、PodのステータスのConditionを更新します:
type: PodResizePending: kubeletはリクエストをすぐには許可できません。
messageフィールドにその理由が記載されます。
reason: Infeasible: 要求されたリサイズは現在のノード上では実行不可能です(例えば、ノードが持つリソースより多くを要求した場合)。
reason: Deferred: 要求されたリサイズは現時点では不可能ですが、後で実現可能になる可能性があります(例えば、他のPodが削除された場合)。
kubeletはリサイズを再試行します。
type: PodResizeInProgress: kubeletはリサイズを受け入れてリソースを割り当てましたが、変更はまだ適用中です。
通常は短時間で完了しますが、リソースの種類やランタイムの挙動によってはさらに時間がかかる場合があります。
実行中に発生したエラーは、messageフィールドに(reason: Errorとともに)報告されます。
要求されたリサイズが Deferred となった場合、kubeletは、例えば他のPodが削除されたりスケールダウンされたりしたときなどに、定期的にリサイズを再試行します。
Podのリサイズの詳細については、コンテナに割り当てられたCPUおよびメモリリソースのリサイズ を参照してください。
Enhanced Pod readiness アプリケーションは、Podの.statusに追加のフィードバックやシグナルを注入できます。
これは Enhanced Pod readiness と呼ばれます。
これを使用するには、PodのspecでreadinessGatesを設定し、kubeletがPodのReadinessを評価する際に確認する追加のConditionのリストを指定します。
そして、これらのカスタムConditionを管理するコントローラーを実装またはインストールすると、kubeletはそれをPodがreadyかどうかを判断するための追加情報として使用します。
ReadinessゲートはPodのstatus.conditionフィールドの現在の状態によって決まります。
Kubernetesがstatus.conditionsフィールド内に該当するConditionを見つけられない場合、そのConditionのステータスはデフォルトで"False"になります。
kind : Pod
...
spec :
readinessGates :
- conditionType : "www.example.com/feature-1"
status :
conditions :
- type : Ready # ビルトインのPodCondition
status : "False"
lastProbeTime : null
lastTransitionTime : 2018-01-01T00:00:00Z
- type : "www.example.com/feature-1" # 追加のPodCondition
status : "False"
lastProbeTime : null
lastTransitionTime : 2018-01-01T00:00:00Z
containerStatuses :
- containerID : docker://abcd...
ready : true
...
追加するPodのConditionの名前は、Kubernetesのラベルキーのフォーマット に準拠している必要があります。
Pod Readinessのためのステータス Podにこれらのstatus.conditionsを設定するには、アプリケーションやオペレーター は、Podのステータスサブリソースに対してPATCHアクションを使用する必要があります。
kubectl patchを--subresource=statusとともに使用するか、Kubernetesのクライアントライブラリ を使用して、PodのReadinessのためにカスタムのPodのConditionを設定するコードを記述できます。
カスタムConditionを使用するPodは、以下の両方が当てはまる場合のみ readyと評価されます。
Pod内のすべてのコンテナがreadyである。
readinessGatesに指定されたすべてのConditionがTrueである。
PodのコンテナがReadyでも、カスタムConditionの少なくとも1つが欠落しているかFalseの場合、kubeletはPodのReady Conditionをreason: ReadinessGatesNotReadyとともにstatus: "False"に設定します。
次の項目
3 - Initコンテナ
このページでは、Initコンテナの概要について説明します。
Initコンテナとは、Pod 内でアプリケーションコンテナの前に実行される特別なコンテナです。
Initコンテナには、アプリケーションコンテナのイメージに存在しないユーティリティやセットアップスクリプトを含めることができます。
Podの仕様では、アプリケーションコンテナを記述するcontainers配列と同じ階層に並べて、Initコンテナを指定できます。
Kubernetesでは、サイドカーコンテナ は、メインのアプリケーションコンテナよりも前に起動し、実行し続ける コンテナです。
このドキュメントでは、Podの初期化中に実行が完了するコンテナであるInitコンテナについて説明します。
Initコンテナを理解する Pod は、内部で実行される複数のアプリケーションコンテナを持つことができますが、アプリケーションコンテナが起動する前に実行される1つ以上のInitコンテナを持つこともできます。
Initコンテナは下記の項目をのぞいて、通常のコンテナと全く同じです:
Initコンテナは常に完了するまで稼働します。
各Initコンテナは、次のInitコンテナが稼働する前に正常に完了しなくてはなりません。
Pod内のInitコンテナが失敗した場合、kubeletは成功するまで、Initコンテナの再起動を繰り返します。
しかし、PodのrestartPolicyがNeverに設定されていて、Podの起動時にInitコンテナが失敗した場合、KubernetesはPod全体を失敗として扱います。
PodにInitコンテナを指定するためには、Podの仕様 にinitContainersフィールドをcontainer項目の配列として追加してください(アプリケーションのcontainersフィールドとそのコンテンツと同様です)。
詳細については、APIリファレンスのコンテナ を参照してください。
Initコンテナのステータスは、.status.initContainerStatusesフィールドにコンテナのステータスの配列として返されます(.status.containerStatusesと同様です)。
通常のコンテナとの違い Initコンテナは、リソース制限、ボリューム 、セキュリティ設定などのアプリケーションコンテナの全てのフィールドと機能をサポートしています。
ただし、Initコンテナのリソース要求と制限は、コンテナ間のリソース共有 に記載されているように、異なる方法で処理されます。
通常のInitコンテナ(つまり、サイドカーコンテナを除く)は、lifecycle、livenessProbe、readinessProbe、startupProbeフィールドをサポートしていません。
InitコンテナはPodの準備が完了する前に実行を完了する必要があります。
一方、サイドカーコンテナはPodのライフタイム中は常に実行され続け、一部のProbeを サポートしています 。
サイドカーコンテナの詳細については、サイドカーコンテナ を参照してください。
単一のPodに対して複数のInitコンテナを指定した場合、kubeletはそれらのInitコンテナを順次実行します。
各Initコンテナは、次のInitコンテナが実行される前に正常に終了する必要があります。
全てのInitコンテナの実行が完了すると、kubeletはPodのアプリケーションコンテナを初期化し、通常通り実行します。
サイドカーコンテナとの違い Initコンテナは、メインのアプリケーションコンテナが起動する前にタスクを実行して完了します。
サイドカーコンテナ とは異なり、Initコンテナはメインコンテナと並行して継続的に実行されることはありません。
Initコンテナは順次実行され完了します。
すべてのInitコンテナが正常に完了するまで、メインコンテナは起動しません。
Initコンテナはlifecycle、livenessProbe、readinessProbe、startupProbeをサポートしていませんが、サイドカーコンテナはこれらすべてのProbe をサポートしてライフサイクルを制御します。
Initコンテナは、メインのアプリケーションコンテナとリソース(CPU、メモリ、ネットワーク)を共有しますが、直接やり取りすることはありません。
ただし、共有ボリュームを使用してデータの交換を行うことは可能です。
Initコンテナを使用する Initコンテナはアプリケーションコンテナのイメージとは分離されているため、コンテナの起動に関連したコードにおいていくつかの利点があります:
Initコンテナには、アプリケーションイメージに含まれないセットアップ用のユーティリティやカスタムコードを含めることができます。
たとえば、セットアップ時にsed、awk、python、digなどのツールを使用するためだけに、別のイメージをFROMしてイメージを作成する必要はありません。
アプリケーションイメージをビルドする役割とデプロイする役割は、共同で単一のアプリケーションイメージをビルドする必要がないため、それぞれ独立して実施することができます。
Initコンテナは、同じPod内のアプリケーションコンテナとは異なる方法でファイルシステムにアクセスできます。
その結果、アプリケーションコンテナがアクセスできないSecret に対するアクセス権限を得ることができます。
Initコンテナはアプリケーションコンテナが開始する前に完了するまで実行されるため、Initコンテナを使用することで、特定の前提条件が満たされるまでアプリケーションコンテナの起動をブロックしたり遅らせることができます。
前提条件が満たされると、Pod内の全てのアプリケーションコンテナを並行して起動することができます。
Initコンテナは、アプリケーションコンテナイメージのセキュリティを低下させる可能性のあるユーティリティやカスタムコードを安全に実行できます。
不要なツールを分離することで、アプリケーションコンテナイメージの攻撃対象領域を制限できます。
例 Initコンテナを活用する方法について、いくつかのアイデアを次に示します:
シェルのワンライナーコマンドを使ってService が作成されるのを待機する:
for i in { 1..100} ; do sleep 1; if nslookup myservice; then exit 0; fi ; done ; exit 1
以下のようなコマンドを使って、Downward APIを介してこのPodをリモートサーバーに登録する:
curl -X POST http://$MANAGEMENT_SERVICE_HOST :$MANAGEMENT_SERVICE_PORT /register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
以下のようなコマンドを使ってアプリケーションコンテナの起動を待機する:
Gitリポジトリをボリューム にクローンする。
いくつかの値を設定ファイルに配置し、メインのアプリケーションコンテナのための設定ファイルを動的に生成するためのテンプレートツールを実行する。
例えば、そのPodのPOD_IPの値を設定ファイルに配置し、Jinjaを使ってメインのアプリケーションコンテナの設定ファイルを生成する。
Initコンテナの具体的な使用方法 下記の例は、2つのInitコンテナを含むシンプルなPodを定義しています。
1つ目のInitコンテナはmyserviceの起動を、2つ目のInitコンテナはmydbの起動をそれぞれ待ちます。
両方のInitコンテナの実行が完了すると、Podはspecセクションにあるアプリケーションコンテナを実行します。
apiVersion : v1
kind : Pod
metadata :
name : myapp-pod
labels :
app.kubernetes.io/name : MyApp
spec :
containers :
- name : myapp-container
image : busybox:1.28
command : [ 'sh' , '-c' , 'echo The app is running! && sleep 3600' ]
initContainers :
- name : init-myservice
image : busybox:1.28
command : [ 'sh' , '-c' , "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done" ]
- name : init-mydb
image : busybox:1.28
command : [ 'sh' , '-c' , "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done" ]
次のコマンドを実行して、このPodを開始します:
kubectl apply -f myapp.yaml
実行結果は下記のようになります:
pod/myapp-pod created
そして次のコマンドでステータスを確認します:
kubectl get -f myapp.yaml
実行結果は下記のようになります:
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 6m
より詳細な情報は次のコマンドで確認します:
kubectl describe -f myapp.yaml
実行結果は下記のようになります:
Name: myapp-pod
Namespace: default
[...]
Labels: app.kubernetes.io/name=MyApp
Status: Pending
[...]
Init Containers:
init-myservice:
[...]
State: Running
[...]
init-mydb:
[...]
State: Waiting
Reason: PodInitializing
Ready: False
[...]
Containers:
myapp-container:
[...]
State: Waiting
Reason: PodInitializing
Ready: False
[...]
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.201
16s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image "busybox"
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox"
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container init-myservice
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container init-myservice
このPod内のInitコンテナのログを確認するためには、次のコマンドを実行します:
kubectl logs myapp-pod -c init-myservice # 1つ目のInitコンテナを調査する
kubectl logs myapp-pod -c init-mydb # 2つ目のInitコンテナを調査する
この時点で、これらのInitコンテナはmydbとmyserviceという名前のService の検出を待機しています。
これらのServiceを検出するための設定は以下の通りです:
---
apiVersion : v1
kind : Service
metadata :
name : myservice
spec :
ports :
- protocol : TCP
port : 80
targetPort : 9376
---
apiVersion : v1
kind : Service
metadata :
name : mydb
spec :
ports :
- protocol : TCP
port : 80
targetPort : 9377
mydbおよびmyserviceというServiceを作成するために、以下のコマンドを実行します:
kubectl apply -f services.yaml
実行結果は下記のようになります:
service/myservice created
service/mydb created
Initコンテナが完了し、myapp-podというPodが実行状態に移行したことを確認できます:
kubectl get -f myapp.yaml
実行結果は下記のようになります:
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 9m
この簡単な例は、独自のinitコンテナを作成する際のヒントになるはずです。
次の項目 には、さらに詳細な使用例に関するリンクがあります。
Initコンテナのふるまいに関する詳細 Podの起動時に、kubeletはネットワークおよびストレージの準備が整うまで、Initコンテナを実行可能な状態にしません。
また、kubeletはPodのspecに定義された順番に従って、PodのInitコンテナを起動します。
各Initコンテナは次のInitコンテナが起動する前に正常に終了しなくてはなりません。
もし、あるInitコンテナがランタイムにより起動失敗した場合、もしくはエラーで終了した場合、そのPodのrestartPolicyの値に従ってリトライされます。
しかし、PodのrestartPolicyがAlwaysに設定されていた場合は、InitコンテナのrestartPolicyはOnFailureとして適用されます。
すべてのInitコンテナが成功するまで、PodはReadyになりません。
InitコンテナのポートはService配下に集約されません。
初期化中のPodはPending状態ですが、条件Initializedはfalseに設定されているはずです。
Podを再起動 するとき、またはPodが再起動されたとき、全てのInitコンテナは必ず再度実行されます。
Initコンテナのspecに対する変更は、コンテナイメージフィールドに制限されています。
Initコンテナのimageフィールドを直接変更しても、Podの再起動や再作成はトリガー されません 。
ただし、Podがまだ起動していない場合、その変更はPodの起動方法に影響を与える可能性があります。
Podテンプレート の場合、通常はInitコンテナの任意のフィールドを変更できます。
その変更の影響は、Podテンプレートがどこで使用されているかによって異なります。
Initコンテナは何度も再起動、リトライおよび再実行可能であるため、べき等(Idempotent)である必要があります。
特に、emptyDirにファイルを書き込むコードは、書き込み先のファイルがすでに存在している可能性を考慮に入れなければいけません。
Initコンテナは、アプリケーションコンテナが持つすべてのフィールドを持っています。
ただし、KubernetesではreadinessProbeの使用が禁止されています。
これは、Initコンテナでは完了とは別にreadiness状態を定義することができないためです。
この制約は、バリデーション時に強制されます。
Initコンテナが永久に失敗し続けることを防ぐために、Pod上でactiveDeadlineSecondsを使用してください。
activeDeadlineSecondsの設定はInitコンテナが実行中の時間にも適用されます。
ただし、activeDeadlineSecondsはInitコンテナが完了した後にも影響が及ぶため、アプリケーションをJobとしてデプロイする場合にのみ使用することを推奨します。
すでに正しく動作しているPodは、activeDeadlineSecondsを設定すると強制終了されます。
Pod内の各アプリケーションコンテナとInitコンテナの名前はユニークである必要があります。
他のコンテナと同じ名前を共有していた場合、バリデーションエラーが返されます。
コンテナ間のリソース共有 Initコンテナ、サイドカーコンテナ、アプリケーションコンテナの実行順序を考慮すると、リソース使用に関して以下のルールが適用されます:
すべてのInitコンテナで定義された特定のリソースの要求または制限のうち、最も高い値が実効Init要求/制限 となります。
リソース制限が指定されていない場合、これが最も高い制限であるとみなされます。
リソースに対するPodの実効要求/制限 は、以下のうち高い方になります。
すべてのアプリケーションコンテナのリソース要求/制限の合計
リソースに対する実効Init要求/制限
スケジューリングは実効要求/制限に基づいて行われます。
つまり、Initコンテナは初期化のためにリソースを予約できますが、これらはPodのライフタイム中は使用されません。
Podの実効QoS tier は、Initコンテナとアプリケーションコンテナの両方に適用されるQoS(サービス品質) tierです。
クォータと制限は、実効的なPodの要求と制限に基づいて適用されます。
InitコンテナとLinux cgroups Linuxでは、Podレベルのコントロールグループ(cgroups)に対するリソース割り当ては、スケジューラーと同様に、実効的なPodの要求と制限に基づいています。
Podの再起動の理由 以下の理由によりPodは再起動し、Initコンテナの再実行を引き起こす可能性があります:
Podインフラストラクチャコンテナが再起動された場合。
これは稀なケースであり、ノードへのルートアクセス権を持つ人が実行する必要があります。
restartPolicyがAlwaysに設定されている状態でPod内のすべてのコンテナが終了し、再起動が強制され、かつInitコンテナの完了記録がガベージコレクション により失われた場合。
Initコンテナイメージが変更された場合、またはガベージコレクションによりInitコンテナの完了記録が失われた場合、Podは再起動されません。
これはKubernetes v1.20以降に適用されます。
それ以前のバージョンのKubernetesを使用している場合は、使用しているバージョンのドキュメントを参照してください。
次の項目 詳しく学ぶには、以下を参照してください:
4 - サイドカーコンテナ
FEATURE STATE:
GA since Kubernetes v1.33
More information about this feature
This is a stable feature in Kubernetes, and has been since version v1.33. It was first available in the v1.28 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate SidecarContainers , Kubernetes ignores it but does not report any error.
サイドカーコンテナは、同じPod 内でメインのアプリケーションコンテナと共に実行されるセカンダリコンテナです。
これらのコンテナは、ロギング、モニタリング、セキュリティ、データ同期などの追加サービスや機能を提供することで、プライマリの アプリケーションコンテナ の機能を強化または拡張するために使用されます。
メインのアプリケーションコードを直接変更する必要はありません。
通常、Pod内にはアプリケーションコンテナが1つだけ含まれます。
例えば、ローカルWebサーバーを必要とするWebアプリケーションがある場合、ローカルWebサーバーがサイドカーであり、Webアプリケーション自体がアプリケーションコンテナです。
Kubernetesにおけるサイドカーコンテナ Kubernetesは、サイドカーコンテナをInitコンテナ の特殊なケースとして実装しています。
サイドカーコンテナはPod起動後も実行され続けます。
このドキュメントでは、Pod起動時にのみ実行されるコンテナを明確に指すために、通常のInitコンテナ という用語を使用します。
クラスターでSidecarContainersフィーチャーゲート が有効になっている場合(この機能はKubernetes v1.29以降デフォルトで有効です)、PodのinitContainersフィールドにリストされているコンテナに対してrestartPolicyを指定できます。
これらの再起動可能な サイドカー コンテナは、同じPod内の他のInitコンテナやメインアプリケーションコンテナから独立しています。
メインアプリケーションコンテナや他のInitコンテナに影響を与えることなく、これらを起動、停止、または再起動することができます。
また、Initコンテナやサイドカーコンテナとして定義されていない複数のコンテナでPodを実行することもできます。
これは、Pod内のコンテナがPod全体の動作に必要であるが、どのコンテナを最初に起動または停止するかを制御する必要がない場合に適しています。
また、コンテナレベルのrestartPolicyフィールドをサポートしていない古いバージョンのKubernetesをサポートする必要がある場合にも、この方法を使用できます。
アプリケーションの例 以下は、2つのコンテナを持つDeploymentの例で、そのうちの1つがサイドカーコンテナです:
apiVersion : apps/v1
kind : Deployment
metadata :
name : myapp
labels :
app : myapp
spec :
replicas : 1
selector :
matchLabels :
app : myapp
template :
metadata :
labels :
app : myapp
spec :
containers :
- name : myapp
image : alpine:latest
command : [ 'sh' , '-c' , 'while true; do echo "logging" >> /opt/logs.txt; sleep 1; done' ]
volumeMounts :
- name : data
mountPath : /opt
initContainers :
- name : logshipper
image : alpine:latest
restartPolicy : Always
command : [ 'sh' , '-c' , 'tail -F /opt/logs.txt' ]
volumeMounts :
- name : data
mountPath : /opt
volumes :
- name : data
emptyDir : {}
サイドカーコンテナとPodのライフサイクル InitコンテナがrestartPolicyをAlwaysに設定して作成された場合、Podの全ライフサイクルを通じて起動し、実行され続けます。
これは、メインのアプリケーションコンテナから分離した補助的なサービスを実行する際に役立ちます。
このInitコンテナにreadinessProbeが指定されている場合、その結果はPodのready状態を判定するために使用されます。
これらのコンテナはInitコンテナとして定義されているため、通常のInitコンテナと同じ順序と順次実行の保証の恩恵を受けます。
これにより、複雑なPod初期化フローの際に、サイドカーコンテナと通常のInitコンテナを混在させることができます。
通常のInitコンテナと比較して、initContainers内で定義されたサイドカーコンテナは起動後も実行され続けます。
これは、Podの.spec.initContainers内に複数のエントリがある場合に重要です。
サイドカー形式のInitコンテナが実行状態になった後(kubeletがそのInitコンテナのstartedステータスをtrueに設定した後)、kubeletは順序付けられた.spec.initContainersリストから次のInitコンテナを起動します。
このステータスは、コンテナ内でプロセスが実行されておりStartup Probeが定義されていない場合、またはstartupProbeが成功した結果として、trueになります。
Podの終了 時には、kubeletはメインのアプリケーションコンテナが完全に停止するまで、サイドカーコンテナの終了を引き延ばします。
その後、サイドカーコンテナはPodの仕様内で定義された順序と逆の順序でシャットダウンされます。
このアプローチにより、サイドカーコンテナは、そのサービスが不要になるまで、Pod内の他のコンテナをサポートし続けることが保証されます。
サイドカーコンテナを持つJob Kubernetes形式のInitコンテナを使用してサイドカーコンテナを使用するJobを定義した場合、各Pod内のサイドカーコンテナは、メインコンテナが終了した後にJobが完了することを妨げません。
以下は、2つのコンテナを持つJobの例で、そのうちの1つがサイドカーコンテナです:
apiVersion : batch/v1
kind : Job
metadata :
name : myjob
spec :
template :
spec :
containers :
- name : myjob
image : alpine:latest
command : [ 'sh' , '-c' , 'echo "logging" > /opt/logs.txt' ]
volumeMounts :
- name : data
mountPath : /opt
initContainers :
- name : logshipper
image : alpine:latest
restartPolicy : Always
command : [ 'sh' , '-c' , 'tail -F /opt/logs.txt' ]
volumeMounts :
- name : data
mountPath : /opt
restartPolicy : Never
volumes :
- name : data
emptyDir : {}
アプリケーションコンテナとの違い サイドカーコンテナは、同じPod内で アプリケーションコンテナ と並行して実行されます。
ただし、サイドカーコンテナは主要なアプリケーションロジックを実行するのではなく、メインアプリケーションに補助的な機能を提供します。
サイドカーコンテナは独自の独立したライフサイクルを持ちます。
アプリケーションコンテナとは独立して、起動、停止、再起動できます。
これは、メインアプリケーションに影響を与えることなく、サイドカーコンテナを更新、スケール、またはメンテナンスできることを意味します。
サイドカーコンテナは、プライマリコンテナと同じネットワークおよびストレージ名前空間を共有します。
このように共存することで、密接に相互作用しリソースを共有できます。
Kubernetesの観点からは、サイドカーコンテナのグレースフルな終了はそれほど重要ではありません。
他のコンテナが、割り当てられたグレースフルな終了時間をすべて消費した場合、サイドカーコンテナはグレースフルに終了する時間を持つ前に、SIGTERMシグナルに続いてSIGKILLシグナルを受信します。
そのため、サイドカーコンテナにおいては、Pod終了時の0以外の終了コード(0は正常終了を示します)は正常なものであり、一般的に外部ツールによって無視されるべきです。
Initコンテナとの違い サイドカーコンテナはメインコンテナと並行して動作し、その機能を拡張して追加のサービスを提供します。
サイドカーコンテナは、メインのアプリケーションコンテナと同時に実行されます。
サイドカーコンテナはPodのライフサイクル全体を通じてアクティブであり、メインコンテナとは独立して起動および停止できます。
Initコンテナ とは異なり、サイドカーコンテナは、ライフサイクルを制御するためのProbe をサポートしています。
サイドカーコンテナは、メインのアプリケーションコンテナと直接やり取りできます。
これは、Initコンテナと同様に常に同じネットワークを共有し、オプションでボリューム(ファイルシステム)も共有できるためです。
Initコンテナはメインコンテナが起動する前に停止するため、InitコンテナはPod内のアプリケーションコンテナとメッセージを交換できません。
データの受け渡しは一方向です(例えば、InitコンテナがemptyDirボリューム内に情報を配置することはできます)。
サイドカーコンテナのイメージを変更してもPodは再起動されませんが、コンテナの再起動はトリガーされます。
コンテナ内でのリソース共有
Initコンテナ、サイドカーコンテナ、アプリケーションコンテナの実行順序を考慮すると、リソース使用に関して以下のルールが適用されます:
すべてのInitコンテナで定義された特定のリソース要求または制限のうち、最も高い値が実効Init要求/制限 となります。
いずれかのリソースにリソース制限が指定されていない場合、これが最も高い制限と見なされます。
リソースに対するPodの実効要求/制限 は、Podのオーバーヘッド と以下のうち高い方の合計です:
すべての非Initコンテナ(アプリケーションコンテナとサイドカーコンテナ)のリソース要求/制限の合計
リソースに対する実効Init要求/制限
スケジューリングは実効要求/制限に基づいて行われます。
これは、InitコンテナがPodのライフタイム中には使用されない初期化用のリソースを予約できることを意味します。
Podの実効QoS tier のQoS(サービス品質) tierは、Initコンテナ、サイドカーコンテナ、アプリケーションコンテナすべてに対するQoS tierです。
クォータと制限は、実効Pod要求と制限に基づいて適用されます。
サイドカーコンテナとLinux cgroup Linuxでは、Podレベルのコントロールグループ(cgroup)に対するリソース割り当ては、スケジューラーと同様に、実効的なPod要求/制限に基づいて行われます。
次の項目
5 - エフェメラルコンテナ
FEATURE STATE:
GA since Kubernetes v1.25
このページでは、特別な種類のコンテナであるエフェメラルコンテナの概要を説明します。エフェメラルコンテナは、トラブルシューティングなどのユーザーが開始するアクションを実行するために、すでに存在するPod 内で一時的に実行するコンテナです。エフェメラルコンテナは、アプリケーションの構築ではなく、serviceの調査のために利用します。
エフェメラルコンテナを理解する Pod は、Kubernetesのアプリケーションの基本的なビルディングブロックです。Podは破棄可能かつ置き換え可能であることが想定されているため、一度Podが作成されると新しいコンテナを追加することはできません。その代わりに、通常はDeployment を使用してPodを削除して置き換えます。
たとえば、再現困難なバグのトラブルシューティングなどのために、すでに存在するPodの状態を調査する必要が出てくることがあります。このような場合、既存のPod内でエフェメラルコンテナを実行することで、Podの状態を調査したり、任意のコマンドを実行したりできます。
エフェメラルコンテナとは何か? エフェメラルコンテナは、他のコンテナと異なり、リソースや実行が保証されず、自動的に再起動されることも決してないため、アプリケーションを構築する目的には適しません。エフェメラルコンテナは、通常のコンテナと同じContainerSpecで記述されますが、多くのフィールドに互換性がなかったり、使用できなくなっています。
エフェメラルコンテナはポートを持つことができないため、ports、livenessProbe、readinessProbeなどは使えなくなっています。
Podリソースの割り当てはイミュータブルであるため、resourcesの設定が禁止されています。
利用が許可されているフィールドの一覧については、EphemeralContainerのリファレンスドキュメント を参照してください。
エフェメラルコンテナは、直接pod.specに追加するのではなく、API内の特別なephemeralcontainersハンドラを使用して作成します。そのため、エフェメラルコンテナをkubectl editを使用して追加することはできません。
エフェメラルコンテナをPodに追加した後は、通常のコンテナのようにエフェメラルコンテナを変更または削除することはできません。
エフェメラルコンテナの用途 エフェメラルコンテナは、コンテナがクラッシュしてしまったり、コンテナイメージにデバッグ用ユーティリティが同梱されていない場合など、kubectl execでは不十分なときにインタラクティブなトラブルシューティングを行うために役立ちます。
特に、distrolessイメージ を利用すると、攻撃対象領域を減らし、バグや脆弱性を露出する可能性を減らせる最小のコンテナイメージをデプロイできるようになります。distrolessイメージにはシェルもデバッグ用のユーティリティも含まれないため、kubectl execのみを使用してdistrolessイメージのトラブルシューティングを行うのは困難です。
エフェメラルコンテナを利用する場合には、他のコンテナ内のプロセスにアクセスできるように、プロセス名前空間の共有 を有効にすると便利です。
次の項目
6 - Disruption
このガイドは、高可用性アプリケーションを構築したいと考えており、そのために、Podに対してどのような種類のDisruptionが発生する可能性があるか理解する必要がある、アプリケーション所有者を対象としたものです。
また、クラスターのアップグレードやオートスケーリングなどのクラスターの操作を自動化したいクラスター管理者も対象にしています。
自発的なDisruptionと非自発的なDisruption Podは誰か(人やコントローラー)が破壊するか、避けることができないハードウェアまたはシステムソフトウェアエラーが発生するまで、消えることはありません。
これらの不可避なケースをアプリケーションに対する非自発的なDisruption と呼びます。
例えば:
ノードのバックエンドの物理マシンのハードウェア障害
クラスター管理者が誤ってVM(インスタンス)を削除した
クラウドプロバイダーまたはハイパーバイザーの障害によってVMが消えた
カーネルパニック
クラスターネットワークパーティションが原因でクラスターからノードが消えた
ノードのリソース不足 によるPodの退避
リソース不足を除いて、これら条件は全て、大半のユーザーにとって馴染みのあるものでしょう。
これらはKubernetesに固有のものではありません。
それ以外のケースのことを自発的なDisruption と呼びます。
これらはアプリケーションの所有者によって起こされたアクションと、クラスター管理者によって起こされたアクションの両方を含みます。
典型的なアプリケーションの所有者によるアクションには次のものがあります:
Deploymentやその他のPodを管理するコントローラーの削除
再起動を伴うDeployment内のPodのテンプレートの更新
Podの直接削除(例:アクシデントによって)
クラスター管理者のアクションには、次のようなものが含まれます:
修復やアップグレードのためのノードのドレイン 。
クラスターのスケールダウンのためにクラスターからノードをドレインする(クラスター自動スケーリング について学ぶ)。
そのノードに別のものを割り当てることができるように、ノードからPodを削除する。
これらのアクションはクラスター管理者によって直接実行されるか、クラスター管理者やクラスターをホスティングしているプロバイダーによって自動的に実行される可能性があります。
クラスターに対して自発的なDisruptionの要因となるものが有効になっているかどうかについては、クラスター管理者に聞くか、クラウドプロバイダーに相談または配布文書を参照してください。
有効になっているものが何もなければ、Pod Disruption Budgetの作成はスキップすることができます。
注意: 全ての自発的なDisruptionがPod Disruption Budgetによる制約を受けるわけではありません。
例えばDeploymentやPodの削除はPod Disruption Budgetをバイパスします。
Disruptionへの対応 非自発的なDisruptionを軽減する方法をいくつか紹介します:
Podは必要なリソースを要求 するようにする。
高可用性が必要な場合はアプリケーションをレプリケートする。(レプリケートされたステートレス およびステートフル アプリケーションの実行について学ぶ。)
レプリケートされたアプリケーションを実行する際にさらに高い可用性を得るには、(アンチアフィニティ を使って)ラックを横断して、または(マルチゾーンクラスター を使用している場合には)ゾーンを横断してアプリケーションを分散させる。
自発的なDisruptionの頻度は様々です。
基本的なKubernetesクラスターでは、自動で発生する自発的なDisruptionはありません(ユーザーによってトリガーされたものだけです)。
しかし、クラスター管理者やホスティングプロバイダーが何か追加のサービスを実行して自発的なDisruptionが発生する可能性があります。
例えば、ノード上のソフトウェアアップデートのロールアウトは自発的なDisruptionの原因となります。
また、クラスター(ノード)自動スケーリングの実装の中には、ノードのデフラグとコンパクト化のために自発的なDisruptionを伴うものがあります。
クラスター管理者やホスティングプロバイダーは、自発的なDisruptionがある場合、どの程度のDisruptionが予想されるかを文書化しているはずです。
Podのspecの中でPriorityClassesを使用している 場合など、特定の設定オプションによっても自発的(および非自発的)なDisruptionを引き起こす可能性があります。
Pod Disruption Budget
FEATURE STATE:
GA since Kubernetes v1.21
Kubernetesは、自発的なDisruptionが頻繁に発生する場合でも、可用性の高いアプリケーションの運用を支援する機能を提供しています。
アプリケーションの所有者として、各アプリケーションに対してPodDisruptionBudget (PDB)を作成することができます。
PDBは、レプリカを持っているアプリケーションのうち、自発的なDisruptionによって同時にダウンするPodの数を制限します。
例えば、クォーラムベースのアプリケーションでは、実行中のレプリカの数がクォーラムに必要な数を下回らないようにする必要があります。
Webフロントエンドは、負荷に対応するレプリカの数が、全体に対して一定の割合を下回らないようにしたいかもしれません。
クラスター管理者やホスティングプロバイダーは、直接PodやDeploymentを削除するのではなく、Eviction API を呼び出す、PodDisruptionBudgetsに配慮したツールを使用すべきです。
例えば、kubectl drainサブコマンドはノードを休止中とマークします。
kubectl drainを実行すると、ツールは休止中としたノード上の全てのPodを退避しようとします。
kubectlがあなたの代わりに送信する退避要求は一時的に拒否される可能性があるため、ツールは対象のノード上の全てのPodが終了するか、設定可能なタイムアウト時間に達するまで、全ての失敗した要求を定期的に再試行します。
PDBはアプリケーションの意図したレプリカ数に対して、許容できるレプリカの数を指定します。
例えば.spec.replicas: 5を持つDeploymentは常に5つのPodを持つことが想定されます。
PDBが同時に4つまでを許容する場合、Eviction APIは1度に(2つではなく)1つのPodの自発的なDisruptionを許可します。
アプリケーションを構成するPodのグループは、アプリケーションのコントローラー(Deployment、StatefulSetなど)が使用するものと同じラベルセレクターを使用して指定されます。
"意図した"Podの数は、これらのPodを管理するワークロードリソースの.spec.replicasから計算されます。
コントロールプレーンはPodの.metadata.ownerReferencesを調べることで、所有しているワークロードリソースを見つけます。
非自発的なDisruption はPDBによって防ぐことができません;
しかし、予算にはカウントされます。
アプリケーションのローリングアップデートによって削除または利用できなくなったPodはDisruptionの予算にカウントされますが、ローリングアップグレードを実行している時は(DeploymentやStatefulSetなどの)ワークロードリソースはPDBによって制限されません。
代わりに、アプリケーションのアップデート中の障害のハンドリングは、個々のワークロードリソースに対するspecで設定されます。
ノードのドレイン中に動作がおかしくなったアプリケーションの退避をサポートするために、Unhealthy Pod Eviction Policy にAlwaysAllowを設定することを推奨します。
既定の動作は、ドレインを継続する前にアプリケーションPodがhealthy な状態になるまで待機します。
Eviction APIを使用してPodを退避した場合、PodSpec で設定したterminationGracePeriodSecondsに従って正常に終了 します。
PodDisruptionBudgetの例 node-1からnode-3まで3つのノードがあるクラスターを考えます。
クラスターにはいくつかのアプリケーションが動いています。
それらのうちの1つは3つのレプリカを持ち、最初はpod-a、pod-bそしてpod-cと名前が付いています。
もう一つ、これとは独立したPDBなしのpod-xと呼ばれるものもあります。
初期状態ではPodは次のようにレイアウトされています:
node-1
node-2
node-3
pod-a available
pod-b available
pod-c available
pod-x available
3つのPodはすべてDeploymentの一部で、これらはまとめて1つのPDBを持ち、3つのPodのうちの少なくとも2つが常に存在していることを要求します。
例えばクラスター管理者がカーネルのバグを修正するために、再起動して新しいカーネルバージョンにしたいとします。
クラスター管理者はまず、kubectl drainコマンドを使ってnode-1をドレインしようとします。
ツールはpod-aとpod-xを退避しようとします。
これはすぐに成功します。
2つのPodは同時にterminating状態になります。
これにより、クラスターは次のような状態になります:
node-1 draining
node-2
node-3
pod-a terminating
pod-b available
pod-c available
pod-x terminating
DeploymentはPodの1つが終了中であることに気づき、pod-dという代わりのPodを作成します。
node-1はcordonされたため、別のノードに展開されます。
また、pod-xの代わりとしてpod-yも作られました。
(備考: StatefulSetの場合、pod-aはpod-0のように呼ばれ、代わりのPodが作成される前に完全に終了する必要があります。
この代わりのPodは、UIDは異なりますが、同じpod-0という名前になります。
それを除けば、本例はStatefulSetにも当てはまります。)
現在、クラスターは次のような状態になっています:
node-1 draining
node-2
node-3
pod-a terminating
pod-b available
pod-c available
pod-x terminating
pod-d starting
pod-y
ある時点でPodは終了し、クラスターはこのようになります:
node-1 drained
node-2
node-3
pod-b available
pod-c available
pod-d starting
pod-y
この時点で、せっかちなクラスター管理者がnode-2かnode-3をドレインしようとすると、Deploymentの利用可能なPodは2つしかなく、また、PDBによって最低2つのPodが要求されているため、drainコマンドはブロックされます。
しばらくすると、pod-dが使用可能になります。
クラスターの状態はこのようになります:
node-1 drained
node-2
node-3
pod-b available
pod-c available
pod-d available
pod-y
ここでクラスター管理者がnode-2をドレインしようとします。
drainコマンドは2つのPodをなんらかの順番で退避しようとします。
例えば最初にpod-b、次にpod-dとします。
pod-bについては退避に成功します。
しかしpod-dを退避しようとすると、Deploymentに対して利用可能なPodは1つしか残らないため、退避は拒否されます。
Deploymentはpod-bの代わりとしてpod-eを作成します。
クラスターにはpod-eをスケジューリングする十分なリソースがないため、ドレインは再びブロックされます。
クラスターは次のような状態になります:
node-1 drained
node-2
node-3
no node
pod-b terminating
pod-c available
pod-e pending
pod-d available
pod-y
この時点で、クラスター管理者はアップグレードを継続するためにクラスターにノードを追加する必要があります。
KubernetesがどのようにDisruptionの発生率を変化させているかについては、次のようなものから知ることができます:
いくつのレプリカをアプリケーションが必要としているか
インスタンスのグレースフルシャットダウンにどれくらいの時間がかかるか
新しいインスタンスのスタートアップにどれくらいの時間がかかるか
コントローラーの種類
クラスターリソースのキャパシティ
Pod Disruption Condition
FEATURE STATE:
Beta since Kubernetes v1.26
備考: この機能を使用するためには、クラスターで
フィーチャーゲート PodDisruptionConditionsを有効にする必要があります。
有効にすると、専用のPod DisruptionTarget Condition が追加されます。
これはPodがDisruption によって削除されようとしていることを示すものです。
Conditionのreasonフィールドにて、追加で以下のいずれかをPodの終了の理由として示します:
PreemptionByScheduler
Podはより高い優先度を持つ新しいPodを収容するために、スケジューラーによってプリエンプトされる 予定です。
詳細についてはPodの優先度とプリエンプション を参照してください。
DeletionByTaintManager
Podが許容しないNoExecute taintによって、Podは(kube-controller-managerの中のノードライフサイクルコントローラーである)Taintマネージャーによって削除される予定です。
taint ベースの退避を参照してください。
EvictionByEvictionAPI
PodはKubernetes APIを使用して退避するように マークされました。
DeletionByPodGC
すでに存在しないノードに紐づいているPodのため、Podのガベージコレクション によって削除される予定です。
TerminationByKubelet
node-pressureによる退避 またはGraceful Node Shutdown のため、Podはkubeletによって終了させられました。
備考: PodのDisruptionは一時停止する場合があります。
コントロールプレーンは同じPodに対するDisruptionを継続するために再試行するかもしれませんが、保証はされていません。
その結果、DisruptionTarget ConditionはPodに付与されるかもしれませんが、実際にはPodは削除されていない可能性があります。
そのような状況の場合、しばらくすると、Pod Disruption Conditionはクリアされます。
フィーチャーゲートPodDisruptionConditionsを有効にすると、Podのクリーンアップと共に、Podガベージコレクタ(PodGC)が非終了フェーズにあるPodを失敗とマークします。
(Podガベージコレクション も参照してください)。
Job(またはCronJob)を使用している場合、JobのPod失敗ポリシー の一部としてこれらのPod Disruption Conditionを使用したいと思うかもしれません。
クラスターオーナーとアプリケーションオーナーロールの分離 多くの場合、クラスター管理者とアプリケーションオーナーは、互いの情報を一部しか持たない別の役割であると考えるのが便利です。
このような責任の分離は、次のようなシナリオで意味を持つことがあります:
多くのアプリケーションチームでKubernetesクラスターを共有していて、役割の専門化が自然に行われている場合
クラスター管理を自動化するためにサードパーティのツールやサービスを使用している場合
Pod Disruption Budgetはロール間のインターフェースを提供することによって、この役割の分離をサポートします。
もしあなたの組織でこのような責任の分担がなされていない場合は、Pod Disruption Budgetを使用する必要はないかもしれません。
クラスターで破壊的なアクションを実行する方法 あなたがクラスターの管理者で、ノードやシステムソフトウェアのアップグレードなど、クラスター内のすべてのノードに対して破壊的なアクションを実行する必要がある場合、次のような選択肢があります:
アップグレードの間のダウンタイムを許容する。
もう一つの完全なレプリカクラスターにフェールオーバーする。
ダウンタイムはありませんが、重複するノードと、切り替えを調整する人的労力の両方のコストがかかる可能性があります。
Disruptionに耐性のあるアプリケーションを書き、PDBを使用する。
ダウンタイムはありません。
リソースの重複は最小限です。
クラスター管理をより自動化できます。
Disruptionに耐えうるアプリケーションを書くことは大変ですが、自発的なDisruptionに耐えうるようにするための作業は、非自発的なDisruptionに耐えうるために必要な作業とほぼ重複しています。
次の項目
7 - Pod Quality of Serviceクラス
このページでは、Kubernetesにおける Quality of Service(QoS)クラス を紹介し、Pod内のコンテナに指定したリソース制約に応じて、KubernetesがどのようにPodにQoSクラスを割り当てるのかについて説明します。
Kubernetesは、ノード上で利用可能なリソースが不足した際に、どのPodを退避させるかを決定するために、このクラスを利用します。
Quality of Serviceクラス Kubernetesは、実行中のPodを分類し、各Podを特定の Quality of Service(QoS)クラス に割り当てます。
Kubernetesは、このクラスを用いてそれぞれのPodの扱い方を決定します。
分類は、Pod内のコンテナ のリソース要求 と、それらの要求とリソース制限との関連性に基づいて行われます。
これはQuality of Service (QoS)クラスと呼ばれます。
Kubernetesは、Podのコンポーネントであるコンテナのリソース要求と制限に基づいて、すべてのPodにQoSクラスを割り当てます。
QoSクラスは、ノードの圧迫 が発生しているノードからどのPodを退避させるかを決定する際に使用されます。
QoSクラスにはGuaranteed、Burstable、BestEffortがあります。
ノードのリソースが不足すると、KubernetesはまずBestEffort Podを退避し、次にBurstable、最後にGuaranteed Podを退避させます。
リソースの圧迫による退避の場合、リソース要求を超過しているPodのみが退避の候補となります。
Guaranteed GuaranteedのPodは最も厳しいリソース制限を持ち、退避される可能性が最も低いです。
制限を超過するか、ノードからプリエンプト可能なより低い優先度のPodが存在しない限り、強制終了されることはありません。
ただし、指定された制限を超えてリソースを取得することはできません。
これらのPodは、static CPU管理ポリシーを使って、排他的にCPUを利用することもできます。
条件 PodがGuaranteed QoSクラスとして分類されるための条件は以下の通りです:
Pod内のすべてのコンテナが、メモリ制限とメモリ要求を持っていること。
Pod内のすべてのコンテナで、メモリ制限がメモリ要求と等しいこと。
Pod内のすべてのコンテナが、CPU制限とCPU要求を持っていること。
Pod内のすべてのコンテナで、CPU制限がCPU要求と等しいこと。
もしくは、PodがPodレベルのリソース を使用する場合は以下の通りです:
FEATURE STATE:
Beta since Kubernetes v1.34; (デフォルトで有効)
PodがPodレベルのメモリ制限とメモリ要求を持ち、それらの値が等しいこと。
PodがPodレベルのCPU制限とCPU要求を持ち、それらの値が等しいこと。
Burstable BurstableのPodは、要求に基づく下限のリソース保証を持ちますが、特定の制限は必要としません。
制限が指定されていない場合、デフォルトでノードの容量と同等の制限となり、リソースが利用可能であればPodは柔軟にリソースを増やすことができます。
ノードのリソース圧迫によるPod退避の際、これらのPodは、すべてのBestEffort Podが退避されてから退避されます。
Burstable Podには、リソース制限や要求を持たないコンテナを含めることができるため、BurstableなPodは任意の量のノードリソースを使おうとする可能性があります。
条件 以下の場合、PodはBurstable QoSクラスとして分類されます:
PodがGuaranteed QoSクラスの条件を満たさないこと。
Pod内の少なくとも1つのコンテナがメモリまたはCPUの要求または制限を持つか、PodがPodレベルのメモリまたはCPUの要求または制限を持つこと。
BestEffort BestEffort QoSクラスのPodは、他のQoSクラスのPodに明示的に割り当てられていないノードリソースを使用できます。
たとえば、kubeletで利用可能な16個のCPUコアを持つノードがあり、Guaranteed Podに4個のCPUコアを割り当てた場合、BestEffort QoSクラスのPodは、残りの12個のCPUコアのうち任意の量を使うことができます。
kubeletは、ノードがリソース圧迫を受けた場合、BestEffort Podを優先的に退避させます。
条件 Podは、GuaranteedまたはBurstableのいずれの条件も満たさない場合、BestEffort QoSクラスになります。
つまり、Pod内のどのコンテナもメモリ制限またはメモリ要求を持たず、Pod内のどのコンテナもCPU制限またはCPU要求を持たず、PodがPodレベルのメモリまたはCPUの制限または要求を持たない場合にのみ、PodはBestEffortとなります。
Pod内のコンテナは、(CPUまたはメモリ以外の)他のリソースを要求していても、BestEffortとして分類されます。
cgroup v2を使用したメモリQoS
FEATURE STATE:
Beta since Kubernetes v1.37; (デフォルトで有効)
メモリQoSは、cgroup v2のメモリコントローラーを使用して、Kubernetesでメモリリソースを保証します。
Pod内のコンテナのメモリ要求と制限は、メモリコントローラーが提供するmemory.minとmemory.highインターフェースの設定に使用されます。
memory.minがメモリ要求に設定されると、メモリリソースは予約され、カーネルによって回収されることはありません。
これが、メモリQoSがKubernetes Podのメモリ可用性を保証する仕組みです。
また、コンテナでメモリ制限が設定されている場合、システムはコンテナのメモリ使用量を制限する必要があります。
メモリQoSは、memory.highを使用してメモリ制限に近づいているワークロードの動作を抑制し、瞬間的なメモリ割り当てによってシステムが圧迫されないようにします。
メモリQoSは、QoSクラスに基づいてどの設定を適用するか決定しますが、これらは異なるメカニズムであり、どちらもQuality of Serviceに対する制御を提供します。
QoSクラスに依存しない動作 Kubernetesによって割り当てられたQoSクラスとは無関係な動作もあります。
例えば、以下が該当します:
リソース制限を超過したコンテナは、そのPod内の他のコンテナに影響を与えることなく、kubeletによって強制終了され、再起動されます。
コンテナがリソース要求を超過し、実行しているノードがリソース圧迫に直面している場合、そのコンテナが含まれるPodは退避 の候補となります。
このような場合、Pod内のすべてのコンテナが終了されます。
Kubernetesは、通常は別のノード上に、置き換えとなるPodを作成する可能性があります。
Podのリソース要求は、コンポーネントであるコンテナのリソース要求の合計に等しく、Podのリソース制限は、コンポーネントであるコンテナのリソース制限の合計に等しくなります。
kube-schedulerは、どのPodをプリエンプト するかを選択する際に、QoSクラスを考慮しません。
プリエンプションは、クラスター内に、定義したすべてのPodを実行するのに十分なリソースがない場合に発生する可能性があります。
次の項目
8 - Podのホスト名
このページでは、Podのホスト名を設定する方法、その設定後に起こり得る副作用、そして基盤となる仕組みについて説明します。
Podのデフォルトのホスト名 Podが作成されると、(Pod内部から観測される)そのホスト名は、Podのmetadata.nameの値から導き出されます。
ホスト名と、それに対応する完全修飾ドメイン名(FQDN)の両方が(Podの視点からは)metadata.nameの値に設定されます。
apiVersion : v1
kind : Pod
metadata :
name : busybox-1
spec :
containers :
- image : busybox:1.28
command :
- sleep
- "3600"
name : busybox
このmanifestで作成されたPodは、ホスト名と完全修飾ドメイン名(FQDN)がbusybox-1に設定されます。
Podのhostnameとsubdomainフィールド Podのspecには、オプションのhostnameフィールドがあります。
この値が設定されると、Podのmetadata.nameよりも優先され、(Pod内部から観測される)ホスト名として使われます。
例えば、spec.hostnameがmy-hostに設定されているPodは、ホスト名がmy-hostです。
また、Podのspecにはオプションのsubdomainフィールドもあり、Podが自分のNamespace内のサブドメインに属していることを示します。
もしPodのspec.hostnameが"foo"、spec.subdomainが"bar"に設定され、さらにNamespaceがmy-namespaceの場合、ホスト名はfooで、完全修飾ドメイン名(FQDN)は(Podの内部から観測される)foo.bar.my-namespace.svc.cluster-domain.exampleです。
hostnameとsubdomainの両方が設定されていると、クラスターのDNSサーバーはこれらのフィールドに基づいてA/AAAAレコードを作成します。
Podのhostnameとsubdomainフィールド を参照してください。
PodのsetHostnameAsFQDNフィールド
FEATURE STATE:
GA since Kubernetes v1.22
Podが完全修飾ドメイン名(FQDN)を持つように設定されている場合、そのホスト名は短いホスト名です。
例えば、Podの完全修飾ドメイン名がbusybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.exampleの場合、デフォルトではそのPod内でhostnameコマンドを実行するとbusybox-1が返り、hostname --fqdnコマンドを実行するとFQDNが返ります。
setHostnameAsFQDN: trueとsubdomainフィールドがPodのspecに設定されている場合、kubeletはそのPodのNamespaceに対してFQDNをホスト名として書き込みます。
この場合、hostnameとhostname --fqdnの両方がPodのFQDNを返します。
PodのFQDNは前述と同じ方法で構築されます。
つまり、Podのspec.hostname(設定されている場合)またはmetadata.nameフィールド、spec.subdomain、namespace名、そしてクラスタードメインサフィックスで構成されます。
備考: Linuxでは、kernelのhostnameフィールド(struct utsnameのnodenameフィールド)は64文字に制限されています。
Podがこの機能を有効にし、そのFQDNが64文字を超える場合、起動に失敗します。
そのPodはPendingステータスのままになり(kubectlからはContainerCreatingと表示)、"Failed to construct FQDN from Pod hostname and cluster domain"などのエラーイベントが生成されます。
つまり、このフィールドを使う場合、Podのmetadata.name(またはspec.hostname)とspec.subdomainフィールドを組み合わせた長さが64文字を超えないようにする必要があります。
PodのhostnameOverride
FEATURE STATE:
GA since Kubernetes v1.37; (デフォルトで有効)
More information about this feature
This is a stable feature in , and has been since version 1.37. It was first available in the v1.34 release.
PodのspecでhostnameOverrideに値を設定すると、kubeletは無条件にその値をPodのホスト名とFQDN両方に設定します。
hostnameOverrideフィールドには64文字の長さ制限があり、RFC 1123 で定義されているDNSのサブドメイン名の基準に従う必要があります。
例:
apiVersion : v1
kind : Pod
metadata :
name : busybox-2-busybox-example-domain
spec :
hostnameOverride : busybox-2.busybox.example.domain
containers :
- image : busybox:1.28
command :
- sleep
- "3600"
name : busybox
備考: これはPod内のホスト名にのみ影響し、クラスターのDNSサーバーにおけるPodのAレコードやAAAAレコードには影響しません。
hostnameOverrideがhostnameやsubdomainフィールドと同時に設定されている場合:
備考: hostnameOverrideが設定されている場合、hostNetworkとsetHostnameAsFQDNフィールドを同時に設定することはできません。
APIサーバーは、この組み合わせで作成要求が行われた場合、明示的に拒否します。
hostnameOverrideが他のフィールド(hostname、subdomain、setHostnameAsFQDN、hostNetwork)と組み合わされた時の動作の詳細については、KEP-4762の設計詳細 の表を参照してください。
9 - Workload参照
FEATURE STATE:
Beta since Kubernetes v1.37; (デフォルトで無効)
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the GenericWorkload feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
PodをWorkload オブジェクトに紐づけることで、そのPodがより大きなアプリケーションやグループに属していることを示すことができます。
これにより、スケジューラーは各Podを独立したエンティティとして扱うのではなく、グループとしての要件を考慮してスケジューリングを行います。
Workload参照の指定 GenericWorkload フィーチャーゲートが有効な場合、Podマニフェストでspec.workloadRefフィールドを使用できます。
このフィールドは、同じ名前空間内のWorkloadリソースで定義された特定のPodグループへの紐づけを行います。
apiVersion : v1
kind : Pod
metadata :
name : worker-0
namespace : some-ns
spec :
workloadRef :
# 同じ名前空間内のWorkloadオブジェクトの名前
name : training-job-workload
# このWorkload内の特定のPodグループの名前
podGroup : workers
Podグループのレプリカ より複雑なシナリオでは、単一のPodグループを複数の独立したスケジューリング単位に複製できます。
これは、PodのworkloadRef内でpodGroupReplicaKeyフィールドを使用して実現します。
このキーはラベルとして機能し、論理的なサブグループを作成します。
たとえば、minCount: 2のPodグループがあり、4つのPodを作成する場合を考えます。
2つにpodGroupReplicaKey: "0"を、残り2つにpodGroupReplicaKey: "1"を設定すると、それぞれ2つのPodから構成される独立した2つのグループとして扱われます。
spec :
workloadRef :
name : training-job-workload
podGroup : workers
# レプリカキー"0"を持つすべてのworkerは、1つのグループとして一緒にスケジュールされます
podGroupReplicaKey : "0"
動作 workloadRefを定義すると、Podは参照先のPodグループで定義されたポリシー に応じて異なる動作をします。
参照先のグループがbasicポリシーを使用している場合、Workload参照は主にグループ化のためのラベルとして機能します。
参照先のグループがgangポリシーを使用している場合(かつGangScheduling フィーチャーゲートが有効な場合)、Podはgangスケジューリングのライフサイクルに入ります。
この場合、Podはノードにバインドされる前に、グループ内の他のPodが作成され、スケジュールされるのを待ちます。
参照が存在しない場合 スケジューラーは、配置を決定する前にworkloadRefを検証します。
Podが、存在しないWorkloadを参照している場合、またはそのWorkload内で定義されていないPodグループを参照している場合、Podは保留状態のままになります。
存在しないWorkloadオブジェクトを作成するか、不足しているPodGroup定義を含んだWorkloadを再作成するまで、配置の対象とはみなされません。
この動作は、最終的なポリシーがbasicかgangかに関係なく、workloadRefを持つすべてのPodに適用されます。
スケジューラーはポリシーを決定するためにWorkload定義を必要とするためです。
次の項目
10 - Static Pod
Static Pod は、APIサーバー による監視を受けることなく、特定のノード上のkubeletデーモンによって直接管理されます。
コントロールプレーンによって管理されるPod(たとえばDeployment )とは異なり、kubeletが各Static Podを監視し、障害が発生した場合には再起動します。
Static Podは、常に特定のノード上の1つのkubelet に紐付けられます。
Static Podの主な用途は、セルフホスト型のコントロールプレーンを実行することです。
言い換えると、kubeletを使用して個々のコントロールプレーンコンポーネント を管理することです。
たとえば、kubeadm はStatic Podを使用して、コントロールプレーンのノード上でkube-apiserver、kube-controller-manager、kube-scheduler、etcdを実行します。
備考: もしクラスターがコントロールプレーンコンポーネントをPodとして実行している場合、それらはおそらくStatic Podです。
これらのミラーPodは、kube-system名前空間内でkubernetes.io/config.mirrorアノテーションによって識別できます。
ミラーPod kubeletは、各Static Podに対応するミラーPod を、Kubernetes APIサーバー上に自動的に作成しようとします。
これにより、ノード上で実行されているPodはAPIサーバー上で参照できるようになりますが、APIサーバーから制御することはできません。
Pod名には、先頭にハイフンを付けたノードのホスト名がサフィックスとして付加されます。
kubeletは、Static Podからラベル をミラーPodへ伝播します。
これらのラベルは、セレクター を通じて通常どおり使用できます。
kubectlを使用してAPIサーバーからミラーPodを削除しようとしても、kubeletはStatic Podを削除 しません 。
kubeletはミラーPodを再作成します。
制限事項 Static Podのspecは、ServiceAccount 、ConfigMap 、Secret などの他のAPIオブジェクトを参照できません。
Static Podは、エフェメラルコンテナ をサポートしていません。
Static PodとDaemonSetの比較
クラスター化されたKubernetesを実行していて、すべてのノードでPodを実行するためにStatic Podを使用している場合は、代わりにDaemonSet を使用するべきでしょう。
Static Podはコントロールプレーンによって管理されないため、Kubernetesの標準的な仕組みを使用してロールアウト、ロールバック、スケールを行うことはできません。
DaemonSetはこれらの機能を提供しており、ノードレベルのワークロードを実行するための推奨される方法です。
Static Podは、APIサーバーが利用可能になる前にkubeletによって起動されるため、コントロールプレーンコンポーネントのブートストラップに適しています。
DaemonSetは、稼働中のコントロールプレーンを必要とします。
次の項目
11 - ユーザー名前空間
FEATURE STATE:
Beta since Kubernetes v1.30
このページでは、KubernetesのPodにおけるユーザー名前空間 について説明します。
ユーザー名前空間はホストのユーザーとコンテナ内プロセスが利用するユーザーを隔離するものです。
ユーザー名前空間を使うと、コンテナ内でrootとして稼働するプロセスを、ホスト側の異なる(root以外の)ユーザーとして実行することができます。
言い換えれば、ユーザー名前空間内部のリソースの操作に特権をもつプロセスは、名前空間の外側では非特権のプロセスとなっています。
ホストや他のPodに危害を及ぼす、侵害されたコンテナによる被害を軽減するために、この機能を用いることができます。
HIGH ないしは CRITICAL にレートされたいくつかの脆弱性 は、ユーザー名前空間が有効な場合には悪用できないものでした。
ユーザー名前空間は、将来の脆弱性を緩和することも期待できます。
始める前に 備考:  このセクションでは、Kubernetesが必要とする機能を提供するサードパーティプロジェクトにリンクしています。これらのプロジェクトはアルファベット順に記載されていて、Kubernetesプロジェクトの作者は責任を持ちません。このリストにプロジェクトを追加するには、変更を提出する前に
コンテンツガイド をお読みください。
詳細はこちら。
この機能はLinux固有であり、Linuxのファイルシステムでidmapマウントがサポートされている必要があります。
ノード上で/var/lib/kubelet/pods/(ないしはそのカスタムディレクトリとして設定した場所)でidmapマウントがサポートされている必要があります。
Podのボリュームとして使われる全てのファイルシステムがidmapマウントをサポートしている必要があります。
これは、最低でもLinux 6.3以降を利用していて、かつidmapマウントをサポートするtmpfsが必要であることを意味します。
一般的に、いくつかのKubernetesの機能はtmpfsを利用しています。
(デフォルトでは、PodがサービスアカウントトークンやSecretをマウントする時にtmpfsを使っていたりします)。
Linux 6.3でidmapマウントをサポートするポピュラーなファイルシステムはbtrfs、ext4、xfs、fat、tmpfs、overlayfsです。
さらに、コンテナランタイムとその基盤であるOCIランタイムもユーザー名前空間をサポートしている必要があります。
次のOCIランタイムではサポートが提供されています。
crun バージョン1.9以上 (推奨バージョンは1.13以上).
runc バージョン1.2以上
備考: いくつかのOCIランタイムには、LinuxのPodでユーザー名前空間を利用するのに必要なサポートが含まれていません。
マネージドKubernetesを利用している場合やOCIランタイムをパッケージとしてダウンロードしてセットアップした場合には、クラスター内のノードがユーザー名前空間をサポートしない可能性があります。
Kubernetesでユーザー名前空間を利用する際、Podでこの機能を使うためにはCRIコンテナランタイム も必要です。
containerd: バージョン2.0以上ではコンテナのユーザー名前空間をサポート。
CRI-O: バージョン1.25以上でコンテナのユーザー名前空間をサポート。
ユーザー名前空間のサポート状況については、GitHubのissue で確認できます。
導入 Linuxの機能であるユーザー名前空間を用いると、コンテナのユーザーをホスト側の異なるユーザーにマップすることができます。
さらに言えば、ユーザー名前空間においてPodに付与されたケーパビリティ(capability)は、ユーザー名前空間内においてのみ有効で、外側では無効です。
Podはpod.spec.hostUsersフィールドをfalseに設定することで、ユーザー名前空間を使えるようになります。
kubeletはPodに対応する(ホストの)UID/GIDを選択した上で、同一ノードの2つ以上のPodが同じ対応関係にならないよう保証するようにしつつ、ユーザーをマップします。
pod.specにおけるrunAsUserやrunAsGroup、fsGroupなどのフィールドはコンテナ内のユーザーを指すものです。
この機能が有効化された場合、UID/GIDとして正しい値の範囲は0-65535です。
これはファイルとプロセスに対して適用されます。
(runAsUserやrunAsGroupなど)。
この範囲を超えるUID/GIDを利用するファイルはオーバーフローしたID(一般的には65534)に所属するように見えるでしょう。
(/proc/sys/kernel/overflowuidと/proc/sys/kernel/overflowgidで設定されます)。
ただし、これらのファイルは65534のユーザー/グループで稼働するプロセスであっても、編集することはできません。
rootとして動かす必要があるアプリケーションであっても、ホストにおける他のユーザー名前空間や他のリソースに対してアクセスしないものの多くは、ユーザー名前空間を有効化しても動かせますし、アプリケーションを修正しなくても問題なく動作するでしょう。
Podにおけるユーザー名前空間を理解する いくつかのコンテナランタイム(Docker Engineやcontainer、CRI-Oなど)は、デフォルトでユーザー名前空間を利用するように設定されています。
これらのランタイムとその他の既存技術を組み合わせて使うことも可能です。
(例えば、Kata ContainerはLinux名前空間の代わりにVMを利用します)。
このページの内容はLinux名前空間を隔離に使うコンテナランタイムに適用できるものです。
Podを作成する時、デフォルトでは、Podの隔離にいくつかの新しい名前空間が利用されます。
(コンテナネットワークの隔離のためのネットワーク名前空間、プロセスの見える範囲を隔離するためのPID名前空間など)。
ユーザー名前空間を利用する場合には、コンテナ内のユーザーをノードのユーザーと隔離します。
これは、コンテナがrootとしてプロセスを動かせる一方で、ホスト上では非rootユーザーとしてマップされていることを意味します。
コンテナ内部のプロセスはrootとして動作しているものと思っていることでしょう。
(したがって、aptやyumなどは問題なく動作します)。
しかし、実際には、このプロセスにホスト上での特権はありません。
これを検証するには、例えばホスト上でps auxを実行することで、コンテナのプロセスがどのユーザーを使用しているかを確認するとよいでしょう。
psが示すユーザーは、コンテナ内でidを実行した場合に示されるユーザーとは異なっているはずです。
この分離によって、ホスト上で「起こせること」を制限できます。例えばコンテナ内プロセスのホストへのエスケープを処理する場合にこの制限が有効に働きます。
コンテナはホスト上で非特権のユーザーとして動作しているため、ホスト上でできることが制限されているのです。
さらに言えば、それぞれのPodのユーザーは、ホスト上においては異なるユーザーにマップされており、UID/GIDは重複しません。
他のPodに対してできることさえも制限されているのです。
Podに付与されたケーパビリティについても、Podのユーザー名前空間に制限されており、名前空間の外部においてはほとんどが効力を持たず、いくつかのケーパビリティは外部では完全に無効です。
2つの例を挙げます:
CAP_SYS_MODULE がユーザー名前空間を使うPodに付与されている場合、Podはカーネルモジュールをロードできません。
CAP_SYS_ADMIN はPodのユーザー名前空間の内部のみに制限され、名前空間の外部では無効です。
コンテナブレークアウトのケースについて考えてみます。
この場合、ユーザー名前空間を使用せずにコンテナをrootで稼働させていると、ノードのroot権限が取得されます。
さらに、ケーパビリティがコンテナに付与されていた場合には、そのケーパビリティはホスト上でも有効となっています。
ユーザー名前空間を利用していれば、これらはいずれも成立しません。
ユーザー名前空間を使う場合に何が変わるのかについて詳しく知りたい場合には、man 7 user_namespacesを参照してください。
ユーザー名前空間をサポートするノードを設定する ほとんどのLinuxディストリビューションで標準的なUIDである0-65535の範囲については、kubeletはホストのファイルやプロセスがこの範囲のUIDを利用しているものとみなし、デフォルトではこれよりも上のUID/GIDの値をPodに紐付けます。
言い換えれば、0-65535の範囲のIDをPodで使うことはできません。
このアプローチにより、PodとホストのUID/GIDが重複することを防ぎます。
Podによる潜在的な任意のファイル読み出しの脆弱性であるCVE-2021-25741 のような脆弱性の影響を緩和する上で、UID/GIDの重複を防ぐことは重要です。
PodとホストのUID/GIDが重複しなければ、Podができることは限定されます。
(PodのUID/GIDはホスト上のファイル所有者やグループと一致することがないのです)。
kubeletはPodに割り当てるユーザーIDとグループIDの範囲を変更することが可能です。カスタムの範囲を設定するには、ノードが次の条件を満たす必要があります。
ユーザーkubeletがシステム上に存在していること(他のユーザー名を使うことはできません)
getsubidsバイナリ(shadow-utils の一部)がインストールされており、kubeletバイナリが参照するPATHに入っていること
kubeletユーザーのsubordinate UID/GID (man 5 subuid およびman 5 subgid を参照)
これはsubordinate UID/GIDの範囲に関する設定のみを示しており、kubeletを実行するユーザーは変更しません。
ユーザーkubeletに割り当てるsubordinate IDの範囲に関しては、いくつかの制約に従う必要があります。
subordinate UIDの起点(つまりPodのUID範囲の開始位置)が65536の倍数に設定されていて、かつ65536以上であること( 必須 )。
言い換えると、0-65535の範囲をPodのUIDとして使うことはできません。
偶発的にインセキュアな設定がなされることを防ぐために、kubeletはこの制約を強制します。
subordinate UID/GIDの個数が65536の倍数であること(必須)。
subordinate UID/GIDの個数は最低でも65536 x <最大Pod数>であること(必須)。
<最大Pod数>
はノードで稼働できるPodの数の最大値を表します。
UIDとGIDとして同じ個数を割り当てること(必須)。
他のユーザーに対して、GIDの範囲と合致しないUID範囲を指定することは問題ありません。
割り当てられたUID/GID範囲は他の割当と重複しないこと(推奨)。
subordinate UID/GIDの設定は単一行でなされること(必須)。
同一のユーザーに対して複数のUID/GID範囲を定義することはできません。
例えば、ユーザーkubeletのエントリについて、/etc/subuidと/etc/subgidに次のように定義することができます。
# フォーマットは次の通り
# name:firstID:count
# この例における意味
# - firstIDは65536 (とりうる最小の値)
# - countは110 (デフォルトの制限値) * 65536
kubelet:65536:7208960
Podセキュリティのアドミッション検証への統合
FEATURE STATE:
Alpha since Kubernetes v1.29
ユーザー名前空間を有効化したLinuxのPodでは、KubernetesはPod Security Standards で制御されるアプリケーションの制限を緩和します。
この挙動はエンドユーザーの早期オプトインを可能にするためのUserNamespacesPodSecurityStandardsフィーチャーゲート で制御することが可能です。
このフィーチャーゲートを使う場合、クラスター管理者はユーザー名前空間が全てのノードで有効化されていることを確実にする必要があります。
フィーチャーゲートを有効化した上でユーザー名前空間を使うPodを作成する場合、_Baseline_ないしは_Restricted_Podセキュリティ基準のセキュリティコンテキストが強制されていても、以下のフィールドによる制約がなされません。
spec.securityContext.runAsNonRoot
spec.containers[*].securityContext.runAsNonRoot
spec.initContainers[*].securityContext.runAsNonRoot
spec.ephemeralContainers[*].securityContext.runAsNonRoot
spec.securityContext.runAsUser
spec.containers[*].securityContext.runAsUser
spec.initContainers[*].securityContext.runAsUser
spec.ephemeralContainers[*].securityContext.runAsUser
制限 Podでユーザー名前空間を利用する際には、他のホスト名前空間を利用することはできません。
特にhostUsers: falseを設定している場合、次の値を設定することはできません。
hostNetwork: true
hostIPC: true
hostPID: true
次の項目
12 - Downward API
Podやコンテナのフィールドを実行中のコンテナに公開する方法には2つあります。 1つは環境変数で、もう1つは特殊なボリュームタイプによってファイルとして公開する方法です。 これら2つの方法をまとめてDownward APIと呼びます。
Kubernetesに過度に密結合することなく、コンテナが自分自身についての情報を持つことは有用な場合があります。
downward API を用いることで、コンテナはKubernetesのクライアントやAPIサーバーを利用せずに、自分自身やクラスターに関する情報を取得することができます。
例として、特定の既知の環境変数に一意な識別子が格納されていることを前提とする既存のアプリケーションがあるとします。
一つの可能性は、アプリケーションをラップすることですが、これは煩雑でエラーが起こりやすく、疎結合という目標に反します。
より良い選択肢は、Pod名を識別子として使用し、Pod名をその既知の環境変数に注入することです。
Kubernetesでは、実行中のコンテナにPodおよびコンテナフィールドを公開する方法が2つあります:
これらPodおよびコンテナフィールドを公開する2つの方法を総称して、downward API と呼びます。
利用可能なフィールド Kubernetes APIフィールドのうち、downward APIを通じて利用可能なものは一部のみです。
このセクションでは、利用可能なフィールドを列挙します。
利用可能なPodレベルのフィールドからの情報は、fieldRefを使用して渡すことができます。
APIレベルでは、Podのspecは常に少なくとも1つのContainer を定義します。
利用可能なコンテナレベルのフィールドからの情報は、resourceFieldRefを使用して渡すことができます。
fieldRefを通じて利用可能な情報一部のPodレベルフィールドについては、環境変数として、またはdownwardAPIボリュームを使用して、コンテナに提供することができます。
どちらのメカニズムでも利用可能なフィールドは以下の通りです:
metadata.name
Podの名前
metadata.namespace
Podのネームスペース
metadata.uid
Podの一意ID
metadata.annotations['<KEY>']
<KEY>という名前のPodのアノテーション の値(例: metadata.annotations['myannotation'])
metadata.labels['<KEY>']
<KEY>という名前のPodのラベル のテキスト値(例: metadata.labels['mylabel'])
以下の情報は環境変数を通じて利用可能ですが、downwardAPIボリュームのfieldRefとしては利用できません :
spec.serviceAccountName
Podのサービスアカウント の名前
spec.nodeName
Podが実行されているノード の名前
status.hostIP
Podが割り当てられているノードのプライマリIPアドレス
status.hostIPs
status.hostIPのデュアルスタック版のIPアドレスで、最初のIPアドレスは常にstatus.hostIPと同じです
status.podIP
PodのプライマリIPアドレス(通常、IPv4アドレス)
status.podIPs
status.podIPのデュアルスタック版のIPアドレスで、最初のIPアドレスは常にstatus.podIPと同じです
以下の情報はdownwardAPIボリュームのfieldRefを通じて利用可能ですが、環境変数としては利用できません :
metadata.labels
Podのすべてのラベルで、label-key="escaped-label-value"形式でフォーマットされ、1行に1つのラベルが記載されます
metadata.annotations
Podのすべてのアノテーションで、annotation-key="escaped-annotation-value"形式でフォーマットされ、1行に1つのアノテーションが記載されます
resourceFieldRefを通じて利用可能な情報これらのコンテナレベルフィールドを使用すると、CPUやメモリなどのリソースの要求と制限 に関する情報を提供することができます。
備考: <div class="feature-state-notice feature-stable" title="フィーチャーゲート: InPlacePodVerticalScaling">
<span class="feature-state-name">FEATURE STATE:</span>
<span class="feature-state-details">
<span class="feature-state-stage">GA</span> since Kubernetes v1.35
</span>
</div>
<div class="feature-stable">
<details>
<summary>More information about this feature</summary>
<p>This is a stable feature in Kubernetes, and has been since version v1.35. It was first available in the v1.27 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate <tt>InPlacePodVerticalScaling</tt>, Kubernetes ignores it but does not report any error.</p></p>
</details>
</div>
コンテナのCPUとメモリリソースは、コンテナの実行中にリサイズすることができます。
この場合、downward APIボリュームは更新されますが、環境変数はコンテナが再起動されない限り更新されません。
詳細については、コンテナに割り当てるCPUとメモリ容量を変更する を参照してください。
resource: limits.cpu
コンテナのCPU制限
resource: requests.cpu
コンテナのCPU要求
resource: limits.memory
コンテナのメモリ制限
resource: requests.memory
コンテナのメモリ要求
resource: limits.hugepages-*
コンテナのhugepages制限
resource: requests.hugepages-*
コンテナのhugepages要求
resource: limits.ephemeral-storage
コンテナの一時ストレージ制限
resource: requests.ephemeral-storage
コンテナの一時ストレージ要求
リソース制限のフォールバック情報 コンテナにCPUとメモリの制限が指定されておらず、downward APIを使用してその情報を公開しようとする場合、kubeletはノード割り当て可能量 の計算に基づいて、CPUとメモリの最大割り当て可能値をデフォルトで公開します。
次の項目 downwardAPIボリューム について詳しく読むことができます。
downward APIを使用してコンテナレベルまたはPodレベルの情報を公開することを試してみることができます:
13 - 高度なPod設定
このページでは、PriorityClass 、RuntimeClass 、Pod内のセキュリティコンテキスト を含む高度なPod設定に関するトピックを扱い、スケジューリング との関連についても説明します。
PriorityClass PriorityClass を使用すると、他のPodと比較したPodの重要度を設定することができます。
Podに優先度クラスを割り当てると、Kubernetesは指定したPriorityClassに基づいて、そのPodの.spec.priorityフィールドを設定します(ただし、.spec.priorityを直接設定することはできません)。
Podがスケジュールできず、その問題がリソース不足によるものである場合、kube-scheduler は、より高い優先度のPodのスケジューリングを可能にするため、より低い優先度のPodをプリエンプト しようとします。
PriorityClassは、優先度クラス名を整数の優先度値にマッピングするクラスタースコープのAPIオブジェクトです。
数値が大きいほど高い優先度であることを示します。
PriorityClassを定義する apiVersion : scheduling.k8s.io/v1
kind : PriorityClass
metadata :
name : high-priority
value : 10000
globalDefault : false
description : "Priority class for high-priority workloads"
PriorityClassを使用してPodの優先度を指定する apiVersion : v1
kind : Pod
metadata :
name : nginx
spec :
containers :
- name : nginx
image : nginx
priorityClassName : high-priority
ビルトインのPriorityClass Kubernetesは2つのビルトインのPriorityClassを提供します:
system-cluster-critical: クラスターにとって重要なシステムコンポーネント用。
system-node-critical: 個々のノードにとって重要なシステムコンポーネント用。
これはKubernetesでPodが持つことができる最も高い優先度です。
詳細については、Podの優先度とプリエンプション を参照してください。
RuntimeClass RuntimeClass を使用すると、Podの低レベルなコンテナランタイムを指定できます。
これは、異なる分離レベルやランタイム機能が必要な場合など、異なる種類のPodに対して異なるコンテナランタイムを指定したい場合に役立ちます。
Pod定義の例 apiVersion : v1
kind : Pod
metadata :
name : mypod
spec :
runtimeClassName : myclass
containers :
- name : mycontainer
image : nginx
RuntimeClass は、クラスター内の一部またはすべてのノードで利用可能なコンテナランタイムを表すクラスタースコープのオブジェクトです。
クラスター管理者は、RuntimeClassを支える具体的なランタイムをインストールおよび設定します。
管理者は、その特別なコンテナランタイム設定をすべてのノードに設定する場合もあれば、一部のノードのみに設定する場合もあります。
詳細については、RuntimeClass のドキュメントを参照してください。
Podおよびコンテナレベルのセキュリティコンテキスト設定 Pod仕様内のsecurityContextフィールドは、Podとコンテナのセキュリティ設定をきめ細かく制御できます。
Pod全体のsecurityContext セキュリティ設定の中には、Pod全体に適用されるものがあります。
その他の設定については、コンテナレベルでオーバーライドせずにデフォルトを設定することもできます。
以下は、PodレベルでPod全体のsecurityContextを使用する例です:
Pod定義の例 apiVersion : v1
kind : Pod
metadata :
name : security-context-demo
spec :
securityContext : # この設定は、Pod全体に適用されます
runAsUser : 1000
runAsGroup : 3000
fsGroup : 2000
containers :
- name : sec-ctx-demo
image : registry.k8s.io/e2e-test-images/agnhost:2.45
command : [ "sh" , "-c" , "sleep 1h" ]
コンテナレベルのセキュリティコンテキスト 特定のコンテナに対してのみ、セキュリティコンテキストを指定できます。
以下はその例です:
Pod定義の例 apiVersion : v1
kind : Pod
metadata :
name : security-context-demo-2
spec :
containers :
- name : sec-ctx-demo-2
image : gcr.io/google-samples/node-hello:1.0
securityContext :
allowPrivilegeEscalation : false
runAsNonRoot : true
runAsUser : 1000
capabilities :
drop :
- ALL
seccompProfile :
type : RuntimeDefault
セキュリティコンテキストのオプション
ユーザーIDとグループID : コンテナを実行するユーザー/グループを制御します
ケーパビリティ : Linuxケーパビリティを追加または削除します
Seccompプロファイル : セキュリティコンピューティングプロファイル(seccomp)を設定します
SELinuxオプション : SELinuxコンテキストを設定します
AppArmor : 追加のアクセス制御のためにAppArmorプロファイルを設定します
Windowsオプション : Windows固有のセキュリティ設定を行います
注意: Podの
securityContextを使用して、Linuxコンテナで
特権モード を許可することもできます。
特権モードは、
securityContextの他の多くのセキュリティ設定を上書きします。
securityContextの他のフィールドを使用して同等の権限を付与できない場合を除き、この設定を使用することは避けてください。
Podレベルのセキュリティコンテキストで
windowsOptions.hostProcessフラグを設定することで、同様の特権モードでWindowsコンテナを実行できます。
詳細とその手順については、
Windows HostProcess Podの作成 を参照してください。
詳細については、Podまたはコンテナのセキュリティコンテキストの設定 を参照してください。
Podのスケジューリングを制御する Kubernetesは、Podがどのノードにスケジュールされるかを制御するためのいくつかのメカニズムを提供します。
ノードセレクター 最もシンプルな形式のノード選択制約:
apiVersion : v1
kind : Pod
metadata :
name : nginx
spec :
containers :
- name : nginx
image : nginx
nodeSelector :
disktype : ssd
ノードアフィニティ ノードアフィニティを使用すると、Podをスケジュールできるノードを制約するルールを指定できます。
以下は、topology.kubernetes.io/zone ラベルの値に基づいて選択し、特定の大陸(continent)にあるとラベル付けされたノードでの実行を優先するPodの例です。
apiVersion : v1
kind : Pod
metadata :
name : with-node-affinity
spec :
affinity :
nodeAffinity :
requiredDuringSchedulingIgnoredDuringExecution :
nodeSelectorTerms :
- matchExpressions :
- key : topology.kubernetes.io/zone
operator : In
values :
- antarctica-east1
- antarctica-west1
containers :
- name : with-node-affinity
image : registry.k8s.io/pause:3.8
Podアフィニティとアンチアフィニティ ノードアフィニティに加えて、ノード上ですでに実行されている 他のPod のラベルに基づいて、Podがスケジュールされるノードを制約することもできます。
Podアフィニティを使用すると、他のPodとの位置関係に基づいてPodを配置するルールを指定できます。
apiVersion : v1
kind : Pod
metadata :
name : with-pod-affinity
spec :
affinity :
podAffinity :
requiredDuringSchedulingIgnoredDuringExecution :
- labelSelector :
matchExpressions :
- key : app
operator : In
values :
- database
topologyKey : topology.kubernetes.io/zone
containers :
- name : with-pod-affinity
image : registry.k8s.io/pause:3.8
Toleration Toleration を使用すると、一致するTaintを持つノードにPodをスケジュールできます:
apiVersion : v1
kind : Pod
metadata :
name : mypod
spec :
containers :
- name : myapp
image : nginx
tolerations :
- key : "key"
operator : "Equal"
value : "value"
effect : "NoSchedule"
詳細については、ノード上へのPodのスケジューリング を参照してください。
Podのオーバーヘッド Podのオーバーヘッドを使用すると、コンテナのリソース要求とリソース制限に加えて、Podのインフラストラクチャが消費するリソースを考慮できます。
---
apiVersion : node.k8s.io/v1
kind : RuntimeClass
metadata :
name : kvisor-runtime
handler : kvisor-runtime
overhead :
podFixed :
memory : "2Gi"
cpu : "500m"
---
apiVersion : v1
kind : Pod
metadata :
name : mypod
spec :
runtimeClassName : kvisor-runtime
containers :
- name : myapp
image : nginx
resources :
requests :
memory : "64Mi"
cpu : "250m"
limits :
memory : "128Mi"
cpu : "500m"
次の項目