2.3. OpenShift Container Platform クラスターでの Pod の設定
管理者として、Pod に対して効率的なクラスターを作成し、維持することができます。
クラスターの効率性を維持することにより、1 回のみ実行するように設計された Pod をいつ再起動するか、Pod が利用できる帯域幅をいつ制限するか、中断時に Pod をどのように実行させ続けるかなど、Pod が終了するときの動作をツールとして使用して必要な数の Pod が常に実行されるようにし、開発者により良い環境を提供することができます。
2.3.1. 再起動後の Pod の動作方法の設定
Pod 再起動ポリシーは、Pod のコンテナーの終了時に OpenShift Container Platform が応答する方法を決定します。このポリシーは Pod のすべてのコンテナーに適用されます。
以下の値を使用できます。
-
Always
- Pod で正常に終了したコンテナーの再起動を継続的に試みます。指数関数的なバックオフ遅延 (10 秒、20 秒、40 秒) は 5 分に制限されています。デフォルトはAlways
です。 -
OnFailure
: Pod で失敗したコンテナーの継続的な再起動を、5 分を上限として指数関数のバックオフ遅延 (10 秒、20 秒、40 秒) で試行します。 -
Never
: Pod で終了したコンテナーまたは失敗したコンテナーの再起動を試行しません。Pod はただちに失敗し、終了します。
いったんノードにバインドされた Pod は別のノードにはバインドされなくなります。これは、Pod がノードの失敗後も存続するにはコントローラーが必要であることを示しています。
条件 | コントローラーのタイプ | 再起動ポリシー |
---|---|---|
(バッチ計算など) 終了することが予想される Pod | ジョブ |
|
(Web サービスなど) 終了しないことが予想される Pod | レプリケーションコントローラー |
|
マシンごとに 1 回実行される Pod | デーモンセット | すべて |
Pod のコンテナーが失敗し、再起動ポリシーが OnFailure
に設定される場合、Pod はノード上に留まり、コンテナーが再起動します。コンテナーを再起動させない場合には、再起動ポリシーの Never
を使用します。
Pod 全体が失敗すると、OpenShift Container Platform は新規 Pod を起動します。開発者は、アプリケーションが新規 Pod で再起動される可能性に対応しなくてはなりません。とくに、アプリケーションは、一時的なファイル、ロック、以前の実行で生じた未完成の出力などを処理する必要があります。
Kubernetes アーキテクチャーでは、クラウドプロバイダーからの信頼性のあるエンドポイントが必要です。クラウドプロバイダーが停止している場合、kubelet は OpenShift Container Platform が再起動されないようにします。
基礎となるクラウドプロバイダーのエンドポイントに信頼性がない場合は、クラウドプロバイダー統合を使用してクラスターをインストールしないでください。クラスターを、非クラウド環境で実行する場合のようにインストールします。インストール済みのクラスターで、クラウドプロバイダー統合をオンまたはオフに切り替えることは推奨されていません。
OpenShift Container Platform が失敗したコンテナーについて再起動ポリシーを使用する方法の詳細は、Kubernetes ドキュメントの State の例 を参照してください。
2.3.2. Pod で利用可能な帯域幅の制限
QoS (Quality-of-Service) トラフィックシェーピングを Pod に適用し、その利用可能な帯域幅を効果的に制限することができます。(Pod からの) Egress トラフィックは、設定したレートを超えるパケットを単純にドロップするポリシングによって処理されます。(Pod への) Ingress トラフィックは、データを効果的に処理できるようシェーピングでパケットをキューに入れて処理されます。Pod に設定する制限は、他の Pod の帯域幅には影響を与えません。
手順
Pod の帯域幅を制限するには、以下を実行します。
オブジェクト定義 JSON ファイルを作成し、
kubernetes.io/ingress-bandwidth
およびkubernetes.io/egress-bandwidth
アノテーションを使用してデータトラフィックの速度を指定します。たとえば、Pod の egress および ingress の両方の帯域幅を 10M/s に制限するには、以下を実行します。制限が設定された
Pod
オブジェクト定義{ "kind": "Pod", "spec": { "containers": [ { "image": "openshift/hello-openshift", "name": "hello-openshift" } ] }, "apiVersion": "v1", "metadata": { "name": "iperf-slow", "annotations": { "kubernetes.io/ingress-bandwidth": "10M", "kubernetes.io/egress-bandwidth": "10M" } } }
オブジェクト定義を使用して Pod を作成します。
$ oc create -f <file_or_dir_path>
2.3.3. Pod の Disruption Budget (停止状態の予算) を使用して起動している Pod の数を指定する方法
Pod 中断バジェット では、メンテナンスのためのノードのドレインなど、運用中の Pod に対する安全制約を指定できます。
PodDisruptionBudget
は、同時に起動している必要のあるレプリカの最小数またはパーセンテージを指定する API オブジェクトです。これらをプロジェクトに設定することは、ノードのメンテナンス (クラスターのスケールダウンまたはクラスターのアップグレードなどの実行) 時に役立ち、この設定は (ノードの障害時ではなく) 自発的なエビクションの場合にのみ許可されます。
PodDisruptionBudget
オブジェクトの設定は、次の主要な部分で構成されます。
- 一連の Pod に対するラベルのクエリー機能であるラベルセレクター。
同時に利用可能にする必要のある Pod の最小数を指定する可用性レベル。
-
minAvailable
は、中断時にも常に利用可能である必要のある Pod 数です。 -
maxUnavailable
は、中断時に利用不可にできる Pod 数です。
-
Available
は、Ready=True
の状態にある Pod 数を指します。ready=True
は、要求に対応でき、一致するすべてのサービスの負荷分散プールに追加する必要がある Pod を指します。
maxUnavailable
の 0%
または 0
あるいは minAvailable
の 100%
、ないしはレプリカ数に等しい値は許可されますが、これによりノードがドレイン (解放) されないようにブロックされる可能性があります。
OpenShift Container Platform のすべてのマシン設定プールにおける maxUnavailable
のデフォルト設定は 1
です。この値を変更せず、一度に 1 つのコントロールプレーンノードを更新することを推奨します。コントロールプレーンプールのこの値を 3
に変更しないでください。
以下を実行して、Pod の Disruption Budget をすべてのプロジェクトで確認することができます。
$ oc get poddisruptionbudget --all-namespaces
出力例
NAMESPACE NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE openshift-apiserver openshift-apiserver-pdb N/A 1 1 121m openshift-cloud-controller-manager aws-cloud-controller-manager 1 N/A 1 125m openshift-cloud-credential-operator pod-identity-webhook 1 N/A 1 117m openshift-cluster-csi-drivers aws-ebs-csi-driver-controller-pdb N/A 1 1 121m openshift-cluster-storage-operator csi-snapshot-controller-pdb N/A 1 1 122m openshift-cluster-storage-operator csi-snapshot-webhook-pdb N/A 1 1 122m openshift-console console N/A 1 1 116m #...
PodDisruptionBudget
は、最低でも minAvailable
Pod がシステムで実行されている場合は正常であるとみなされます。この制限を超えるすべての Pod はエビクションの対象となります。
Pod の優先順位およびプリエンプションの設定に基づいて、優先順位の低い Pod は Pod の Disruption Budget の要件を無視して削除される可能性があります。
2.3.3.1. Pod の Disruption Budget を使用して起動している Pod 数の指定
同時に起動している必要のあるレプリカの最小数またはパーセンテージは、PodDisruptionBudget
オブジェクトを使用して指定します。
手順
Pod の Disruption Budget を設定するには、以下を実行します。
YAML ファイルを以下のようなオブジェクト定義で作成します。
apiVersion: policy/v1 1 kind: PodDisruptionBudget metadata: name: my-pdb spec: minAvailable: 2 2 selector: 3 matchLabels: name: my-pod
または、以下を実行します。
apiVersion: policy/v1 1 kind: PodDisruptionBudget metadata: name: my-pdb spec: maxUnavailable: 25% 2 selector: 3 matchLabels: name: my-pod
以下のコマンドを実行してオブジェクトをプロジェクトに追加します。
$ oc create -f </path/to/file> -n <project_name>
2.3.3.2. 正常でない Pod のエビクションポリシーの指定
Pod の Disruption Budget (PDB: 停止状態の予算) を使用して同時に利用可能にする必要のある Pod 数を指定する場合、正常でない Pod がエビクション対象とみなされる条件も定義できます。
以下のポリシーから選択できます。
- IfHealthyBudget
- 正常ではない実行中の Pod は、保護されたアプリケーションが停止されない場合に限りエビクトできます。
- AlwaysAllow
正常ではない実行中の Pod は、Pod の Disruption Budget の条件が満たされているかどうかにかかわらずエビクトできます。このポリシーは、Pod が
CrashLoopBackOff
状態でスタックしているアプリケーションやReady
ステータスの報告に失敗しているアプリケーションなど、正常に動作しないアプリケーションをエビクトするために使用できます。注記ノードドレイン中に誤動作するアプリケーションのエビクションをサポートするには、
PodDisruptionBudget
オブジェクトのunhealthyPodEvictionPolicy
フィールドをAlwaysAllow
に設定することを推奨します。デフォルトの動作では、ドレインを続行する前に、アプリケーション Pod が正常になるまで待機します。
手順
PodDisruptionBudget
オブジェクトを定義する YAML ファイルを作成し、正常でない Pod のエビクションポリシーを指定します。pod-disruption-budget.yaml
ファイルの例apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-pdb spec: minAvailable: 2 selector: matchLabels: name: my-pod unhealthyPodEvictionPolicy: AlwaysAllow 1
- 1
- 正常でない Pod エビクションポリシーとして
IfHealthyBudget
またはAlwaysAllow
のいずれかを選択します。unhealthyPodEvictionPolicy
フィールドが空の場合、デフォルトはIfHealthyBudget
です。
以下のコマンドを実行して
PodDisruptionBudget
オブジェクトを作成します。$ oc create -f pod-disruption-budget.yaml
PDB で正常でない Pod のエビクションポリシーが AlwaysAllow
に設定されている場合、ノードをドレイン (解放)、この PDB が保護する正常に動作しないアプリケーションの Pod をエビクトできます。
関連情報
- フィーチャーゲートを使用した機能の有効化
- Kubernetes ドキュメントの Unhealthy Pod Eviction Policy
2.3.4. Critical Pod の使用による Pod の削除の防止
クラスターを十分に機能させるために不可欠であるのに、マスターノードではなく通常のクラスターノードで実行される重要なコンポーネントは多数あります。重要なアドオンをエビクトすると、クラスターが正常に動作しなくなる可能性があります。
Critical とマークされている Pod はエビクトできません。
手順
Pod を Citical にするには、以下を実行します。
Pod
仕様を作成するか、既存の Pod を編集してsystem-cluster-critical
優先順位クラスを含めます。apiVersion: v1 kind: Pod metadata: name: my-pdb spec: template: metadata: name: critical-pod priorityClassName: system-cluster-critical 1
- 1
- ノードからエビクトすべきではない Pod のデフォルトの優先順位クラス。
または、クラスターにとって重要だが、必要に応じて削除できる Pod に
system-node-critical
を指定することもできます。Pod を作成します。
$ oc create -f <file-name>.yaml
2.3.5. ファイル数の多い永続ボリュームを使用する場合の Pod タイムアウトの短縮
ストレージボリュームに多くのファイル (~1,000,000 以上) が含まれている場合、Pod のタイムアウトが発生する可能性があります。
これは、ボリュームがマウントされると、Pod の securityContext
で指定された fsGroup
と一致するように、OpenShift Container Platform が各ボリュームのコンテンツの所有権とパーミッションを再帰的に変更するために発生する可能性があります。ボリュームが大きい場合、所有権とアクセス許可の確認と変更に時間がかかり、Pod の起動が非常に遅くなる可能性があります。
次の回避策のいずれかを適用することで、この遅延を減らすことができます。
- セキュリティーコンテキスト制約 (SCC) を使用して、ボリュームの SELinux の再ラベル付けをスキップします。
-
SCC 内の
fsGroupChangePolicy
フィールドを使用して、OpenShift Container Platform がボリュームの所有権とパーミッションをチェックおよび管理する方法を制御します。 - Cluster Resource Override Operator を使用して SCC を自動的に適用し、SELinux の再ラベル付けを省略します。
- ランタイムクラスを使用して、ボリュームの SELinux 再ラベル付けをスキップします。