ノード


OpenShift Container Platform 4.14

OpenShift Container Platform でのノードの設定および管理

Red Hat OpenShift Documentation Team

概要

このドキュメントでは、クラスターのノード、Pod、コンテナーを設定し管理する方法を説明します。また、Pod のスケジューリングや配置の設定方法、ジョブや DaemonSet を使用してタスクを自動化する方法やクラスターを効率化するための他のタスクなどに関する情報も提供します。

第1章 ノードの概要

1.1. ノードについて

ノードは、Kubernetes クラスター内の仮想マシンまたはベアメタルマシンです。ワーカーノードは、Pod としてグループ化されたアプリケーションコンテナーをホストします。コントロールプレーンノードは、Kubernetes クラスターを制御するために必要なサービスを実行します。OpenShift Container Platform では、コントロールプレーンノードには、OpenShift Container Platform クラスターを管理するための Kubernetes サービス以上のものが含まれています。

クラスター内に安定した正常なノードを持つことは、ホストされたアプリケーションがスムーズに機能するための基本です。OpenShift Container Platform では、ノードを表す Node オブジェクトを介して Node にアクセス、管理、およびモニターできます。OpenShift CLI (oc) または Web コンソールを使用して、ノードで以下の操作を実行できます。

ノードの次のコンポーネントは、Pod の実行を維持し、Kubernetes ランタイム環境を提供するロールを果たします。

コンテナーランタイム
コンテナーランタイムはコンテナーの実行を担当します。Kubernetes は、containerd、cri-o、rktlet、Docker などのいくつかのランタイムを提供します。
Kubelet
Kubelet はノード上で実行され、コンテナーマニフェストを読み取ります。定義されたコンテナーが開始され、実行されていることを確認します。kubelet プロセスは、作業の状態とノードサーバーを維持します。Kubelet は、ネットワークルールとポートフォワーディングを管理します。kubelet は、Kubernetes によってのみ作成されたコンテナーを管理します。
Kube-proxy
Kube-proxy は、クラスター内のすべてのノードで実行され、Kubernetes リソース間のネットワークトラフィックを維持します。Kube プロキシーは、ネットワーク環境が分離され、アクセス可能であることを保証します。
DNS
クラスター DNS は、Kubernetes サービスの DNS レコードを提供する DNS サーバーです。Kubernetes により開始したコンテナーは、DNS 検索にこの DNS サーバーを自動的に含めます。
コントロールプレーンとワーカーノードの概要
読み取り操作

読み取り操作により、管理者または開発者は OpenShift Container Platform クラスター内のノードに関する情報を取得できます。

管理操作

管理者は、次のいくつかのタスクを通じて、OpenShift Container Platform クラスター内のノードを簡単に管理できます。

  • ノードラベルを追加または更新します。ラベルは、Node オブジェクトに適用されるキーと値のペアです。ラベルを使用して Pod のスケジュールを制御できます。
  • カスタムリソース定義 (CRD) または kubeletConfig オブジェクトを使用してノード設定を変更します。
  • Pod のスケジューリングを許可または禁止するようにノードを設定します。Ready ステータスの正常なワーカーノードでは、デフォルトで Pod の配置が許可されますが、コントロールプレーンノードでは許可されません。このデフォルトの動作は、ワーカーノードをスケジュール不可に設定しコントロールプレーンノードをスケジュール可能に 設定することで変更できます。
  • システム予約 設定を使用して、ノードにリソースを割り当てます。OpenShift Container Platform がノードに最適な system-reserved CPU およびメモリーリソースを自動的に決定できるようにするか、ノードに最適なリソースを手動で決定および設定することができます。
  • ノード上のプロセッサーコアの数、ハードリミット、またはその両方に基づいて ノード上で実行できる Pod の数を設定 します。
  • pod anti-affinity を使用してノードを正常に再起動します。
  • コンピュートマシンセットを使用してクラスターをスケールダウンすることにより、クラスターからノードを削除します。ベアメタルクラスターからノードを削除するには、最初にノード上のすべての Pod をドレインしてから、手動でノードを削除する必要があります。
エンハンスメント操作

OpenShift Container Platform を使用すると、ノードへのアクセスと管理以上のことができます。管理者は、ノードで次のタスクを実行して、クラスターをより効率的でアプリケーションに適したものにし、開発者により良い環境を提供できます。

1.2. Pod について

Pod は、ノードに一緒にデプロイされる 1 つ以上のコンテナーです。クラスター管理者は、Pod を定義し、スケジューリングの準備ができている正常なノードで実行するように割り当て、管理することができます。コンテナーが実行されている限り、Pod は実行されます。Pod を定義して実行すると、Pod を変更することはできません。Pod を操作するときに実行できる操作は次のとおりです。

読み取り操作

管理者は、次のタスクを通じてプロジェクト内の Pod に関する情報を取得できます。

管理操作

以下のタスクのリストは、管理者が OpenShift Container Platform クラスターで Pod を管理する方法の概要を示しています。

エンハンスメント操作

OpenShift Container Platform で利用可能なさまざまなツールと機能を使用して、Pod をより簡単かつ効率的に操作できます。次の操作では、これらのツールと機能を使用して Pod をより適切に管理します。

操作ユーザー詳細情報

Horizontal Pod Autoscaler を作成して使用。

開発者

Horizontal Pod Autoscaler を使用して、実行する Pod の最小数と最大数、および Pod がターゲットとする CPU 使用率またはメモリー使用率を指定できます。水平 Pod オートスケーラーを使用すると、Pod を自動的にスケーリング できます。

垂直 Pod オートスケーラーをインストールして使用します

管理者および開発者

管理者は、垂直 Pod オートスケーラーを使用して、リソースとワークロードのリソース要件を監視することにより、クラスターリソースをより適切に使用します。

開発者は、垂直 Pod オートスケーラーを使用して、各 Pod に十分なリソースがあるノードに Pod をスケジュールすることにより、需要が高い時に Pod が稼働し続けるようにします。

デバイスプラグインを使用して外部リソースへのアクセスを提供。

管理者

デバイスプラグイン は、ノード (kubelet の外部) で実行される gRPC サービスであり、特定のハードウェアリソースを管理します。デバイスプラグインをデプロイ して、クラスター間でハードウェアデバイスを使用するための一貫性のある移植可能なソリューションを提供できます。

Secret オブジェクトを使用して Pod に機密データを提供します。

管理者

一部のアプリケーションでは、パスワードやユーザー名などの機密情報が必要です。Secret オブジェクトを使用して、そのような情報をアプリケーション Pod に提供できます。

1.3. コンテナーについて

コンテナーは、OpenShift Container Platform アプリケーションの基本ユニットであり、依存関係、ライブラリー、およびバイナリーとともにパッケージ化されたアプリケーションコードで構成されます。コンテナーは、複数の環境、および物理サーバー、仮想マシン (VM)、およびプライベートまたはパブリッククラウドなどの複数のデプロイメントターゲット間に一貫性をもたらします。

Linux コンテナーテクノロジーは、実行中のプロセスを分離し、指定されたリソースのみへのアクセスを制限するための軽量メカニズムです。管理者は、Linux コンテナーで次のようなさまざまなタスクを実行できます。

OpenShift Container Platform は、Init コンテナー と呼ばれる特殊なコンテナーを提供します。Init コンテナーは、アプリケーションコンテナーの前に実行され、アプリケーションイメージに存在しないユーティリティーまたはセットアップスクリプトを含めることができます。Pod の残りの部分がデプロイされる前に、Init コンテナーを使用してタスクを実行できます。

ノード、Pod、およびコンテナーで特定のタスクを実行する以外に、OpenShift Container Platform クラスター全体を操作して、クラスターの効率とアプリケーション Pod の高可用性を維持できます。

1.4. ノードでの Pod の自動スケーリング

OpenShift Container Platform には、ノード上の Pod の数と Pod に割り当てられたリソースの自動スケーリングに使用できる 3 つのツールがあります。

水平 Pod オートスケーラー

水平 Pod オートスケーラー (HPA) は、レプリケーションコントローラーまたはデプロイメント設定のスケールを、そのレプリケーションコントローラーまたはデプロイメント設定に属する Pod から収集されたメトリクスに基づき自動的に増減できます。

詳細は、水平 Pod オートスケーラーを使用した Pod の自動スケーリング を参照してください。

カスタムメトリクスオートスケーラー

カスタムメトリクスオートスケーラーは、CPU やメモリーに基づくだけではないカスタムメトリクスに基づき、デプロイメント、ステートフルセット、カスタムリソース、またはジョブの Pod 数を自動的に増減できます。

詳細は、Custom Metrics Autoscaler Operator の概要 を参照してください。

Vertical Pod Autoscaler

Vertical Pod Autoscaler (VPA) は、Pod 内のコンテナーの履歴および現在の CPU とメモリーリソースを自動的に確認し、確認された使用値に基づいてリソース制限および要求を更新できます。

詳細は、vertical pod autoscaler を使用した Pod リソースレベルの自動調整 を参照してください。

1.5. OpenShift Container Platform のノードの一般用語集

この用語集では、ノード のコンテンツで使用される一般的な用語を定義しています。

コンテナー
これは、ソフトウェアとそのすべての依存関係を構成する軽量で実行可能なイメージです。コンテナーはオペレーティングシステムを仮想化するため、データセンターからパブリックまたはプライベートクラウド、さらには開発者のラップトップまで、どこでもコンテナーを実行できます。
デーモンセット
Pod のレプリカが OpenShift Container Platform クラスター内の対象となるノードで実行されるようにします。
egress
Pod からのネットワークのアウトバウンドトラフィックを介して外部とデータを共有するプロセス。
ガベージコレクション
終了したコンテナーや実行中の Pod によって参照されていないイメージなどのクラスターリソースをクリーンアップするプロセス。
Horizontal Pod Autoscaler (HPA)
Kubernetes API リソースおよびコントローラーとして実装されます。HPA を使用して、実行する Pod の最小数と最大数を指定できます。Pod がターゲットとする CPU またはメモリーの使用率を指定することもできます。HPA は、特定の CPU またはメモリーのしきい値を超えると、Pod をスケールアウトおよびスケールインします。
Ingress
Pod への着信トラフィック。
ジョブ
完了するまで実行されるプロセス。ジョブは 1 つ以上の Pod オブジェクトを作成し、指定された Pod が正常に完了するようにします。
ラベル
キーと値のペアであるラベルを使用して、Pod などのオブジェクトのサブセットを整理および選択できます。
Node
OpenShift Container Platform クラスター内のワーカーマシン。ノードは、仮想マシン (VM) または物理マシンのいずれかになります。
Node Tuning Operator
Node Tuning Operator を使用すると、TuneD デーモンを使用してノードレベルのチューニングを管理できます。これにより、カスタムチューニング仕様が、デーモンが認識する形式でクラスターで実行されるすべてのコンテナー化された TuneD デーモンに渡されます。デーモンは、ノードごとに 1 つずつ、クラスターのすべてのノードで実行されます。
Self Node Remediation Operator
Operator はクラスターノードで実行され、異常なノードを特定して再起動します。
Pod
OpenShift Container Platform クラスターで実行されている、ボリュームや IP アドレスなどの共有リソースを持つ 1 つ以上のコンテナー。Pod は、定義、デプロイ、および管理される最小のコンピュート単位です。
toleration
taint が一致するノードまたはノードグループで Pod をスケジュールできる (必須ではない) ことを示します。toleration を使用して、スケジューラーが一致する taint を持つ Pod をスケジュールできるようにすることができます。
taint
キー、値、および Effect で構成されるコアオブジェクト。taint と toleration が連携して、Pod が無関係なノードでスケジュールされないようにします。

第2章 Pod の使用

2.1. Pod の使用

Pod は 1 つのホストにデプロイされる 1 つ以上のコンテナーであり、定義され、デプロイされ、管理される最小のコンピュート単位です。

2.1.1. Pod について

Pod はコンテナーに対してマシンインスタンス (物理または仮想) とほぼ同じ機能を持ちます。各 Pod は独自の内部 IP アドレスで割り当てられるため、そのポートスペース全体を所有し、Pod 内のコンテナーはそれらのローカルストレージおよびネットワークを共有できます。

Pod にはライフサイクルがあります。それらは定義された後にノードで実行されるために割り当てられ、コンテナーが終了するまで実行されるか、その他の理由でコンテナーが削除されるまで実行されます。ポリシーおよび終了コードによっては、Pod は終了後に削除されるか、コンテナーのログへのアクセスを有効にするために保持される可能性があります。

OpenShift Container Platform は Pod をほとんどがイミュータブルなものとして処理します。Pod が実行中の場合は Pod に変更を加えることができません。OpenShift Container Platform は既存 Pod を終了し、これを変更された設定、ベースイメージのいずれかまたはその両方で再作成して変更を実装します。Pod は拡張可能なものとしても処理されますが、再作成時に状態を維持しません。そのため、通常 Pod はユーザーから直接管理されるのでははく、ハイレベルのコントローラーで管理される必要があります。

注記

OpenShift Container Platform ノードホストごとの Pod の最大数については、クラスターの制限を参照してください。

警告

レプリケーションコントローラーによって管理されないベア Pod はノードの中断時に再スケジュールされません。

2.1.2. Pod 設定の例

OpenShift Container Platform は、Pod の Kubernetes の概念を活用しています。これはホスト上に共にデプロイされる 1 つ以上のコンテナーであり、定義され、デプロイされ、管理される最小のコンピュート単位です。

以下は、Rails アプリケーションからの Pod の定義例です。これは数多くの Pod の機能を示していますが、それらのほとんどは他のトピックで説明されるため、ここではこれらについて簡単に説明します。

Pod オブジェクト定義 (YAML)

kind: Pod
apiVersion: v1
metadata:
  name: example
  namespace: default
  selfLink: /api/v1/namespaces/default/pods/example
  uid: 5cc30063-0265780783bc
  resourceVersion: '165032'
  creationTimestamp: '2019-02-13T20:31:37Z'
  labels:
    app: hello-openshift 1
  annotations:
    openshift.io/scc: anyuid
spec:
  restartPolicy: Always 2
  serviceAccountName: default
  imagePullSecrets:
    - name: default-dockercfg-5zrhb
  priority: 0
  schedulerName: default-scheduler
  terminationGracePeriodSeconds: 30
  nodeName: ip-10-0-140-16.us-east-2.compute.internal
  securityContext: 3
    seLinuxOptions:
      level: 's0:c11,c10'
  containers: 4
    - resources: {}
      terminationMessagePath: /dev/termination-log
      name: hello-openshift
      securityContext:
        capabilities:
          drop:
            - MKNOD
        procMount: Default
      ports:
        - containerPort: 8080
          protocol: TCP
      imagePullPolicy: Always
      volumeMounts: 5
        - name: default-token-wbqsl
          readOnly: true
          mountPath: /var/run/secrets/kubernetes.io/serviceaccount 6
      terminationMessagePolicy: File
      image: registry.redhat.io/openshift4/ose-ogging-eventrouter:v4.3 7
  serviceAccount: default 8
  volumes: 9
    - name: default-token-wbqsl
      secret:
        secretName: default-token-wbqsl
        defaultMode: 420
  dnsPolicy: ClusterFirst
status:
  phase: Pending
  conditions:
    - type: Initialized
      status: 'True'
      lastProbeTime: null
      lastTransitionTime: '2019-02-13T20:31:37Z'
    - type: Ready
      status: 'False'
      lastProbeTime: null
      lastTransitionTime: '2019-02-13T20:31:37Z'
      reason: ContainersNotReady
      message: 'containers with unready status: [hello-openshift]'
    - type: ContainersReady
      status: 'False'
      lastProbeTime: null
      lastTransitionTime: '2019-02-13T20:31:37Z'
      reason: ContainersNotReady
      message: 'containers with unready status: [hello-openshift]'
    - type: PodScheduled
      status: 'True'
      lastProbeTime: null
      lastTransitionTime: '2019-02-13T20:31:37Z'
  hostIP: 10.0.140.16
  startTime: '2019-02-13T20:31:37Z'
  containerStatuses:
    - name: hello-openshift
      state:
        waiting:
          reason: ContainerCreating
      lastState: {}
      ready: false
      restartCount: 0
      image: openshift/hello-openshift
      imageID: ''
  qosClass: BestEffort

1
Pod には 1 つまたは複数のラベルで "タグ付け" することができ、このラベルを使用すると、一度の操作で Pod グループの選択や管理が可能になります。これらのラベルは、キー/値形式で metadata ハッシュに保存されます。
2
Pod 再起動ポリシーと使用可能な値の AlwaysOnFailure、および Never です。デフォルト値は Always です。
3
OpenShift Container Platform は、コンテナーが特権付きコンテナーとして実行されるか、選択したユーザーとして実行されるかどうかを指定するセキュリティーコンテキストを定義します。デフォルトのコンテキストには多くの制限がありますが、管理者は必要に応じてこれを変更できます。
4
containers は、1 つ以上のコンテナー定義の配列を指定します。
5
コンテナーは外部ストレージボリュームがコンテナー内にマウントされるかどうかを指定します。この場合、OpenShift Container Platform API に対して要求を行うためにレジストリーが必要とする認証情報へのアクセスを保存するためにボリュームがあります。
6
Pod に提供するボリュームを指定します。ボリュームは指定されたパスにマウントされます。コンテナーのルート (/) や、ホストとコンテナーで同じパスにはマウントしないでください。これは、コンテナーに十分な特権が付与されている場合に、ホストシステムを破壊する可能性があります (例: ホストの /dev/pts ファイル)。ホストをマウントするには、/host を使用するのが安全です。
7
Pod 内の各コンテナーは、独自のコンテナーイメージからインスタンス化されます。
8
OpenShift Container Platform API に対して要求する Pod は一般的なパターンです。この場合、serviceAccount フィールドがあり、これは要求を行う際に Pod が認証する必要のあるサービスアカウントユーザーを指定するために使用されます。これにより、カスタムインフラストラクチャーコンポーネントの詳細なアクセス制御が可能になります。
9
Pod は、コンテナーで使用できるストレージボリュームを定義します。この場合、デフォルトのサービスアカウントトークンを含む secret ボリュームのエフェメラルボリュームを提供します。

ファイル数が多い永続ボリュームを Pod に割り当てる場合、それらの Pod は失敗するか、起動に時間がかかる場合があります。詳細は、When using Persistent Volumes with high file counts in OpenShift, why do pods fail to start or take an excessive amount of time to achieve "Ready" state? を参照してください。

注記

この Pod 定義には、Pod が作成され、ライフサイクルが開始された後に OpenShift Container Platform によって自動的に設定される属性が含まれません。Kubernetes Pod ドキュメント には、Pod の機能および目的の詳細が記載されています。

2.1.3. 関連情報

2.2. Pod の表示

管理者として、クラスターで Pod を表示し、それらの Pod および全体としてクラスターの正常性を判別することができます。

2.2.1. Pod について

OpenShift Container Platform は、Pod の Kubernetes の概念を活用しています。これはホスト上に共にデプロイされる 1 つ以上のコンテナーであり、定義され、デプロイされ、管理される最小のコンピュート単位です。Pod はコンテナーに対するマシンインスタンス (物理または仮想) とほぼ同等のものです。

特定のプロジェクトに関連付けられた Pod のリストを表示したり、Pod に関する使用状況の統計を表示したりすることができます。

2.2.2. プロジェクトでの Pod の表示

レプリカの数、Pod の現在のステータス、再起動の数および年数を含む、現在のプロジェクトに関連付けられた Pod のリストを表示できます。

手順

プロジェクトで Pod を表示するには、以下を実行します。

  1. プロジェクトに切り替えます。

    $ oc project <project-name>
  2. 以下のコマンドを実行します。

    $ oc get pods

    以下に例を示します。

    $ oc get pods

    出力例

    NAME                       READY   STATUS    RESTARTS   AGE
    console-698d866b78-bnshf   1/1     Running   2          165m
    console-698d866b78-m87pm   1/1     Running   2          165m

    -o wide フラグを追加して、Pod の IP アドレスと Pod があるノードを表示します。

    $ oc get pods -o wide

    出力例

    NAME                       READY   STATUS    RESTARTS   AGE    IP            NODE                           NOMINATED NODE
    console-698d866b78-bnshf   1/1     Running   2          166m   10.128.0.24   ip-10-0-152-71.ec2.internal    <none>
    console-698d866b78-m87pm   1/1     Running   2          166m   10.129.0.23   ip-10-0-173-237.ec2.internal   <none>

2.2.3. Pod の使用状況に関する統計の表示

コンテナーのランタイム環境を提供する、Pod に関する使用状況の統計を表示できます。これらの使用状況の統計には CPU、メモリー、およびストレージの消費量が含まれます。

前提条件

  • 使用状況の統計を表示するには、cluster-reader 権限が必要です。
  • 使用状況の統計を表示するには、メトリクスをインストールしている必要があります。

手順

使用状況の統計を表示するには、以下を実行します。

  1. 以下のコマンドを実行します。

    $ oc adm top pods

    以下に例を示します。

    $ oc adm top pods -n openshift-console

    出力例

    NAME                         CPU(cores)   MEMORY(bytes)
    console-7f58c69899-q8c8k     0m           22Mi
    console-7f58c69899-xhbgg     0m           25Mi
    downloads-594fcccf94-bcxk8   3m           18Mi
    downloads-594fcccf94-kv4p6   2m           15Mi

  2. ラベルを持つ Pod の使用状況の統計を表示するには、以下のコマンドを実行します。

    $ oc adm top pod --selector=''

    フィルターに使用するセレクター (ラベルクエリー) を選択する必要があります。===、および != をサポートします。

    以下に例を示します。

    $ oc adm top pod --selector='name=my-pod'

2.2.4. リソースログの表示

OpenShift CLI (oc) および Web コンソールでさまざまなリソースのログを表示できます。ログの末尾から読み取られるログ。

前提条件

  • OpenShift CLI (oc) へのアクセスがある。

手順 (UI)

  1. OpenShift Container Platform コンソールで WorkloadsPods に移動するか、調査するリソースから Pod に移動します。

    注記

    ビルドなどの一部のリソースには、直接クエリーする Pod がありません。このような場合は、リソースの Details ページで Logs リンクを特定できます。

  2. ドロップダウンメニューからプロジェクトを選択します。
  3. 調査する Pod の名前をクリックします。
  4. Logs をクリックします。

手順 (CLI)

  • 特定の Pod のログを表示します。

    $ oc logs -f <pod_name> -c <container_name>

    ここでは、以下のようになります。

    -f
    オプション: ログに書き込まれている内容に沿って出力することを指定します。
    <pod_name>
    Pod の名前を指定します。
    <container_name>
    オプション: コンテナーの名前を指定します。Pod に複数のコンテナーがある場合は、コンテナー名を指定する必要があります。

    以下に例を示します。

    $ oc logs ruby-58cd97df55-mww7r
    $ oc logs -f ruby-57f7f4855b-znl92 -c ruby

    ログファイルの内容が出力されます。

  • 特定のリソースのログを表示します。

    $ oc logs <object_type>/<resource_name> 1
    1
    リソースタイプおよび名前を指定します。

    以下に例を示します。

    $ oc logs deployment/ruby

    ログファイルの内容が出力されます。

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

ジョブ

OnFailure または Never

(Web サービスなど) 終了しないことが予想される Pod

レプリケーションコントローラー

Always

マシンごとに 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 の帯域幅を制限するには、以下を実行します。

  1. オブジェクト定義 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"
            }
        }
    }

  2. オブジェクト定義を使用して 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 を指します。

maxUnavailable0% または 0 あるいは minAvailable100%、ないしはレプリカ数に等しい値は許可されますが、これによりノードがドレイン (解放) されないようにブロックされる可能性があります。

警告

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 を設定するには、以下を実行します。

  1. YAML ファイルを以下のようなオブジェクト定義で作成します。

    apiVersion: policy/v1 1
    kind: PodDisruptionBudget
    metadata:
      name: my-pdb
    spec:
      minAvailable: 2  2
      selector:  3
        matchLabels:
          name: my-pod
    1
    PodDisruptionBudgetpolicy/v1 API グループの一部です。
    2
    同時に利用可能である必要のある Pod の最小数。これには、整数またはパーセンテージ (例: 20%) を指定する文字列を使用できます。
    3
    一連のリソースに対するラベルのクエリー。matchLabelsmatchExpressions の結果は論理的に結合されます。プロジェクト内のすべての Pod を選択するには、このパラメーターを空白のままにします (例: selector {})。

    または、以下を実行します。

    apiVersion: policy/v1 1
    kind: PodDisruptionBudget
    metadata:
      name: my-pdb
    spec:
      maxUnavailable: 25% 2
      selector: 3
        matchLabels:
          name: my-pod
    1
    PodDisruptionBudgetpolicy/v1 API グループの一部です。
    2
    同時に利用不可にできる Pod の最大数。これには、整数またはパーセンテージ (例: 20%) を指定する文字列を使用できます。
    3
    一連のリソースに対するラベルのクエリー。matchLabelsmatchExpressions の結果は論理的に結合されます。プロジェクト内のすべての Pod を選択するには、このパラメーターを空白のままにします (例: selector {})。
  2. 以下のコマンドを実行してオブジェクトをプロジェクトに追加します。

    $ 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 が正常になるまで待機します。

手順

  1. 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 です。
  2. 以下のコマンドを実行して PodDisruptionBudget オブジェクトを作成します。

    $ oc create -f pod-disruption-budget.yaml

PDB で正常でない Pod のエビクションポリシーが AlwaysAllow に設定されている場合、ノードをドレイン (解放)、この PDB が保護する正常に動作しないアプリケーションの Pod をエビクトできます。

2.3.4. Critical Pod の使用による Pod の削除の防止

クラスターを十分に機能させるために不可欠であるのに、マスターノードではなく通常のクラスターノードで実行される重要なコンポーネントは多数あります。重要なアドオンをエビクトすると、クラスターが正常に動作しなくなる可能性があります。

Critical とマークされている Pod はエビクトできません。

手順

Pod を Citical にするには、以下を実行します。

  1. 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 を指定することもできます。

  2. 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 再ラベル付けをスキップします。

詳細は、When using Persistent Volumes with high file counts in OpenShift, why do pods fail to start or take an excessive amount of time to achieve "Ready" state? を参照してください。

2.4. Horizontal Pod Autoscaler での Pod の自動スケーリング

開発者として、Horizontal Pod Autoscaler (HPA) を使用して、レプリケーションコントローラーに属する Pod から収集されるメトリクスまたはデプロイメント設定に基づき、OpenShift Container Platform がレプリケーションコントローラーまたはデプロイメント設定のスケールを自動的に増減する方法を指定できます。HPA は、任意のデプロイメント、デプロイメント設定、レプリカセット、レプリケーションコントローラー、またはステートフルセットに対して作成できます。

カスタムメトリクスに基づいて Pod をスケーリングする方法の詳細は、カスタムメトリクスに基づいて Pod を自動的にスケーリングする を参照してください。

注記

他のオブジェクトが提供する特定の機能や動作が必要な場合を除き、Deployment オブジェクトまたは ReplicaSet オブジェクトを使用することを推奨します。これらのオブジェクトの詳細は、デプロイメントについて を参照してください。

2.4.1. Horizontal Pod Autoscaler について

Horizontal Pod Autoscaler を作成することで、実行する Pod の最小数と最大数を指定するだけでなく、Pod がターゲットに設定する CPU の使用率またはメモリー使用率を指定することができます。

Horizontal Pod Autoscaler を作成すると、OpenShift Container Platform は Pod で CPU またはメモリーリソースのメトリックのクエリーを開始します。メトリックが利用可能になると、Horizontal Pod Autoscaler は必要なメトリックの使用率に対する現在のメトリックの使用率の割合を計算し、随時スケールアップまたはスケールダウンを実行します。クエリーとスケーリングは一定間隔で実行されますが、メトリックが利用可能になるでに 1 分から 2 分の時間がかかる場合があります。

レプリケーションコントローラーの場合、このスケーリングはレプリケーションコントローラーのレプリカに直接対応します。デプロイメント設定の場合、スケーリングはデプロイメント設定のレプリカ数に直接対応します。自動スケーリングは Complete フェーズの最新デプロイメントにのみ適用されることに注意してください。

OpenShift Container Platform はリソースに自動的に対応し、起動時などのリソースの使用が急増した場合など必要のない自動スケーリングを防ぎます。unready 状態の Pod には、スケールアップ時の使用率が 0 CPU と指定され、Autoscaler はスケールダウン時にはこれらの Pod を無視します。既知のメトリックのない Pod にはスケールアップ時の使用率が 0% CPU、スケールダウン時に 100% CPU となります。これにより、HPA の決定時に安定性が増します。この機能を使用するには、readiness チェックを設定して新規 Pod が使用可能であるかどうかを判別します。

Horizontal Pod Autoscaler を使用するには、クラスターの管理者はクラスターメトリックを適切に設定している必要があります。

2.4.1.1. サポートされるメトリック

以下のメトリックは Horizontal Pod Autoscaler でサポートされています。

表2.1 メトリクス
メトリック説明API バージョン

CPU の使用率

使用されている CPU コアの数。Pod の要求される CPU の割合の計算に使用されます。

autoscaling/v1autoscaling/v2

メモリーの使用率

使用されているメモリーの量。Pod の要求されるメモリーの割合の計算に使用されます。

autoscaling/v2

重要

メモリーベースの自動スケーリングでは、メモリー使用量がレプリカ数と比例して増減する必要があります。平均的には以下のようになります。

  • レプリカ数が増えると、Pod ごとのメモリー (作業セット) の使用量が全体的に減少します。
  • レプリカ数が減ると、Pod ごとのメモリー使用量が全体的に増加します。

OpenShift Container Platform Web コンソールを使用して、アプリケーションのメモリー動作を確認し、メモリーベースの自動スケーリングを使用する前にアプリケーションがそれらの要件を満たしていることを確認します。

以下の例は、image-registry Deployment オブジェクトの自動スケーリングを示しています。最初のデプロイメントでは 3 つの Pod が必要です。HPA オブジェクトは、最小値を 5 に増やします。Pod の CPU 使用率が 75% に達すると、Pod は 7 まで増加します。

$ oc autoscale deployment/image-registry --min=5 --max=7 --cpu-percent=75

出力例

horizontalpodautoscaler.autoscaling/image-registry autoscaled

minReplicas が 3 に設定された image-registry Deployment オブジェクトのサンプル HPA

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: image-registry
  namespace: default
spec:
  maxReplicas: 7
  minReplicas: 3
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: image-registry
  targetCPUUtilizationPercentage: 75
status:
  currentReplicas: 5
  desiredReplicas: 0

  1. デプロイメントの新しい状態を表示します。

    $ oc get deployment image-registry

    デプロイメントには 5 つの Pod があります。

    出力例

    NAME             REVISION   DESIRED   CURRENT   TRIGGERED BY
    image-registry   1          5         5         config

2.4.2. HPA はどのように機能するか

Horizontal Pod Autoscaler (HPA) は、Pod オートスケーリングの概念を拡張するものです。HPA を使用すると、負荷分散されたノードグループを作成および管理できます。HPA は、所定の CPU またはメモリーのしきい値を超えると、Pod 数を自動的に増減させます。

図2.1 HPA の高レベルのワークフロー

workflow

HPA は、Kubernetes 自動スケーリング API グループの API リソースです。オートスケーラは制御ループとして動作し、同期期間のデフォルトは 15 秒です。この期間中、コントローラーマネージャーは、HPA の YAML ファイルに定義されている CPU、メモリー使用率、またはその両方を照会します。コントローラーマネージャーは、HPA の対象となる Pod ごとに、CPU やメモリーなどの Pod 単位のリソースメトリックをリソースメトリック API から取得します。

使用率の目標値が設定されている場合、コントローラーは、各 Pod のコンテナーにおける同等のリソース要求のパーセンテージとして使用率の値を計算します。次に、コントローラーは、対象となるすべての Pod の使用率の平均を取り、必要なレプリカの数をスケーリングするために使用される比率を生成します。HPA は、メトリクスサーバーが提供する metrics.k8s.io からメトリクスを取得するよう設定されています。メトリック評価は動的な性質を持っているため、レプリカのグループに対するスケーリング中にレプリカの数が変動する可能性があります。

注記

HPA を実装するには、対象となるすべての Pod のコンテナーにリソース要求が設定されている必要があります。

2.4.3. 要求と制限について

スケジューラーは、Pod 内のコンテナーに対して指定したリソース要求をもとに、どのノードに Pod を配置するかを決定します。kubelet は、コンテナーに指定されたリソース制限を適用して、コンテナーが指定された制限を超えて使用できないようにします。kubelet は、そのコンテナーが使用するために、そのシステムリソースの要求量も予約します。

リソースメトリックの使用方法

Pod の仕様では、CPU やメモリーなどのリソース要求を指定する必要があります。HPA はこの仕様を使用してリソース使用率を決定し、ターゲットを増減させます。

たとえば、HPA オブジェクトは次のメトリックソースを使用します。

type: Resource
resource:
  name: cpu
  target:
    type: Utilization
    averageUtilization: 60

この例では、HPA はスケーリングターゲットの Pod の平均使用率を 60% に維持しています。使用率とは、Pod の要求リソースに対する現在のリソース使用量の比率です。

2.4.4. ベストプラクティス

すべての Pod にリソース要求が設定されていること

HPA は、OpenShift Container Platform クラスター内の Pod の CPU またはメモリー使用率の観測値に基づいてスケーリング判定を行います。使用率の値は、各 Pod のリソース要求のパーセンテージとして計算されます。リソース要求値が欠落していると、HPA の最適性能に影響を与える可能性があります。

クールダウン期間の設定

Horizontal Pod Autoscaler の実行中に、時間差なしにイベントが急速にスケーリングされる場合があります。頻繁なレプリカの変動を防ぐために、クールダウン期間を設定します。stabilizationWindowSeconds フィールドを設定することで、クールダウン期間を指定できます。安定化ウィンドウは、スケーリングに使用するメトリックが変動し続ける場合に、レプリカ数の変動を制限するために使用されます。自動スケーリングアルゴリズムは、このウィンドウを使用して、以前の望ましい状態を推測し、ワークロードスケールへの不要な変更を回避します。

たとえば、scaleDown フィールドに安定化ウィンドウが指定されています。

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300

上記の例では、過去 5 分間のすべての望ましい状態が考慮されます。これはローリングの最大値に近似しており、スケーリングアルゴリズムが Pod を頻繁に削除して、すぐ後に同等の Pod の再作成をトリガーすることを回避します。

2.4.4.1. スケーリングポリシー

autoscaling/v2 API を使用すると、スケーリングポリシー を Horizontal Pod Autoscaler に追加できます。スケーリングポリシーは、OpenShift Container Platform の Horizontal Pod Autoscaler (HPA) が Pod をスケーリングする方法を制御します。スケーリングポリシーにより、特定の期間にスケーリングするように特定の数または特定のパーセンテージを設定して、HPA が Pod をスケールアップまたはスケールダウンするレートを制限できます。固定化ウィンドウ (stabilization window) を定義することもできます。これはメトリックが変動する場合に、先に計算される必要な状態を使用してスケーリングを制御します。同じスケーリングの方向に複数のポリシーを作成し、変更の量に応じて使用するポリシーを判別することができます。タイミングが調整された反復によりスケーリングを制限することもできます。HPA は反復時に Pod をスケーリングし、その後の反復で必要に応じてスケーリングを実行します。

スケーリングポリシーを適用するサンプル HPA オブジェクト

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-resource-metrics-memory
  namespace: default
spec:
  behavior:
    scaleDown: 1
      policies: 2
      - type: Pods 3
        value: 4 4
        periodSeconds: 60 5
      - type: Percent
        value: 10 6
        periodSeconds: 60
      selectPolicy: Min 7
      stabilizationWindowSeconds: 300 8
    scaleUp: 9
      policies:
      - type: Pods
        value: 5 10
        periodSeconds: 70
      - type: Percent
        value: 12 11
        periodSeconds: 80
      selectPolicy: Max
      stabilizationWindowSeconds: 0
...

1
scaleDown または scaleUp のいずれかのスケーリングポリシーの方向を指定します。この例では、スケールダウンのポリシーを作成します。
2
スケーリングポリシーを定義します。
3
ポリシーが反復時に特定の Pod の数または Pod のパーセンテージに基づいてスケーリングするかどうかを決定します。デフォルト値は pods です。
4
反復ごとに Pod の数または Pod のパーセンテージのいずれかでスケーリングの量を制限します。Pod 数でスケールダウンする際のデフォルト値はありません。
5
スケーリングの反復の長さを決定します。デフォルト値は 15 秒です。
6
パーセンテージでのスケールダウンのデフォルト値は 100% です。
7
複数のポリシーが定義されている場合は、最初に使用するポリシーを決定します。最大限の変更を許可するポリシーを使用するように Max を指定するか、最小限の変更を許可するポリシーを使用するように Min を指定するか、HPA がポリシーの方向でスケーリングしないように Disabled を指定します。デフォルト値は Max です。
8
HPA が必要とされる状態で遡る期間を決定します。デフォルト値は 0 です。
9
この例では、スケールアップのポリシーを作成します。
10
Pod 数によるスケールアップの量を制限します。Pod 数をスケールアップするためのデフォルト値は 4% です。
11
Pod のパーセンテージによるスケールアップの量を制限します。パーセンテージでスケールアップするためのデフォルト値は 100% です。

スケールダウンポリシーの例

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-resource-metrics-memory
  namespace: default
spec:
...
  minReplicas: 20
...
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Pods
        value: 4
        periodSeconds: 30
      - type: Percent
        value: 10
        periodSeconds: 60
      selectPolicy: Max
    scaleUp:
      selectPolicy: Disabled

この例では、Pod の数が 40 より大きい場合、パーセントベースのポリシーがスケールダウンに使用されます。このポリシーでは、selectPolicy による要求により、より大きな変更が生じるためです。

80 の Pod レプリカがある場合、初回の反復で HPA は Pod を 8 Pod 減らします。これは、1 分間 (periodSeconds: 60) の (type: Percent および value: 10 パラメーターに基づく) 80 Pod の 10% に相当します。次回の反復では、Pod 数は 72 になります。HPA は、残りの Pod の 10% が 7.2 であると計算し、これを 8 に丸め、8 Pod をスケールダウンします。後続の反復ごとに、スケーリングされる Pod 数は残りの Pod 数に基づいて再計算されます。Pod の数が 40 未満の場合、Pod ベースの数がパーセントベースの数よりも大きくなるため、Pod ベースのポリシーが適用されます。HPA は、残りのレプリカ (minReplicas) が 20 になるまで、30 秒 (periodSeconds: 30) で一度に 4 Pod (type: Pods および value: 4) を減らします。

selectPolicy: Disabled パラメーターは HPA による Pod のスケールアップを防ぎます。必要な場合は、レプリカセットまたはデプロイメントセットでレプリカの数を調整して手動でスケールアップできます。

設定されている場合、oc edit コマンドを使用してスケーリングポリシーを表示できます。

$ oc edit hpa hpa-resource-metrics-memory

出力例

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  annotations:
    autoscaling.alpha.kubernetes.io/behavior:\
'{"ScaleUp":{"StabilizationWindowSeconds":0,"SelectPolicy":"Max","Policies":[{"Type":"Pods","Value":4,"PeriodSeconds":15},{"Type":"Percent","Value":100,"PeriodSeconds":15}]},\
"ScaleDown":{"StabilizationWindowSeconds":300,"SelectPolicy":"Min","Policies":[{"Type":"Pods","Value":4,"PeriodSeconds":60},{"Type":"Percent","Value":10,"PeriodSeconds":60}]}}'
...

2.4.5. Web コンソールを使用した Horizontal Pod Autoscaler の作成

Web コンソールから、Deployment または DeploymentConfig オブジェクトで実行する Pod の最小および最大数を指定する Horizontal Pod Autoscaler (HPA) を作成できます。Pod がターゲットに設定する CPU またはメモリー使用量を定義することもできます。

注記

HPA は、Operator がサポートするサービス、Knative サービス、または Helm チャートの一部であるデプロイメントに追加することはできません。

手順

Web コンソールで HPA を作成するには、以下を実行します。

  1. Topology ビューで、ノードをクリックしてサイドペインを表示します。
  2. Actions ドロップダウンリストから、Add HorizontalPodAutoscaler を選択して Add HorizontalPodAutoscaler フォームを開きます。

    図2.2 HorizontalPodAutoscaler の追加

    Add HorizontalPodAutoscaler フォーム
  3. Add HorizontalPodAutoscaler フォームから、名前、最小および最大の Pod 制限、CPU およびメモリーの使用状況を定義し、Save をクリックします。

    注記

    CPU およびメモリー使用量の値のいずれかが見つからない場合は、警告が表示されます。

Web コンソールで HPA を編集するには、以下を実行します。

  1. Topology ビューで、ノードをクリックしてサイドペインを表示します。
  2. Actions ドロップダウンリストから、Edit HorizontalPodAutoscaler を選択し、Horizontal Pod Autoscaler フォームを開きます。
  3. Edit Horizontal Pod Autoscaler フォームから、最小および最大の Pod 制限および CPU およびメモリー使用量を編集し、Save をクリックします。
注記

Web コンソールで Horizontal Pod Autoscaler を作成または編集する際に、Form view から YAML viewに切り替えることができます。

Web コンソールで HPA を削除するには、以下を実行します。

  1. Topology ビューで、ノードをクリックし、サイドパネルを表示します。
  2. Actions ドロップダウンリストから、Remove HorizontalPodAutoscaler を選択します。
  3. 確認のポップアップウィンドウで、Remove をクリックして HPA を削除します。

2.4.6. CLI を使用した CPU 使用率向けの Horizontal Pod Autoscaler の作成

OpenShift Container Platform CLI を使用して、既存のDeploymentDeploymentConfigReplicaSetReplicationController、または StatefulSet オブジェクトを自動的にスケールする Horizontal Pod Autoscaler (HPA) を作成することができます。HPA は、指定された CPU 使用率を維持するために、そのオブジェクトに関連する Pod をスケーリングします。

注記

他のオブジェクトが提供する特定の機能や動作が必要な場合を除き、Deployment オブジェクトまたは ReplicaSet オブジェクトを使用することを推奨します。

HPA は、すべての Pod で指定された CPU 使用率を維持するために、最小数と最大数の間でレプリカ数を増減します。

CPU 使用率について自動スケーリングを行う際に、oc autoscale コマンドを使用し、実行する必要のある Pod の最小数および最大数と Pod がターゲットとして設定する必要のある平均 CPU 使用率を指定することができます。最小値を指定しない場合、Pod には OpenShift Container Platform サーバーからのデフォルト値が付与されます。

特定の CPU 値について自動スケーリングを行うには、ターゲット CPU および Pod の制限のある HorizontalPodAutoscaler オブジェクトを作成します。

前提条件

Horizontal Pod Autoscaler を使用するには、クラスターの管理者はクラスターメトリックを適切に設定している必要があります。メトリクスが設定されているかどうかは、oc describe PodMetrics <pod-name> コマンドを使用して判断できます。メトリックが設定されている場合、出力は以下の Usage の下にある CpuMemory のように表示されます。

$ oc describe PodMetrics openshift-kube-scheduler-ip-10-0-135-131.ec2.internal

出力例

Name:         openshift-kube-scheduler-ip-10-0-135-131.ec2.internal
Namespace:    openshift-kube-scheduler
Labels:       <none>
Annotations:  <none>
API Version:  metrics.k8s.io/v1beta1
Containers:
  Name:  wait-for-host-port
  Usage:
    Memory:  0
  Name:      scheduler
  Usage:
    Cpu:     8m
    Memory:  45440Ki
Kind:        PodMetrics
Metadata:
  Creation Timestamp:  2019-05-23T18:47:56Z
  Self Link:           /apis/metrics.k8s.io/v1beta1/namespaces/openshift-kube-scheduler/pods/openshift-kube-scheduler-ip-10-0-135-131.ec2.internal
Timestamp:             2019-05-23T18:47:56Z
Window:                1m0s
Events:                <none>

手順

CPU 使用率のための Horizontal Pod Autoscaler を作成するには、以下を実行します。

  1. 以下のいずれかを実行します。

    • CPU 使用率のパーセントに基づいてスケーリングするには、既存のオブジェクトとして HorizontalPodAutoscaler オブジェクトを作成します。

      $ oc autoscale <object_type>/<name> \1
        --min <number> \2
        --max <number> \3
        --cpu-percent=<percent> 4
      1
      自動スケーリングするオブジェクトのタイプと名前を指定します。オブジェクトが存在し、DeploymentDeploymentConfig/dcReplicaSet/rsReplicationController/rc、または StatefulSet である必要があります。
      2
      オプションで、スケールダウン時のレプリカの最小数を指定します。
      3
      スケールアップ時のレプリカの最大数を指定します。
      4
      要求された CPU のパーセントで表示された、すべての Pod に対する目標の平均 CPU 使用率を指定します。指定しない場合または負の値の場合、デフォルトの自動スケーリングポリシーが使用されます。

      たとえば、以下のコマンドは image-registry Deployment オブジェクトの自動スケーリングを示しています。最初のデプロイメントでは 3 つの Pod が必要です。HPA オブジェクトは、最小値を 5 に増やします。Pod の CPU 使用率が 75% に達すると、Pod は 7 まで増加します。

      $ oc autoscale deployment/image-registry --min=5 --max=7 --cpu-percent=75
    • 特定の CPU 値に合わせてスケーリングするには、既存のオブジェクトに対して次のような YAML ファイルを作成します。

      1. 以下のような YAML ファイルを作成します。

        apiVersion: autoscaling/v2 1
        kind: HorizontalPodAutoscaler
        metadata:
          name: cpu-autoscale 2
          namespace: default
        spec:
          scaleTargetRef:
            apiVersion: apps/v1 3
            kind: Deployment 4
            name: example 5
          minReplicas: 1 6
          maxReplicas: 10 7
          metrics: 8
          - type: Resource
            resource:
              name: cpu 9
              target:
                type: AverageValue 10
                averageValue: 500m 11
        1
        autoscaling/v2 API を使用します。
        2
        この Horizontal Pod Autoscaler オブジェクトの名前を指定します。
        3
        スケーリングするオブジェクトの API バージョンを指定します。
        • DeploymentReplicaSetStatefulset オブジェクトの場合は、apps/v1 を使用します。
        • ReplicationController の場合は、v1 を使用します。
        • DeploymentConfig の場合は、apps.openshift.io/v1 を使用します。
        4
        オブジェクトのタイプを指定します。オブジェクトは、DeploymentDeploymentConfig/dcReplicaSet/rsReplicationController/rc、または StatefulSet である必要があります。
        5
        スケーリングするオブジェクトの名前を指定します。オブジェクトが存在する必要があります。
        6
        スケールダウン時のレプリカの最小数を指定します。
        7
        スケールアップ時のレプリカの最大数を指定します。
        8
        メモリー使用率に metrics パラメーターを使用します。
        9
        CPU 使用率に cpu を指定します。
        10
        AverageValue に設定します。
        11
        ターゲットに設定された CPU 値で averageValue に設定します。
      2. Horizontal Pod Autoscaler を作成します。

        $ oc create -f <file-name>.yaml
  2. Horizontal Pod Autoscaler が作成されていることを確認します。

    $ oc get hpa cpu-autoscale

    出力例

    NAME            REFERENCE            TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
    cpu-autoscale   Deployment/example   173m/500m       1         10        1          20m

2.4.7. CLI を使用したメモリー使用率向けの Horizontal Pod Autoscaler オブジェクトの作成

OpenShift Container Platform CLI を使用して、既存のDeploymentDeploymentConfigReplicaSetReplicationController、または StatefulSet オブジェクトを自動的にスケールする Horizontal Pod Autoscaler (HPA) を作成することができます。HPA は、指定した平均メモリー使用率 (直接値または要求メモリーに対する割合) を維持するように、そのオブジェクトに関連する Pod をスケーリングします。

注記

他のオブジェクトが提供する特定の機能や動作が必要な場合を除き、Deployment オブジェクトまたは ReplicaSet オブジェクトを使用することを推奨します。

HPA は、すべての Pod で指定のメモリー使用率を維持するために、最小数と最大数の間でレプリカ数を増減します。

メモリー使用率については、Pod の最小数および最大数と、Pod がターゲットとする平均のメモリー使用率を指定することができます。最小値を指定しない場合、Pod には OpenShift Container Platform サーバーからのデフォルト値が付与されます。

前提条件

Horizontal Pod Autoscaler を使用するには、クラスターの管理者はクラスターメトリックを適切に設定している必要があります。メトリクスが設定されているかどうかは、oc describe PodMetrics <pod-name> コマンドを使用して判断できます。メトリックが設定されている場合、出力は以下の Usage の下にある CpuMemory のように表示されます。

$ oc describe PodMetrics openshift-kube-scheduler-ip-10-0-129-223.compute.internal -n openshift-kube-scheduler

出力例

Name:         openshift-kube-scheduler-ip-10-0-129-223.compute.internal
Namespace:    openshift-kube-scheduler
Labels:       <none>
Annotations:  <none>
API Version:  metrics.k8s.io/v1beta1
Containers:
  Name:  wait-for-host-port
  Usage:
    Cpu:     0
    Memory:  0
  Name:      scheduler
  Usage:
    Cpu:     8m
    Memory:  45440Ki
Kind:        PodMetrics
Metadata:
  Creation Timestamp:  2020-02-14T22:21:14Z
  Self Link:           /apis/metrics.k8s.io/v1beta1/namespaces/openshift-kube-scheduler/pods/openshift-kube-scheduler-ip-10-0-129-223.compute.internal
Timestamp:             2020-02-14T22:21:14Z
Window:                5m0s
Events:                <none>

手順

メモリー使用率の Horizontal Pod Autoscaler を作成するには、以下を実行します。

  1. 以下のいずれか 1 つを含む YAML ファイルを作成します。

    • 特定のメモリー値についてスケーリングするには、既存のオブジェクトについて以下のような HorizontalPodAutoscaler オブジェクトを作成します。

      apiVersion: autoscaling/v2 1
      kind: HorizontalPodAutoscaler
      metadata:
        name: hpa-resource-metrics-memory 2
        namespace: default
      spec:
        scaleTargetRef:
          apiVersion: apps/v1 3
          kind: Deployment 4
          name: example 5
        minReplicas: 1 6
        maxReplicas: 10 7
        metrics: 8
        - type: Resource
          resource:
            name: memory 9
            target:
              type: AverageValue 10
              averageValue: 500Mi 11
        behavior: 12
          scaleDown:
            stabilizationWindowSeconds: 300
            policies:
            - type: Pods
              value: 4
              periodSeconds: 60
            - type: Percent
              value: 10
              periodSeconds: 60
            selectPolicy: Max
      1
      autoscaling/v2 API を使用します。
      2
      この Horizontal Pod Autoscaler オブジェクトの名前を指定します。
      3
      スケーリングするオブジェクトの API バージョンを指定します。
      • DeploymentReplicaSet、または Statefulset オブジェクトの場合は、apps/v1 を使用します。
      • ReplicationController の場合は、v1 を使用します。
      • DeploymentConfig の場合は、apps.openshift.io/v1 を使用します。
      4
      オブジェクトのタイプを指定します。オブジェクトは、DeploymentDeploymentConfigReplicaSetReplicationController、またはStatefulSet である必要があります。
      5
      スケーリングするオブジェクトの名前を指定します。オブジェクトが存在する必要があります。
      6
      スケールダウン時のレプリカの最小数を指定します。
      7
      スケールアップ時のレプリカの最大数を指定します。
      8
      メモリー使用率に metrics パラメーターを使用します。
      9
      メモリー使用率の memory を指定します。
      10
      タイプを AverageValue に設定します。
      11
      averageValue および特定のメモリー値を指定します。
      12
      オプション: スケールアップまたはスケールダウンのレートを制御するスケーリングポリシーを指定します。
    • パーセンテージでスケーリングするには、既存のオブジェクトに対して、次のような HorizontalPodAutoscaler オブジェクトを作成します。

      apiVersion: autoscaling/v2 1
      kind: HorizontalPodAutoscaler
      metadata:
        name: memory-autoscale 2
        namespace: default
      spec:
        scaleTargetRef:
          apiVersion: apps/v1 3
          kind: Deployment 4
          name: example 5
        minReplicas: 1 6
        maxReplicas: 10 7
        metrics: 8
        - type: Resource
          resource:
            name: memory 9
            target:
              type: Utilization 10
              averageUtilization: 50 11
        behavior: 12
          scaleUp:
            stabilizationWindowSeconds: 180
            policies:
            - type: Pods
              value: 6
              periodSeconds: 120
            - type: Percent
              value: 10
              periodSeconds: 120
            selectPolicy: Max
      1
      autoscaling/v2 API を使用します。
      2
      この Horizontal Pod Autoscaler オブジェクトの名前を指定します。
      3
      スケーリングするオブジェクトの API バージョンを指定します。
      • ReplicationController の場合は、v1 を使用します。
      • DeploymentConfig については、apps.openshift.io/v1 を使用します。
      • Deployment、ReplicaSet、Statefulset オブジェクトの場合は、apps/v1 を使用します。
      4
      オブジェクトのタイプを指定します。オブジェクトは、DeploymentDeploymentConfigReplicaSetReplicationController、またはStatefulSet である必要があります。
      5
      スケーリングするオブジェクトの名前を指定します。オブジェクトが存在する必要があります。
      6
      スケールダウン時のレプリカの最小数を指定します。
      7
      スケールアップ時のレプリカの最大数を指定します。
      8
      メモリー使用率に metrics パラメーターを使用します。
      9
      メモリー使用率の memory を指定します。
      10
      Utilization に設定します。
      11
      averageUtilization およびターゲットに設定する平均メモリー使用率をすべての Pod に対して指定します (要求されるメモリーのパーセントで表す)。ターゲット Pod にはメモリー要求が設定されている必要があります。
      12
      オプション: スケールアップまたはスケールダウンのレートを制御するスケーリングポリシーを指定します。
  2. Horizontal Pod Autoscaler を作成します。

    $ oc create -f <file-name>.yaml

    以下に例を示します。

    $ oc create -f hpa.yaml

    出力例

    horizontalpodautoscaler.autoscaling/hpa-resource-metrics-memory created

  3. Horizontal Pod Autoscaler が作成されていることを確認します。

    $ oc get hpa hpa-resource-metrics-memory

    出力例

    NAME                          REFERENCE            TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
    hpa-resource-metrics-memory   Deployment/example   2441216/500Mi   1         10        1          20m

    $ oc describe hpa hpa-resource-metrics-memory

    出力例

    Name:                        hpa-resource-metrics-memory
    Namespace:                   default
    Labels:                      <none>
    Annotations:                 <none>
    CreationTimestamp:           Wed, 04 Mar 2020 16:31:37 +0530
    Reference:                   Deployment/example
    Metrics:                     ( current / target )
      resource memory on pods:   2441216 / 500Mi
    Min replicas:                1
    Max replicas:                10
    ReplicationController pods:  1 current / 1 desired
    Conditions:
      Type            Status  Reason              Message
      ----            ------  ------              -------
      AbleToScale     True    ReadyForNewScale    recommended size matches current size
      ScalingActive   True    ValidMetricFound    the HPA was able to successfully calculate a replica count from memory resource
      ScalingLimited  False   DesiredWithinRange  the desired count is within the acceptable range
    Events:
      Type     Reason                   Age                 From                       Message
      ----     ------                   ----                ----                       -------
      Normal   SuccessfulRescale        6m34s               horizontal-pod-autoscaler  New size: 1; reason: All metrics below target

2.4.8. CLI を使用した Horizontal Pod Autoscaler の状態条件について

状態条件セットを使用して、Horizontal Pod Autoscaler (HPA) がスケーリングできるかどうかや、現時点でこれがいずれかの方法で制限されているかどうかを判別できます。

HPA の状態条件は、自動スケーリング API の v2 バージョンで利用できます。

HPA は、以下の状態条件で応答します。

  • AbleToScale 条件では、HPA がメトリックを取得して更新できるか、またバックオフ関連の条件によりスケーリングが回避されるかどうかを指定します。

    • True 条件はスケーリングが許可されることを示します。
    • False 条件は指定される理由によりスケーリングが許可されないことを示します。
  • ScalingActive 条件は、HPA が有効にされており (ターゲットのレプリカ数がゼロでない)、必要なメトリックを計算できるかどうかを示します。

    • True 条件はメトリックが適切に機能していることを示します。
    • False 条件は通常フェッチするメトリックに関する問題を示します。
  • ScalingLimited 条件は、必要とするスケールが Horizontal Pod Autoscaler の最大値または最小値によって制限されていたことを示します。

    • True 条件は、スケーリングするためにレプリカの最小または最大数を引き上げるか、引き下げる必要があることを示します。
    • False 条件は、要求されたスケーリングが許可されることを示します。

      $ oc describe hpa cm-test

      出力例

      Name:                           cm-test
      Namespace:                      prom
      Labels:                         <none>
      Annotations:                    <none>
      CreationTimestamp:              Fri, 16 Jun 2017 18:09:22 +0000
      Reference:                      ReplicationController/cm-test
      Metrics:                        ( current / target )
        "http_requests" on pods:      66m / 500m
      Min replicas:                   1
      Max replicas:                   4
      ReplicationController pods:     1 current / 1 desired
      Conditions: 1
        Type              Status    Reason              Message
        ----              ------    ------              -------
        AbleToScale       True      ReadyForNewScale    the last scale time was sufficiently old as to warrant a new scale
        ScalingActive     True      ValidMetricFound    the HPA was able to successfully calculate a replica count from pods metric http_request
        ScalingLimited    False     DesiredWithinRange  the desired replica count is within the acceptable range
      Events:

      1
      Horizontal Pod Autoscaler の状況メッセージです。

以下は、スケーリングできない Pod の例です。

出力例

Conditions:
  Type         Status  Reason          Message
  ----         ------  ------          -------
  AbleToScale  False   FailedGetScale  the HPA controller was unable to get the target's current scale: no matches for kind "ReplicationController" in group "apps"
Events:
  Type     Reason          Age               From                       Message
  ----     ------          ----              ----                       -------
  Warning  FailedGetScale  6s (x3 over 36s)  horizontal-pod-autoscaler  no matches for kind "ReplicationController" in group "apps"

以下は、スケーリングに必要なメトリックを取得できなかった Pod の例です。

出力例

Conditions:
  Type                  Status    Reason                    Message
  ----                  ------    ------                    -------
  AbleToScale           True     SucceededGetScale          the HPA controller was able to get the target's current scale
  ScalingActive         False    FailedGetResourceMetric    the HPA was unable to compute the replica count: failed to get cpu utilization: unable to get metrics for resource cpu: no metrics returned from resource metrics API

以下は、要求される自動スケーリングが要求される最小数よりも小さい場合の Pod の例です。

出力例

Conditions:
  Type              Status    Reason              Message
  ----              ------    ------              -------
  AbleToScale       True      ReadyForNewScale    the last scale time was sufficiently old as to warrant a new scale
  ScalingActive     True      ValidMetricFound    the HPA was able to successfully calculate a replica count from pods metric http_request
  ScalingLimited    False     DesiredWithinRange  the desired replica count is within the acceptable range

2.4.8.1. CLI を使用した Horizontal Pod Autoscaler の状態条件の表示

Pod に設定された状態条件は、Horizontal Pod Autoscaler (HPA) で表示することができます。

注記

Horizontal Pod Autoscaler の状態条件は、自動スケーリング API の v2 バージョンで利用できます。

前提条件

Horizontal Pod Autoscaler を使用するには、クラスターの管理者はクラスターメトリックを適切に設定している必要があります。メトリクスが設定されているかどうかは、oc describe PodMetrics <pod-name> コマンドを使用して判断できます。メトリックが設定されている場合、出力は以下の Usage の下にある CpuMemory のように表示されます。

$ oc describe PodMetrics openshift-kube-scheduler-ip-10-0-135-131.ec2.internal

出力例

Name:         openshift-kube-scheduler-ip-10-0-135-131.ec2.internal
Namespace:    openshift-kube-scheduler
Labels:       <none>
Annotations:  <none>
API Version:  metrics.k8s.io/v1beta1
Containers:
  Name:  wait-for-host-port
  Usage:
    Memory:  0
  Name:      scheduler
  Usage:
    Cpu:     8m
    Memory:  45440Ki
Kind:        PodMetrics
Metadata:
  Creation Timestamp:  2019-05-23T18:47:56Z
  Self Link:           /apis/metrics.k8s.io/v1beta1/namespaces/openshift-kube-scheduler/pods/openshift-kube-scheduler-ip-10-0-135-131.ec2.internal
Timestamp:             2019-05-23T18:47:56Z
Window:                1m0s
Events:                <none>

手順

Pod の状態条件を表示するには、Pod の名前と共に以下のコマンドを使用します。

$ oc describe hpa <pod-name>

以下に例を示します。

$ oc describe hpa cm-test

条件は、出力の Conditions フィールドに表示されます。

出力例

Name:                           cm-test
Namespace:                      prom
Labels:                         <none>
Annotations:                    <none>
CreationTimestamp:              Fri, 16 Jun 2017 18:09:22 +0000
Reference:                      ReplicationController/cm-test
Metrics:                        ( current / target )
  "http_requests" on pods:      66m / 500m
Min replicas:                   1
Max replicas:                   4
ReplicationController pods:     1 current / 1 desired
Conditions: 1
  Type              Status    Reason              Message
  ----              ------    ------              -------
  AbleToScale       True      ReadyForNewScale    the last scale time was sufficiently old as to warrant a new scale
  ScalingActive     True      ValidMetricFound    the HPA was able to successfully calculate a replica count from pods metric http_request
  ScalingLimited    False     DesiredWithinRange  the desired replica count is within the acceptable range

2.4.9. 関連情報

2.5. Vertical Pod Autoscaler を使用した Pod リソースレベルの自動調整

OpenShift Container Platform の Vertical Pod Autoscaler Operator (VPA) は、Pod 内のコンテナーの履歴および現在の CPU とメモリーリソースを自動的に確認し、把握する使用値に基づいてリソース制限および要求を更新できます。VPA は個別のカスタムリソース (CR) を使用して、プロジェクトの DeploymentDeploymentConfigStatefulSetJobDaemonSetReplicaSet、または ReplicationController などのワークロードオブジェクトに関連付けられたすべての Pod を更新します。

VPA は、Pod に最適な CPU およびメモリーの使用状況を理解するのに役立ち、Pod のライフサイクルを通じて Pod のリソースを自動的に維持します。

2.5.1. Vertical Pod Autoscaler Operator について

Vertical Pod Autoscaler Operator (VPA) は、API リソースおよびカスタムリソース (CR) として実装されます。CR は、プロジェクトのデーモンセット、レプリケーションコントローラーなどの特定のワークロードオブジェクトに関連付けられた Pod について Vertical Pod Autoscaler Operator が取るべき動作を判別します。

VPA Operator は 3 つのコンポーネントで構成されており、それぞれのコンポーネントが VPA namespace に独自の Pod を持ちます。

レコメンダー
VPA レコメンダーは、現在および過去のリソース消費を監視し、そのデータに基づき、関連付けられたワークロードオブジェクト内の Pod に最適な CPU およびメモリーリソースを決定します。
アップデーター
VPA アップデーターは、関連付けられたワークロードオブジェクト内の Pod に正しいリソースがあるか確認します。リソースが正しい場合、アップデーターは何も行いません。リソースが正しくない場合、コントローラーが更新されたリクエストを使用して Pod を再作成できるように、アップデーターが Pod を強制終了します。
アドミッションコントローラー
VPA アドミッションコントローラーは、それが新しい Pod か VPA アップデーターのアクションによりコントローラーが再作成した Pod かにかかわらず、関連付けられたワークロードオブジェクト内の新しい Pod ごとに正しいリソースリクエストを設定します。

デフォルトの推奨インストーラーを使用するか、独自のアルゴリズムに基づいて自動スケーリングを実行するために独自の推奨手段を使用できます。

デフォルトのレコメンダーは、それらの Pod 内のコンテナーの履歴および現在の CPU とメモリーの使用状況を自動的に計算し、このデータを使用して、最適化されたリソース制限および要求を判別し、これらの Pod が常時効率的に動作していることを確認することができます。たとえば、デフォルトレコメンダーは使用している量よりも多くのリソースを要求する Pod のリソースを減らし、十分なリソースを要求していない Pod のリソースを増やします。

VPA は、一度に 1 つずつ、これらの推奨値で調整されていない Pod を自動的に削除するため、アプリケーションはダウンタイムなしに継続して要求を提供できます。ワークロードオブジェクトは、元のリソース制限および要求で Pod を再デプロイします。VPA は変更用の受付 Webhook を使用して、Pod がノードに許可される前に最適化されたリソース制限および要求で Pod を更新します。VPA が Pod を削除する必要がない場合は、VPA リソース制限および要求を表示し、必要に応じて Pod を手動で更新できます。

注記

デフォルトで、ワークロードオブジェクトは、VPA が Pod を自動的に削除できるようにするためにレプリカを 2 つ以上指定する必要があります。この最小値よりも少ないレプリカを指定するワークロードオブジェクトは削除されません。これらの Pod を手動で削除すると、ワークロードオブジェクトが Pod を再デプロイします。VPA は推奨内容に基づいて新規 Pod を更新します。この最小値は、VPA の最小値の変更 に記載されているとおり、VerticalPodAutoscalerController オブジェクトを変更して変更できます。

たとえば、CPU の 50% を使用する Pod が 10% しか要求しない場合、VPA は Pod が要求よりも多くの CPU を消費すると判別してその Pod を削除します。レプリカセットなどのワークロードオブジェクトは Pod を再起動し、VPA は推奨リソースで新しい Pod を更新します。

開発者の場合、VPA を使用して、Pod を各 Pod に適したリソースを持つノードにスケジュールし、Pod の需要の多い期間でも稼働状態を維持することができます。

管理者は、VPA を使用してクラスターリソースをより適切に活用できます。たとえば、必要以上の CPU リソースを Pod が予約できないようにします。VPA は、ワークロードが実際に使用しているリソースをモニターし、他のワークロードで容量を使用できるようにリソース要件を調整します。VPA は、初期のコンテナー設定で指定される制限と要求の割合をそのまま維持します。

注記

VPA の実行を停止するか、クラスターの特定の VPA CR を削除する場合、VPA によってすでに変更された Pod のリソース要求は変更されません。新規 Pod は、VPA による以前の推奨事項ではなく、ワークロードオブジェクトで定義されたリソースを取得します。

2.5.2. Vertical Pod Autoscaler Operator のインストール

OpenShift Container Platform Web コンソールを使用して Vertical Pod Autoscaler Operator (VPA) をインストールすることができます。

手順

  1. OpenShift Container Platform Web コンソールで、OperatorsOperatorHub をクリックします。
  2. 利用可能な Operator のリストから VerticalPodAutoscaler を選択し、Install をクリックします。
  3. Install Operator ページで、Operator recommended namespace オプションが選択されていることを確認します。これにより、Operator が必須の openshift-vertical-pod-autoscaler namespace にインストールされます。この namespace は存在しない場合は、自動的に作成されます。
  4. Install をクリックします。

検証

  1. VPA Operator コンポーネントをリスト表示して、インストールを確認します。

    1. WorkloadsPods に移動します。
    2. ドロップダウンメニューから openshift-vertical-pod-autoscaler プロジェクトを選択し、4 つの Pod が実行されていることを確認します。
    3. WorkloadsDeployments に移動し、4 つのデプロイメントが実行されていることを確認します。
  2. オプション: 以下のコマンドを使用して、OpenShift Container Platform CLI でインストールを確認します。

    $ oc get all -n openshift-vertical-pod-autoscaler

    出力には、4 つの Pod と 4 つのデプロイメントが表示されます。

    出力例

    NAME                                                    READY   STATUS    RESTARTS   AGE
    pod/vertical-pod-autoscaler-operator-85b4569c47-2gmhc   1/1     Running   0          3m13s
    pod/vpa-admission-plugin-default-67644fc87f-xq7k9       1/1     Running   0          2m56s
    pod/vpa-recommender-default-7c54764b59-8gckt            1/1     Running   0          2m56s
    pod/vpa-updater-default-7f6cc87858-47vw9                1/1     Running   0          2m56s
    
    NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
    service/vpa-webhook   ClusterIP   172.30.53.206   <none>        443/TCP   2m56s
    
    NAME                                               READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/vertical-pod-autoscaler-operator   1/1     1            1           3m13s
    deployment.apps/vpa-admission-plugin-default       1/1     1            1           2m56s
    deployment.apps/vpa-recommender-default            1/1     1            1           2m56s
    deployment.apps/vpa-updater-default                1/1     1            1           2m56s
    
    NAME                                                          DESIRED   CURRENT   READY   AGE
    replicaset.apps/vertical-pod-autoscaler-operator-85b4569c47   1         1         1       3m13s
    replicaset.apps/vpa-admission-plugin-default-67644fc87f       1         1         1       2m56s
    replicaset.apps/vpa-recommender-default-7c54764b59            1         1         1       2m56s
    replicaset.apps/vpa-updater-default-7f6cc87858                1         1         1       2m56s

2.5.3. Vertical Pod Autoscaler Operator の使用について

Vertical Pod Autoscaler Operator (VPA) を使用するには、クラスター内にワークロードオブジェクトの VPA カスタムリソース (CR) を作成します。VPA は、そのワークロードオブジェクトに関連付けられた Pod に最適な CPU およびメモリーリソースを確認し、適用します。VPA は、デプロイメント、ステートフルセット、ジョブ、デーモンセット、レプリカセット、またはレプリケーションコントローラーのワークロードオブジェクトと共に使用できます。VPA CR はモニターする必要のある Pod と同じプロジェクトになければなりません。

VPA CR を使用してワークロードオブジェクトを関連付け、VPA が動作するモードを指定します。

  • Auto および Recreate モードは、Pod の有効期間中は VPA CPU およびメモリーの推奨事項を自動的に適用します。VPA は、推奨値で調整されていないプロジェクトの Pod を削除します。ワークロードオブジェクトによって再デプロイされる場合、VPA はその推奨内容で新規 Pod を更新します。
  • Initial モードは、Pod の作成時にのみ VPA の推奨事項を自動的に適用します。
  • Off モードは、推奨されるリソース制限および要求のみを提供するので、推奨事項を手動で適用することができます。off モードは Pod を更新しません。

CR を使用して、VPA 評価および更新から特定のコンテナーをオプトアウトすることもできます。

たとえば、Pod には以下の制限および要求があります。

resources:
  limits:
    cpu: 1
    memory: 500Mi
  requests:
    cpu: 500m
    memory: 100Mi

auto に設定された VPA を作成すると、VPA はリソースの使用状況を確認して Pod を削除します。再デプロイ時に、Pod は新規のリソース制限および要求を使用します。

resources:
  limits:
    cpu: 50m
    memory: 1250Mi
  requests:
    cpu: 25m
    memory: 262144k

以下のコマンドを実行して、VPA の推奨事項を表示できます。

$ oc get vpa <vpa-name> --output yaml

数分後に、出力には、以下のような CPU およびメモリー要求の推奨内容が表示されます。

出力例

...
status:
...
  recommendation:
    containerRecommendations:
    - containerName: frontend
      lowerBound:
        cpu: 25m
        memory: 262144k
      target:
        cpu: 25m
        memory: 262144k
      uncappedTarget:
        cpu: 25m
        memory: 262144k
      upperBound:
        cpu: 262m
        memory: "274357142"
    - containerName: backend
      lowerBound:
        cpu: 12m
        memory: 131072k
      target:
        cpu: 12m
        memory: 131072k
      uncappedTarget:
        cpu: 12m
        memory: 131072k
      upperBound:
        cpu: 476m
        memory: "498558823"
...

出力には、target (推奨リソース)、lowerBound (最小推奨リソース)、upperBound (最大推奨リソース)、および uncappedTarget (最新の推奨リソース) が表示されます。

VPA は lowerBound および upperBound の値を使用して、Pod の更新が必要であるかどうかを判別します。Pod のリソース要求が lowerBound 値を下回るか、upperBound 値を上回る場合は、VPA は終了し、target 値で Pod を再作成します。

2.5.3.1. VPA の最小値の変更

デフォルトで、ワークロードオブジェクトは、VPA が Pod を自動的に削除し、更新できるようにするためにレプリカを 2 つ以上指定する必要があります。そのため、2 つ未満を指定するワークロードオブジェクトの場合 VPA は自動的に機能しません。VPA は、Pod が VPA に対して外部にある一部のプロセスで再起動されると、これらのワークロードオブジェクトから新規 Pod を更新します。このクラスター全体の最小値の変更は、VerticalPodAutoscalerController カスタムリソース (CR) の minReplicas パラメーターを変更して実行できます。

たとえば、minReplicas3 に設定する場合、VPA は 2 レプリカ以下のレプリカを指定するワークロードオブジェクトの Pod を削除せず、更新しません。

注記

minReplicas1 に設定する場合、VPA は 1 つのレプリカのみを指定するワークロードオブジェクトの Pod のみを削除できます。この設定は、VPA がリソースを調整するために Pod を削除するたびにワークロードがダウンタイムを許容できる場合のみ、単一のレプリカオブジェクトで使用する必要があります。1 つのレプリカオブジェクトで不要なダウンタイムを回避するには、podUpdatePolicyInitial に設定して VPA CR を設定します。これにより、Pod は VPA の外部にある一部のプロセスで再起動される場合にのみ自動的に更新されます。または、Off に設定される場合、アプリケーションの適切なタイミングで Pod を手動で更新できます。

VerticalPodAutoscalerController オブジェクトの例

apiVersion: autoscaling.openshift.io/v1
kind: VerticalPodAutoscalerController
metadata:
  creationTimestamp: "2021-04-21T19:29:49Z"
  generation: 2
  name: default
  namespace: openshift-vertical-pod-autoscaler
  resourceVersion: "142172"
  uid: 180e17e9-03cc-427f-9955-3b4d7aeb2d59
spec:
  minReplicas: 3 1
  podMinCPUMillicores: 25
  podMinMemoryMb: 250
  recommendationOnly: false
  safetyMarginFraction: 0.15

1 1
動作させる VPA のワークロードオブジェクトのレプリカの最小数を指定します。最低数に満たない数のレプリカを持つオブジェクトは、VPA によって自動的に削除されません。
2.5.3.2. VPA の推奨事項の自動適用

VPA を使用して Pod を自動的に更新するには、updateModeAuto または Recreate に設定された特定のワークロードオブジェクトの VPA CR を作成します。

Pod がワークロードオブジェクト用に作成されると、VPA はコンテナーを継続的にモニターして、CPU およびメモリーのニーズを分析します。VPA は、CPU およびメモリーに関する VPA の推奨値を満たさない Pod を削除します。再デプロイ時に、Pod は VPA の推奨値に基づいて新規のリソース制限および要求を使用し、アプリケーションに設定された Pod の Disruption Budget (停止状態の予算) を反映します。この推奨事項は、参照用に VPA CR の status フィールドに追加されます。

注記

デフォルトで、ワークロードオブジェクトは、VPA が Pod を自動的に削除できるようにするためにレプリカを 2 つ以上指定する必要があります。この最小値よりも少ないレプリカを指定するワークロードオブジェクトは削除されません。これらの Pod を手動で削除すると、ワークロードオブジェクトが Pod を再デプロイします。VPA は推奨内容に基づいて新規 Pod を更新します。この最小値は、VPA の最小値の変更 に記載されているとおり、VerticalPodAutoscalerController オブジェクトを変更して変更できます。

Auto モードの VPA CR の例

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: vpa-recommender
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind:       Deployment 1
    name:       frontend 2
  updatePolicy:
    updateMode: "Auto" 3

1
この VPA CR が管理するワークロードオブジェクトのタイプ。
2
この VPA CR が管理するワークロードオブジェクトの名前。
3
モードを Auto または Recreate に設定します。
  • Auto:VPA は、Pod の作成時にリソース要求を割り当て、要求されるリソースが新規の推奨事項と大きく異なる場合に、それらを終了して既存の Pod を更新します。
  • Recreate:VPA は、Pod の作成時にリソース要求を割り当て、要求されるリソースが新規の推奨事項と大きく異なる場合に、それらを終了して既存の Pod を更新します。このモードはほとんど使用されることはありません。リソース要求が変更される際に Pod が再起動されていることを確認する必要がある場合にのみ使用します。
注記

VPA によってリソースの推奨事項を決定し、推奨リソースを新しい Pod に適用するには、動作中の Pod がプロジェクト内に存在し、実行されている必要があります。

CPU やメモリーなどのワークロードのリソース使用量が安定している場合、VPA はリソースの推奨事項を数分で決定できます。ワークロードのリソース使用量が安定していない場合、VPA は正確な推奨を行うために、さまざまなリソース使用量の間隔でメトリクスを収集する必要があります。

2.5.3.3. Pod 作成時における VPA 推奨の自動適用

VPA を使用して、Pod が最初にデプロイされる場合にのみ推奨リソースを適用するには、updateModeInitial に設定された特定のワークロードオブジェクトの VPA CR を作成します。

次に、VPA の推奨値を使用する必要のあるワークロードオブジェクトに関連付けられた Pod を手動で削除します。Initial モードで、VPA は新しいリソースの推奨内容を確認する際に Pod を削除したり、更新したりしません。

Initial モードの VPA CR の例

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: vpa-recommender
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind:       Deployment 1
    name:       frontend 2
  updatePolicy:
    updateMode: "Initial" 3

1
この VPA CR が管理するワークロードオブジェクトのタイプ。
2
この VPA CR が管理するワークロードオブジェクトの名前。
3
モードを Initial に設定します。VPA は、Pod の作成時にリソースを割り当て、Pod の有効期間中はリソースを変更しません。
注記

VPA によって推奨リソースを決定し、推奨事項を新しい Pod に適用するには、動作中の Pod がプロジェクト内に存在し、実行されている必要があります。

VPA から最も正確な推奨事項を取得するには、Pod が実行され、VPA が安定するまで少なくとも 8 日間待機してください。

2.5.3.4. VPA の推奨事項の手動適用

CPU およびメモリーの推奨値を判別するためだけに VPA を使用するには、updateModeoff に設定した特定のワークロードオブジェクトの VPA CR を作成します。

Pod がワークロードオブジェクト用に作成されると、VPA はコンテナーの CPU およびメモリーのニーズを分析し、VPA CR の status フィールドにそれらの推奨事項を記録します。VPA は、新しい推奨リソースを判別する際に Pod を更新しません。

Off モードの VPA CR の例

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: vpa-recommender
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind:       Deployment 1
    name:       frontend 2
  updatePolicy:
    updateMode: "Off" 3

1
この VPA CR が管理するワークロードオブジェクトのタイプ。
2
この VPA CR が管理するワークロードオブジェクトの名前。
3
モードを Off に設定します。

以下のコマンドを使用して、推奨事項を表示できます。

$ oc get vpa <vpa-name> --output yaml

この推奨事項により、ワークロードオブジェクトを編集して CPU およびメモリー要求を追加し、推奨リソースを使用して Pod を削除および再デプロイできます。

注記

VPA によって推奨リソースを決定し、推奨事項を新しい Pod に適用するには、動作中の Pod がプロジェクト内に存在し、実行されている必要があります。

VPA から最も正確な推奨事項を取得するには、Pod が実行され、VPA が安定するまで少なくとも 8 日間待機してください。

2.5.3.5. VPA の推奨事項をすべてのコンテナーに適用しないようにする

ワークロードオブジェクトに複数のコンテナーがあり、VPA がすべてのコンテナーを評価および実行対象としないようにするには、特定のワークロードオブジェクトの VPA CR を作成し、resourcePolicy を追加して特定のコンテナーをオプトアウトします。

VPA が推奨リソースで Pod を更新すると、resourcePolicy が設定されたコンテナーは更新されず、VPA は Pod 内のそれらのコンテナーの推奨事項を提示しません。

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: vpa-recommender
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind:       Deployment 1
    name:       frontend 2
  updatePolicy:
    updateMode: "Auto" 3
  resourcePolicy: 4
    containerPolicies:
    - containerName: my-opt-sidecar
      mode: "Off"
1
この VPA CR が管理するワークロードオブジェクトのタイプ。
2
この VPA CR が管理するワークロードオブジェクトの名前。
3
モードを AutoRecreate、または Off に設定します。Recreate モードはほとんど使用されることはありません。リソース要求が変更される際に Pod が再起動されていることを確認する必要がある場合にのみ使用します。
4
オプトアウトするコンテナーを指定し、modeOff に設定します。

たとえば、Pod には同じリソース要求および制限の 2 つのコンテナーがあります。

# ...
spec:
  containers:
  - name: frontend
    resources:
      limits:
        cpu: 1
        memory: 500Mi
      requests:
        cpu: 500m
        memory: 100Mi
  - name: backend
    resources:
      limits:
        cpu: "1"
        memory: 500Mi
      requests:
        cpu: 500m
        memory: 100Mi
# ...

backend コンテナーがオプトアウトに設定された VPA CR を起動した後、VPA は Pod を終了し、frontend コンテナーのみに適用される推奨リソースで Pod を再作成します。

...
spec:
  containers:
    name: frontend
    resources:
      limits:
        cpu: 50m
        memory: 1250Mi
      requests:
        cpu: 25m
        memory: 262144k
...
    name: backend
    resources:
      limits:
        cpu: "1"
        memory: 500Mi
      requests:
        cpu: 500m
        memory: 100Mi
...
2.5.3.6. 代替のレコメンダーを使用する

独自のレコメンダーを使用して、独自のアルゴリズムに基づいて自動スケーリングできます。代替レコメンダーを指定しない場合、OpenShift Container Platform はデフォルトのレコメンダーを使用します。これは、過去の使用状況に基づいて CPU およびメモリー要求を提案します。すべてのタイプのワークロードに適用されるユニバーサルレコメンデーションポリシーはないため、特定のワークロードに対して異なるレコメンダーを作成してデプロイメントすることを推奨します。

たとえば、デフォルトのレコメンダーは、コンテナーが特定のリソース動作を示す場合、将来のリソース使用量を正確に予測しない可能性があります。たとえば、監視アプリケーションで使用される使用量の急増とアイドリングを交互に繰り返すパターンや、ディープラーニングアプリケーションで使用される繰り返しパターンなどです。これらの使用動作でデフォルトのレコメンダーを使用すると、アプリケーションのプロビジョニングが大幅に過剰になり、Out of Memory (OOM) が強制終了される可能性があります。

注記

レコメンダーを作成する方法の説明は、このドキュメントの範囲を超えています。

手順

Pod に代替のレコメンダーを使用するには:

  1. 代替レコメンダーのサービスアカウントを作成し、そのサービスアカウントを必要なクラスターロールにバインドします。

    apiVersion: v1 1
    kind: ServiceAccount
    metadata:
      name: alt-vpa-recommender-sa
      namespace: <namespace_name>
    ---
    apiVersion: rbac.authorization.k8s.io/v1 2
    kind: ClusterRoleBinding
    metadata:
      name: system:example-metrics-reader
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:metrics-reader
    subjects:
    - kind: ServiceAccount
      name: alt-vpa-recommender-sa
      namespace: <namespace_name>
    ---
    apiVersion: rbac.authorization.k8s.io/v1 3
    kind: ClusterRoleBinding
    metadata:
      name: system:example-vpa-actor
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:vpa-actor
    subjects:
    - kind: ServiceAccount
      name: alt-vpa-recommender-sa
      namespace: <namespace_name>
    ---
    apiVersion: rbac.authorization.k8s.io/v1 4
    kind: ClusterRoleBinding
    metadata:
      name: system:example-vpa-target-reader-binding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:vpa-target-reader
    subjects:
    - kind: ServiceAccount
      name: alt-vpa-recommender-sa
      namespace: <namespace_name>
    1
    レコメンダーがデプロイされている namespace にレコメンダーのサービスアカウントを作成します。
    2
    レコメンダーサービスアカウントを metrics-reader ロールにバインドします。レコメンダーをデプロイする namespace を指定します。
    3
    レコメンダーサービスアカウントを vpa-actor ロールにバインドします。レコメンダーをデプロイする namespace を指定します。
    4
    レコメンダーサービスアカウントを vpa-target-reader ロールにバインドします。レコメンダーをデプロイする namespace を指定します。
  2. 代替レコメンダーをクラスターに追加するには、次のようなデプロイメントオブジェクトを作成します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: alt-vpa-recommender
      namespace: <namespace_name>
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: alt-vpa-recommender
      template:
        metadata:
          labels:
            app: alt-vpa-recommender
        spec:
          containers: 1
          - name: recommender
            image: quay.io/example/alt-recommender:latest 2
            imagePullPolicy: Always
            resources:
              limits:
                cpu: 200m
                memory: 1000Mi
              requests:
                cpu: 50m
                memory: 500Mi
            ports:
            - name: prometheus
              containerPort: 8942
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop:
                  - ALL
              seccompProfile:
                type: RuntimeDefault
          serviceAccountName: alt-vpa-recommender-sa 3
          securityContext:
            runAsNonRoot: true
    1
    代替レコメンダーのコンテナーを作成します。
    2
    推奨イメージを指定します。
    3
    レコメンダー用に作成したサービスアカウントを関連付けます。

    同じ namespace 内の代替レコメンダー用に新しい Pod が作成されます。

    $ oc get pods

    出力例

    NAME                                        READY   STATUS    RESTARTS   AGE
    frontend-845d5478d-558zf                    1/1     Running   0          4m25s
    frontend-845d5478d-7z9gx                    1/1     Running   0          4m25s
    frontend-845d5478d-b7l4j                    1/1     Running   0          4m25s
    vpa-alt-recommender-55878867f9-6tp5v        1/1     Running   0          9s

  3. 代替レコメンダー Deployment オブジェクトの名前を含む VPA CR を設定します。

    代替レコメンダーを含めるための VPA CR の例

    apiVersion: autoscaling.k8s.io/v1
    kind: VerticalPodAutoscaler
    metadata:
      name: vpa-recommender
      namespace: <namespace_name>
    spec:
      recommenders:
        - name: alt-vpa-recommender 1
      targetRef:
        apiVersion: "apps/v1"
        kind:       Deployment 2
        name:       frontend

    1
    代替レコメンダーデプロイメントの名前を指定します。
    2
    この VPA で管理する既存のワークロードオブジェクトの名前を指定します。

2.5.4. Vertical Pod Autoscaler Operator の使用

VPA カスタムリソース (CR) を作成して、Vertical Pod Autoscaler Operator (VPA) を使用できます。CR は、分析すべき Pod を示し、VPA がそれらの Pod について実行するアクションを判別します。

前提条件

  • 自動スケーリングするワークロードオブジェクトが存在している必要があります。
  • 別のレコメンダーを使用する場合は、そのレコメンダーを含むデプロイメントが存在する必要があります。

手順

特定のワークロードオブジェクトの VPA CR を作成するには、以下を実行します。

  1. スケーリングするワークロードオブジェクトがあるプロジェクトに切り替えます。

    1. VPA CR YAML ファイルを作成します。

      apiVersion: autoscaling.k8s.io/v1
      kind: VerticalPodAutoscaler
      metadata:
        name: vpa-recommender
      spec:
        targetRef:
          apiVersion: "apps/v1"
          kind:       Deployment 1
          name:       frontend 2
        updatePolicy:
          updateMode: "Auto" 3
        resourcePolicy: 4
          containerPolicies:
          - containerName: my-opt-sidecar
            mode: "Off"
        recommenders: 5
          - name: my-recommender
      1
      この VPA が管理するワークロードオブジェクトのタイプ (DeploymentStatefulSetJobDaemonSetReplicaSet、または ReplicationController) を指定します。
      2
      この VPA が管理する既存のワークロードオブジェクトの名前を指定します。
      3
      VPA モードを指定します。
      • auto は、コントローラーに関連付けられた Pod に推奨リソースを自動的に適用します。VPA は既存の Pod を終了し、推奨されるリソース制限および要求で新規 Pod を作成します。
      • recreate は、ワークロードオブジェクトに関連付けられた Pod に推奨リソースを自動的に適用します。VPA は既存の Pod を終了し、推奨されるリソース制限および要求で新規 Pod を作成します。recreate モードはほとんど使用されることはありません。リソース要求が変更される際に Pod が再起動されていることを確認する必要がある場合にのみ使用します。
      • initial は、ワークロードオブジェクトに関連付けられた Pod が作成される際に、推奨リソースを自動的に適用します。VPA は、新しい推奨リソースを確認する際に Pod を更新しません。
      • off は、ワークロードオブジェクトに関連付けられた Pod の推奨リソースのみを生成します。VPA は、新しい推奨リソースを確認する際に Pod を更新しません。また、新規 Pod に推奨事項を適用しません。
      4
      オプション: オプトアウトするコンテナーを指定し、モードを Off に設定します。
      5
      オプション: レコメンダーの推奨者を指定します。
    2. VPA CR を作成します。

      $ oc create -f <file-name>.yaml

      しばらくすると、VPA はワークロードオブジェクトに関連付けられた Pod 内のコンテナーのリソース使用状況を確認します。

      以下のコマンドを実行して、VPA の推奨事項を表示できます。

      $ oc get vpa <vpa-name> --output yaml

      出力には、以下のような CPU およびメモリー要求の推奨事項が表示されます。

      出力例

      ...
      status:
      
      ...
      
        recommendation:
          containerRecommendations:
          - containerName: frontend
            lowerBound: 1
              cpu: 25m
              memory: 262144k
            target: 2
              cpu: 25m
              memory: 262144k
            uncappedTarget: 3
              cpu: 25m
              memory: 262144k
            upperBound: 4
              cpu: 262m
              memory: "274357142"
          - containerName: backend
            lowerBound:
              cpu: 12m
              memory: 131072k
            target:
              cpu: 12m
              memory: 131072k
            uncappedTarget:
              cpu: 12m
              memory: 131072k
            upperBound:
              cpu: 476m
              memory: "498558823"
      
      ...

      1
      lowerBound は、推奨リソースの最小レベルです。
      2
      target は、推奨リソースのレベルです。
      3
      upperBound は、推奨リソースの最大レベルです。
      4
      uncappedTarget は最新の推奨リソースです。

2.5.5. Vertical Pod Autoscaler Operator のアンインストール

Vertical Pod Autoscaler Operator (VPA) を OpenShift Container Platform クラスターから削除できます。アンインストール後、既存の VPA CR によってすでに変更された Pod のリソース要求は変更されません。新規 Pod は、Vertical Pod Autoscaler Operator による以前の推奨事項ではなく、ワークロードオブジェクトで定義されるリソースを取得します。

注記

oc delete vpa <vpa-name> コマンドを使用して、特定の VPA CR を削除できます。Vertical Pod Autoscaler のアンインストール時と同じアクションがリソース要求に対して適用されます。

VPA Operator を削除した後、潜在的な問題を回避するために、Operator に関連する他のコンポーネントを削除することを推奨します。

前提条件

  • Vertical Pod Autoscaler Operator がインストールされていること。

手順

  1. OpenShift Container Platform Web コンソールで、OperatorsInstalled Operators をクリックします。
  2. openshift-vertical-pod-autoscaler プロジェクトに切り替えます。
  3. VerticalPodAutoscaler Operator の場合は、Options メニュー kebab をクリックし、Uninstall Operator を選択します。
  4. オプション: 演算子に関連付けられているすべてのオペランドを削除するには、ダイアログボックスで、Delete all operand instances for this operatorチェックボックスをオンにします。
  5. Uninstall をクリックします。
  6. オプション: OpenShift CLI を使用して VPA コンポーネントを削除します。

    1. VPA namespace を削除します。

      $ oc delete namespace openshift-vertical-pod-autoscaler
    2. VPA カスタムリソース定義 (CRD) オブジェクトを削除します。

      $ oc delete crd verticalpodautoscalercheckpoints.autoscaling.k8s.io
      $ oc delete crd verticalpodautoscalercontrollers.autoscaling.openshift.io
      $ oc delete crd verticalpodautoscalers.autoscaling.k8s.io

      CRD を削除すると、関連付けられたロール、クラスターロール、およびロールバインディングが削除されます。

      注記

      この操作により、ユーザーが作成したすべての VPA CR がクラスターから削除されます。VPA を再インストールする場合は、これらのオブジェクトを再度作成する必要があります。

    3. 次のコマンドを実行して MutatingWebhookConfiguration オブジェクトを削除します。

      $ oc delete MutatingWebhookConfiguration vpa-webhook-config
    4. VPA Operator を削除します。

      $ oc delete operator/vertical-pod-autoscaler.openshift-vertical-pod-autoscaler

2.6. シークレットを使用した機密データの Pod への提供

アプリケーションによっては、パスワードやユーザー名など開発者に使用させない秘密情報が必要になります。

管理者として シークレット オブジェクトを使用すると、この情報を平文で公開することなく提供することが可能です。

2.6.1. シークレットについて

Secret オブジェクトタイプはパスワード、OpenShift Container Platform クライアント設定ファイル、プライベートソースリポジトリーの認証情報などの機密情報を保持するメカニズムを提供します。シークレットは機密内容を Pod から切り離します。シークレットはボリュームプラグインを使用してコンテナーにマウントすることも、システムが Pod の代わりにシークレットを使用して各種アクションを実行することもできます。

キーのプロパティーには以下が含まれます。

  • シークレットデータはその定義とは別に参照できます。
  • シークレットデータのボリュームは一時ファイルストレージ機能 (tmpfs) でサポートされ、ノードで保存されることはありません。
  • シークレットデータは namespace 内で共有できます。

YAML Secret オブジェクト定義

apiVersion: v1
kind: Secret
metadata:
  name: test-secret
  namespace: my-namespace
type: Opaque 1
data: 2
  username: <username> 3
  password: <password>
stringData: 4
  hostname: myapp.mydomain.com 5

1
シークレットにキー名および値の構造を示しています。
2
data フィールドのキーに使用可能な形式は、Kubernetes identifiers glossaryDNS_SUBDOMAIN 値のガイドラインに従う必要があります。
3
data マップのキーに関連付けられる値は base64 でエンコーディングされている必要があります。
4
stringData マップのエントリーが base64 に変換され、このエントリーは自動的に data マップに移動します。このフィールドは書き込み専用です。この値は data フィールドでのみ返されます。
5
stringData マップのキーに関連付けられた値は単純なテキスト文字列で構成されます。

シークレットに依存する Pod を作成する前に、シークレットを作成する必要があります。

シークレットの作成時に以下を実行します。

  • シークレットデータでシークレットオブジェクトを作成します。
  • Pod のサービスアカウントをシークレットの参照を許可するように更新します。
  • シークレットを環境変数またはファイルとして使用する Pod を作成します (secret ボリュームを使用)。
2.6.1.1. シークレットの種類

type フィールドの値で、シークレットのキー名と値の構造を指定します。このタイプを使用して、シークレットオブジェクトにユーザー名とキーの配置を実行できます。検証の必要がない場合には、デフォルト設定の opaque タイプを使用してください。

以下のタイプから 1 つ指定して、サーバー側で最小限の検証をトリガーし、シークレットデータに固有のキー名が存在することを確認します。

  • kubernetes.io/basic-auth: Basic 認証で使用します。
  • kubernetes.io/dockercfg: イメージプルシークレットとして使用します。
  • kubernetes.io/dockerconfigjson: イメージプルシークレットとして使用します。
  • kubernetes.io/service-account-token: レガシーサービスアカウント API トークンの取得に使用します。
  • kubernetes.io/ssh-auth: SSH キー認証で使用します。
  • kubernetes.io/tls: TLS 認証局で使用します。

検証が必要ない場合には type: Opaque と指定します。これは、シークレットがキー名または値の規則に準拠しないという意味です。opaque シークレットでは、任意の値を含む、体系化されていない key:value ペアも利用できます。

注記

example.com/my-secret-type などの他の任意のタイプを指定できます。これらのタイプはサーバー側では実行されませんが、シークレットの作成者がその種類のキー/値の要件に従う意図があることを示します。

さまざまな種類のシークレットを作成する例は、シークレットの作成方法 を参照してください。

2.6.1.2. シークレットデータキー

シークレットキーは DNS サブドメインになければなりません。

2.6.1.3. 自動生成されるサービスアカウントトークンシークレット

サービスアカウントが作成されると、そのサービスアカウント用のトークンシークレットが自動的に生成されます。このサービスアカウントトークンシークレットは、自動的に生成された Docker 設定シークレットとともに、内部 OpenShift Container Platform レジストリーに対する認証に使用されます。これらの自動生成されたシークレットは、自分での使用に依存することがないようにしてください。これらは将来の OpenShift Container Platform リリースで削除される可能性があります。

注記

OpenShift Container Platform 4.11 より前では、サービスアカウントの作成時に 2 番目のサービスアカウントトークンシークレットが生成されました。このサービスアカウントトークンシークレットは、Kubernetes API へのアクセスに使用されていました。

OpenShift Container Platform 4.11 以降、この 2 番目のサービスアカウントトークンシークレットは作成されなくなりました。これは、LegacyServiceAccountTokenNoAutoGeneration アップストリーム Kubernetes フィーチャーゲートが有効になっており、Kubernetes API にアクセスするためのシークレットベースのサービスアカウントトークンの自動生成が停止されているためです。

4.14 にアップグレードした後も、既存のサービスアカウントトークンシークレットは削除されず、引き続き機能します。

バインドされたサービスアカウントトークンを取得するために、予測されたボリュームでワークロードが自動的に挿入されます。ワークロードに追加のサービスアカウントトークンが必要な場合は、ワークロードマニフェストに追加の予測ボリュームを追加します。バインドされたサービスアカウントトークンは、次の理由により、サービスアカウントトークンのシークレットよりも安全です。

  • バインドされたサービスアカウントトークンには有効期間が制限されています。
  • バインドされたサービスアカウントトークンには対象ユーザーが含まれます。
  • バインドされたサービスアカウントトークンは Pod またはシークレットにバインドでき、バインドされたオブジェクトが削除されるとバインドされたトークンは無効になります。

詳細は、ボリュームプロジェクションを使用したバインドされたサービスアカウントトークンの設定 を参照してください。

読み取り可能な API オブジェクト内の有効期限のないトークンのセキュリティー露出が許容される場合は、サービスアカウントトークンシークレットを手動で作成してトークンを取得することもできます。詳細は、サービスアカウントトークンシークレットの作成 を参照してください。

関連情報

2.6.2. シークレットの作成方法

管理者は、開発者がシークレットに依存する Pod を作成できるよう事前にシークレットを作成しておく必要があります。

シークレットの作成時に以下を実行します。

  1. 秘密にしておきたいデータを含む秘密オブジェクトを作成します。各シークレットタイプに必要な特定のデータは、以下のセクションで非表示になります。

    不透明なシークレットを作成する YAML オブジェクトの例

    apiVersion: v1
    kind: Secret
    metadata:
      name: test-secret
    type: Opaque 1
    data: 2
      username: <username>
      password: <password>
    stringData: 3
      hostname: myapp.mydomain.com
      secret.properties: |
        property1=valueA
        property2=valueB

    1
    シークレットのタイプを指定します。
    2
    エンコードされた文字列およびデータを指定します。
    3
    デコードされた文字列およびデータを指定します。

    data フィールドまたは stringdata フィールドの両方ではなく、いずれかを使用してください。

  2. Pod のサービスアカウントをシークレットを参照するように更新します。

    シークレットを使用するサービスアカウントの YAML

    apiVersion: v1
    kind: ServiceAccount
     ...
    secrets:
    - name: test-secret

  3. シークレットを環境変数またはファイルとして使用する Pod を作成します (secret ボリュームを使用)。

    シークレットデータと共にボリュームのファイルが設定された Pod の YAML

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-example-pod
    spec:
      containers:
        - name: secret-test-container
          image: busybox
          command: [ "/bin/sh", "-c", "cat /etc/secret-volume/*" ]
          volumeMounts: 1
              - name: secret-volume
                mountPath: /etc/secret-volume 2
                readOnly: true 3
      volumes:
        - name: secret-volume
          secret:
            secretName: test-secret 4
      restartPolicy: Never

    1
    シークレットが必要な各コンテナーに volumeMounts フィールドを追加します。
    2
    シークレットが表示される未使用のディレクトリー名を指定します。シークレットデータマップの各キーは mountPath の下にあるファイル名になります。
    3
    true に設定します。true の場合、ドライバーに読み取り専用ボリュームを提供するように指示します。
    4
    シークレットの名前を指定します。

    シークレットデータと共に環境変数が設定された Pod の YAML

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-example-pod
    spec:
      containers:
        - name: secret-test-container
          image: busybox
          command: [ "/bin/sh", "-c", "export" ]
          env:
            - name: TEST_SECRET_USERNAME_ENV_VAR
              valueFrom:
                secretKeyRef: 1
                  name: test-secret
                  key: username
      restartPolicy: Never

    1
    シークレットキーを使用する環境変数を指定します。

    シークレットデータと環境変数が設定されたビルド設定の YAML

    apiVersion: build.openshift.io/v1
    kind: BuildConfig
    metadata:
      name: secret-example-bc
    spec:
      strategy:
        sourceStrategy:
          env:
          - name: TEST_SECRET_USERNAME_ENV_VAR
            valueFrom:
              secretKeyRef: 1
                name: test-secret
                key: username
          from:
            kind: ImageStreamTag
            namespace: openshift
            name: 'cli:latest'

    1
    シークレットキーを使用する環境変数を指定します。
2.6.2.1. シークレットの作成に関する制限

シークレットを使用するには、Pod がシークレットを参照できる必要があります。シークレットは、以下の 3 つの方法で Pod で使用されます。

  • コンテナーの環境変数を事前に設定するために使用される。
  • 1 つ以上のコンテナーにマウントされるボリュームのファイルとして使用される。
  • Pod のイメージをプルする際に kubelet によって使用される。

ボリュームタイプのシークレットは、ボリュームメカニズムを使用してデータをファイルとしてコンテナーに書き込みます。イメージプルシークレットは、シークレットを namespace のすべての Pod に自動的に挿入するためにサービスアカウントを使用します。

テンプレートにシークレット定義が含まれる場合、テンプレートで指定のシークレットを使用できるようにするには、シークレットのボリュームソースを検証し、指定されるオブジェクト参照が Secret オブジェクトを実際に参照していることを確認できる必要があります。そのため、シークレットはこれに依存する Pod の作成前に作成されている必要があります。最も効果的な方法として、サービスアカウントを使用してシークレットを自動的に挿入することができます。

シークレット API オブジェクトは namespace にあります。それらは同じ namespace の Pod によってのみ参照されます。

個々のシークレットは 1MB のサイズに制限されます。これにより、apiserver および kubelet メモリーを使い切るような大規模なシークレットの作成を防ぐことができます。ただし、小規模なシークレットであってもそれらを数多く作成するとメモリーの消費につながります。

2.6.2.2. 不透明なシークレットの作成

管理者は、不透明なシークレットを作成できます。これにより、任意の値を含むことができる非構造化 key:value のペアを格納できます。

手順

  1. コントロールプレーンノードの YAML ファイルに Secret オブジェクトを作成します。

    以下に例を示します。

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque 1
    data:
      username: <username>
      password: <password>
    1
    不透明なシークレットを指定します。
  2. 以下のコマンドを使用して Secret オブジェクトを作成します。

    $ oc create -f <filename>.yaml
  3. Pod でシークレットを使用するには、以下を実行します。

    1. 「シークレットの作成方法について」セクションで説明されているとおり、Pod のサービスアカウントを更新してシークレットを参照します。
    2. 「シークレットの作成方法について」で説明されているとおり、シークレットを環境変数またはファイル (secret ボリュームを使用) として使用する Pod を作成します。

関連情報

2.6.2.3. サービスアカウントトークンシークレットの作成

管理者は、サービスアカウントトークンシークレットを作成できます。これにより、API に対して認証する必要のあるアプリケーションにサービスアカウントトークンを配布できます。

注記

サービスアカウントトークンシークレットを使用する代わりに、TokenRequest API を使用してバインドされたサービスアカウントトークンを取得することを推奨します。TokenRequest API から取得したトークンは、有効期間が制限されており、他の API クライアントが読み取れないため、シークレットに保存されているトークンよりも安全です。

TokenRequest API を使用できず、読み取り可能な API オブジェクトで有効期限が切れていないトークンのセキュリティーエクスポージャーが許容できる場合にのみ、サービスアカウントトークンシークレットを作成する必要があります。

バインドされたサービスアカウントトークンの作成に関する詳細は、以下の追加リソースセクションを参照してください。

手順

  1. コントロールプレーンノードの YAML ファイルに Secret オブジェクトを作成します。

    secret オブジェクトの例:

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-sa-sample
      annotations:
        kubernetes.io/service-account.name: "sa-name" 1
    type: kubernetes.io/service-account-token 2

    1
    既存のサービスアカウント名を指定します。ServiceAccountSecret オブジェクトの両方を作成する場合は、ServiceAccount オブジェクトを最初に作成します。
    2
    サービスアカウントトークンシークレットを指定します。
  2. 以下のコマンドを使用して Secret オブジェクトを作成します。

    $ oc create -f <filename>.yaml
  3. Pod でシークレットを使用するには、以下を実行します。

    1. 「シークレットの作成方法について」セクションで説明されているとおり、Pod のサービスアカウントを更新してシークレットを参照します。
    2. 「シークレットの作成方法について」で説明されているとおり、シークレットを環境変数またはファイル (secret ボリュームを使用) として使用する Pod を作成します。

関連情報

2.6.2.4. Basic 認証シークレットの作成

管理者は Basic 認証シークレットを作成できます。これにより、Basic 認証に必要な認証情報を保存できます。このシークレットタイプを使用する場合は、Secret オブジェクトの data パラメーターには、base64 形式でエンコードされた以下のキーが含まれている必要があります。

  • username: 認証用のユーザー名
  • password: 認証のパスワードまたはトークン
注記

stringData パラメーターを使用して、クリアテキストコンテンツを使用できます。

手順

  1. コントロールプレーンノードの YAML ファイルに Secret オブジェクトを作成します。

    secret オブジェクトの例

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-basic-auth
    type: kubernetes.io/basic-auth 1
    data:
    stringData: 2
      username: admin
      password: <password>

    1
    Basic 認証のシークレットを指定します。
    2
    使用する Basic 認証値を指定します。
  2. 以下のコマンドを使用して Secret オブジェクトを作成します。

    $ oc create -f <filename>.yaml
  3. Pod でシークレットを使用するには、以下を実行します。

    1. 「シークレットの作成方法について」セクションで説明されているとおり、Pod のサービスアカウントを更新してシークレットを参照します。
    2. 「シークレットの作成方法について」で説明されているとおり、シークレットを環境変数またはファイル (secret ボリュームを使用) として使用する Pod を作成します。

関連情報

2.6.2.5. SSH 認証シークレットの作成

管理者は、SSH 認証シークレットを作成できます。これにより、SSH 認証に使用されるデータを保存できます。このシークレットタイプを使用する場合、Secret オブジェクトの data パラメーターには、使用する SSH 認証情報が含まれている必要があります。

手順

  1. コントロールプレーンノードの YAML ファイルに Secret オブジェクトを作成します。

    secret オブジェクトの例:

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-ssh-auth
    type: kubernetes.io/ssh-auth 1
    data:
      ssh-privatekey: | 2
              MIIEpQIBAAKCAQEAulqb/Y ...

    1
    SSH 認証シークレットを指定します。
    2
    SSH のキー/値のペアを、使用する SSH 認証情報として指定します。
  2. 以下のコマンドを使用して Secret オブジェクトを作成します。

    $ oc create -f <filename>.yaml
  3. Pod でシークレットを使用するには、以下を実行します。

    1. 「シークレットの作成方法について」セクションで説明されているとおり、Pod のサービスアカウントを更新してシークレットを参照します。
    2. 「シークレットの作成方法について」で説明されているとおり、シークレットを環境変数またはファイル (secret ボリュームを使用) として使用する Pod を作成します。
2.6.2.6. Docker 設定シークレットの作成

管理者は Docker 設定シークレットを作成できます。これにより、コンテナーイメージレジストリーにアクセスするための認証情報を保存できます。

  • kubernetes.io/dockercfg.このシークレットタイプを使用してローカルの Docker 設定ファイルを保存します。secret オブジェクトの data パラメーターには、base64 形式でエンコードされた .dockercfg ファイルの内容が含まれている必要があります。
  • kubernetes.io/dockerconfigjson.このシークレットタイプを使用して、ローカルの Docker 設定 JSON ファイルを保存します。secret オブジェクトの data パラメーターには、base64 形式でエンコードされた .docker/config.json ファイルの内容が含まれている必要があります。

手順

  1. コントロールプレーンノードの YAML ファイルに Secret オブジェクトを作成します。

    Docker 設定の secret オブジェクトの例

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-docker-cfg
      namespace: my-project
    type: kubernetes.io/dockerconfig 1
    data:
      .dockerconfig:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== 2

    1
    シークレットが Docker 設定ファイルを使用することを指定します。
    2
    base64 でエンコードされた Docker 設定ファイルの出力

    Docker 設定の JSON secret オブジェクトの例

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-docker-json
      namespace: my-project
    type: kubernetes.io/dockerconfig 1
    data:
      .dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== 2

    1
    シークレットが Docker 設定の JSON ファイルを使用することを指定します。
    2
    base64 でエンコードされた Docker 設定 JSON ファイルの出力
  2. 以下のコマンドを使用して Secret オブジェクトを作成します。

    $ oc create -f <filename>.yaml
  3. Pod でシークレットを使用するには、以下を実行します。

    1. 「シークレットの作成方法について」セクションで説明されているとおり、Pod のサービスアカウントを更新してシークレットを参照します。
    2. 「シークレットの作成方法について」で説明されているとおり、シークレットを環境変数またはファイル (secret ボリュームを使用) として使用する Pod を作成します。

関連情報

2.6.2.7. Web コンソールを使用したシークレットの作成

Web コンソールを使用してシークレットを作成できます。

手順

  1. WorkloadsSecrets に移動します。
  2. CreateFrom YAML をクリックします。

    1. 仕様に合わせて YAML を手動で編集するか、ファイルを YAML エディターにドラッグアンドドロップします。以下に例を示します。

      apiVersion: v1
      kind: Secret
      metadata:
        name: example
        namespace: <namespace>
      type: Opaque 1
      data:
        username: <base64 encoded username>
        password: <base64 encoded password>
      stringData: 2
        hostname: myapp.mydomain.com
      1
      この例では、不透明なシークレットを指定します。ただし、サービスアカウントトークンシークレット、基本認証シークレット、SSH 認証シークレット、Docker 設定を使用するシークレットなど、他のシークレットタイプが表示される場合があります。
      2
      stringData マップのエントリーが base64 に変換され、このエントリーは自動的に data マップに移動します。このフィールドは書き込み専用です。この値は data フィールドでのみ返されます。
  3. Create をクリックします。
  4. Add Secret to workload をクリックします。

    1. ドロップダウンメニューから、追加するワークロードを選択します。
    2. Save をクリックします。

2.6.3. シークレットの更新方法

シークレットの値を変更する場合、値 (すでに実行されている Pod で使用される値) は動的に変更されません。シークレットを変更するには、元の Pod を削除してから新規の Pod を作成する必要があります (同じ PodSpec を使用する場合があります)。

シークレットの更新は、新規コンテナーイメージのデプロイメントと同じワークフローで実行されます。kubectl rolling-update コマンドを使用できます。

シークレットの resourceVersion 値は参照時に指定されません。したがって、シークレットが Pod の起動と同じタイミングで更新される場合、Pod に使用されるシークレットのバージョンは定義されません。

注記

現時点で、Pod の作成時に使用されるシークレットオブジェクトのリソースバージョンを確認することはできません。コントローラーが古い resourceVersion を使用して Pod を再起動できるように、Pod がこの情報を報告できるようにすることが予定されています。それまでは既存シークレットのデータを更新せずに別の名前で新規のシークレットを作成します。

2.6.4. シークレットの作成および使用

管理者は、サービスアカウントトークンシークレットを作成できます。これにより、サービスアカウントトークンを API に対して認証する必要のあるアプリケーションに配布できます。

手順

  1. 以下のコマンドを実行して namespace にサービスアカウントを作成します。

    $ oc create sa <service_account_name> -n <your_namespace>
  2. 以下の YAML の例は service-account-token-secret.yaml という名前のファイルに保存します。この例には、サービスアカウントトークンの生成に使用可能な Secret オブジェクト設定が含まれています。

    apiVersion: v1
    kind: Secret
    metadata:
      name: <secret_name> 1
      annotations:
        kubernetes.io/service-account.name: "sa-name" 2
    type: kubernetes.io/service-account-token 3
    1
    <secret_name> は、サービストークンシークレットの名前に置き換えます。
    2
    既存のサービスアカウント名を指定します。ServiceAccountSecret オブジェクトの両方を作成する場合は、ServiceAccount オブジェクトを最初に作成します。
    3
    サービスアカウントトークンシークレットタイプを指定します。
  3. ファイルを適用してサービスアカウントトークンを生成します。

    $ oc apply -f service-account-token-secret.yaml
  4. 以下のコマンドを実行して、シークレットからサービスアカウントトークンを取得します。

    $ oc get secret <sa_token_secret> -o jsonpath='{.data.token}' | base64 --decode 1

    出力例

    ayJhbGciOiJSUzI1NiIsImtpZCI6IklOb2dtck1qZ3hCSWpoNnh5YnZhSE9QMkk3YnRZMVZoclFfQTZfRFp1YlUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImJ1aWxkZXItdG9rZW4tdHZrbnIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiYnVpbGRlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjNmZGU2MGZmLTA1NGYtNDkyZi04YzhjLTNlZjE0NDk3MmFmNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmJ1aWxkZXIifQ.OmqFTDuMHC_lYvvEUrjr1x453hlEEHYcxS9VKSzmRkP1SiVZWPNPkTWlfNRp6bIUZD3U6aN3N7dMSN0eI5hu36xPgpKTdvuckKLTCnelMx6cxOdAbrcw1mCmOClNscwjS1KO1kzMtYnnq8rXHiMJELsNlhnRyyIXRTtNBsy4t64T3283s3SLsancyx0gy0ujx-Ch3uKAKdZi5iT-I8jnnQ-ds5THDs2h65RJhgglQEmSxpHrLGZFmyHAQI-_SjvmHZPXEc482x3SkaQHNLqpmrpJorNqh1M8ZHKzlujhZgVooMvJmWPXTb2vnvi3DGn2XI-hZxl1yD2yGH1RBpYUHA

    1
    <sa_token_secret> は、サービストークンシークレットの名前に置き換えます。
  5. サービスアカウントトークンを使用して、クラスターの API で認証します。

    $ curl -X GET <openshift_cluster_api> --header "Authorization: Bearer <token>" 1 2
    1
    <openshift_cluster_api> は OpenShift クラスター API に置き換えます。
    2
    <token> は、直前のコマンドで出力されるサービスアカウントトークンに置き換えます。

2.6.5. シークレットで署名証明書を使用する方法

サービスの通信を保護するため、プロジェクト内のシークレットに追加可能な、署名されたサービス証明書/キーペアを生成するように OpenShift Container Platform を設定することができます。

サービス提供証明書のシークレット は、追加設定なしの証明書を必要とする複雑なミドルウェアアプリケーションをサポートするように設計されています。これにはノードおよびマスターの管理者ツールで生成されるサーバー証明書と同じ設定が含まれます。

サービス提供証明書のシークレット用に設定されるサービス Pod 仕様

apiVersion: v1
kind: Service
metadata:
  name: registry
  annotations:
    service.beta.openshift.io/serving-cert-secret-name: registry-cert1
# ...

1
証明書の名前を指定します。

他の Pod は Pod に自動的にマウントされる /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt ファイルの CA バンドルを使用して、クラスターで作成される証明書 (内部 DNS 名の場合にのみ署名される) を信頼できます。

この機能の署名アルゴリズムは x509.SHA256WithRSA です。ローテーションを手動で実行するには、生成されたシークレットを削除します。新規の証明書が作成されます。

2.6.5.1. シークレットで使用する署名証明書の生成

署名されたサービス証明書/キーペアを Pod で使用するには、サービスを作成または編集して service.beta.openshift.io/serving-cert-secret-name アノテーションを追加した後に、シークレットを Pod に追加します。

手順

サービス提供証明書のシークレット を作成するには、以下を実行します。

  1. サービスの Pod 仕様を編集します。
  2. シークレットに使用する名前に service.beta.openshift.io/serving-cert-secret-name アノテーションを追加します。

    kind: Service
    apiVersion: v1
    metadata:
      name: my-service
      annotations:
          service.beta.openshift.io/serving-cert-secret-name: my-cert 1
    spec:
      selector:
        app: MyApp
      ports:
      - protocol: TCP
        port: 80
        targetPort: 9376

    証明書およびキーは PEM 形式であり、それぞれ tls.crt および tls.key に保存されます。

  3. サービスを作成します。

    $ oc create -f <file-name>.yaml
  4. シークレットを表示して、作成されていることを確認します。

    1. すべてのシークレットのリストを表示します。

      $ oc get secrets

      出力例

      NAME                     TYPE                                  DATA      AGE
      my-cert                  kubernetes.io/tls                     2         9m

    2. シークレットの詳細を表示します。

      $ oc describe secret my-cert

      出力例

      Name:         my-cert
      Namespace:    openshift-console
      Labels:       <none>
      Annotations:  service.beta.openshift.io/expiry: 2023-03-08T23:22:40Z
                    service.beta.openshift.io/originating-service-name: my-service
                    service.beta.openshift.io/originating-service-uid: 640f0ec3-afc2-4380-bf31-a8c784846a11
                    service.beta.openshift.io/expiry: 2023-03-08T23:22:40Z
      
      Type:  kubernetes.io/tls
      
      Data
      ====
      tls.key:  1679 bytes
      tls.crt:  2595 bytes

  5. このシークレットを使用して Pod 仕様を編集します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-service-pod
    spec:
      containers:
      - name: mypod
        image: redis
        volumeMounts:
        - name: my-container
          mountPath: "/etc/my-path"
      volumes:
      - name: my-volume
        secret:
          secretName: my-cert
          items:
          - key: username
            path: my-group/my-username
            mode: 511

    これが利用可能な場合、Pod が実行されます。この証明書は内部サービス DNS 名、<service.name>.<service.namespace>.svc に適しています。

    証明書/キーのペアは有効期限に近づくと自動的に置換されます。シークレットの service.beta.openshift.io/expiry アノテーションで RFC3339 形式の有効期限の日付を確認します。

    注記

    ほとんどの場合、サービス DNS 名 <service.name>.<service.namespace>.svc は外部にルーティング可能ではありません。<service.name>.<service.namespace>.svc の主な使用方法として、クラスターまたはサービス間の通信用として、re-encrypt ルートで使用されます。

2.6.6. シークレットのトラブルシューティング

サービス証明書の生成は以下を出して失敗します (サービスの service.beta.openshift.io/serving-cert-generation-error アノテーションには以下が含まれます)。

secret/ssl-key references serviceUID 62ad25ca-d703-11e6-9d6f-0e9c0057b608, which does not match 77b6dd80-d716-11e6-9d6f-0e9c0057b60

証明書を生成したサービスがすでに存在しないか、サービスに異なる serviceUID があります。古いシークレットを削除し、サービスのアノテーション (service.beta.openshift.io/serving-cert-generation-errorservice.beta.openshift.io/serving-cert-generation-error-num) をクリアして証明書の再生成を強制的に実行する必要があります。

  1. シークレットを削除します。

    $ oc delete secret <secret_name>
  2. アノテーションをクリアします。

    $ oc annotate service <service_name> service.beta.openshift.io/serving-cert-generation-error-
    $ oc annotate service <service_name> service.beta.openshift.io/serving-cert-generation-error-num-
注記

アノテーションを削除するコマンドでは、削除するアノテーション名の後に - を付けます。

2.7. 外部シークレットストアを使用した機密データの Pod への提供

アプリケーションによっては、パスワードやユーザー名など開発者に使用させない秘密情報が必要になります。

Kubernetes Secret オブジェクトを使用して機密情報を提供する代わりに、外部シークレットストアを使用して機密情報を保存できます。Secrets Store CSI Driver Operator を使用して、外部シークレットストアと統合し、シークレットコンテンツを Pod ボリュームとしてマウントできます。

重要

GCP Filestore CSI Driver Operator は、テクノロジープレビュー機能としてのみ提供されます。テクノロジープレビュー機能は、Red Hat 製品のサービスレベルアグリーメント (SLA) の対象外であり、機能的に完全ではないことがあります。Red Hat は、実稼働環境でこれらを使用することを推奨していません。テクノロジープレビューの機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。

Red Hat のテクノロジープレビュー機能のサポート範囲に関する詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。

2.7.1. Secrets Store CSI Driver Operator について

Kubernetes シークレットは Base64 エンコーディングで保存されます。etcd は、これらのシークレットの保存時に暗号化しますが、シークレットの取得時に、シークレットが復号化されてユーザーに表示されます。クラスターでロールベースのアクセス制御が適切に設定されていない場合、API または etcd へのアクセス権を持つユーザーは誰でもシークレットを取得または変更できます。さらに、namespace で Pod を作成する権限を持つ人は誰でも、そのアクセス権を使用して、その namespace 内の任意のシークレットを読み取ることができます。

シークレットを安全に保存および管理するには、プロバイダープラグインを使用して、Azure Key Vault などの外部シークレット管理システムからシークレットをマウントするように OpenShift Container Platform Secrets Store Container Storage Interface (CSI) Driver Operator を設定できます。アプリケーションはシークレットを使用できますが、アプリケーション Pod が破棄されるとシークレットはシステム上に保持されません。

Secrets Store CSI Driver Operator (secrets-store.csi.k8s.io) を使用すると、OpenShift Container Platform で、エンタープライズグレードの外部シークレットストアに保存されている複数のシークレット、キー、証明書をボリュームとして Pod にマウントできます。Secrets Store CSI Driver Operator は、gRPC を使用してプロバイダーと通信し、指定された外部シークレットストアからマウントコンテンツを取得します。ボリュームがアタッチされると、その中のデータがコンテナーのファイルシステムにマウントされます。シークレットストアボリュームはインラインでマウントされます。

2.7.1.1. シークレットストアプロバイダー

次のシークレットストアプロバイダーは、Secrets Store CSI Driver Operator で使用できます。

  • AWS Secrets Manager
  • AWS Systems Manager Parameter Store
  • Azure Key Vault
2.7.1.2. 自動ローテーション

Secrets Store CSI ドライバーは、外部シークレットストアのコンテンツを使用して、マウントされたボリューム内のコンテンツを定期的にローテーションします。外部シークレットストアでシークレットが更新されると、マウントされたボリュームでもシークレットが更新されます。Secrets Store CSI Driver Operator は、2 分ごとに更新をポーリングします。

Kubernetes シークレットとしてマウントされたコンテンツの同期を有効にした場合は、Kubernetes シークレットもローテーションされます。

シークレットデータを使用するアプリケーションは、シークレットの更新を監視する必要があります。

2.7.2. Secrets Store CSI ドライバーのインストール

前提条件

  • OpenShift Container Platform Web コンソールにアクセスできる。
  • 管理者としてクラスターにアクセスできる。

手順

Secrets Store CSI ドライバーをインストールするには、以下を実行します。

  1. Secrets Store CSI Driver Operator をインストールします。

    1. Web コンソールにログインします。
    2. OperatorsOperatorHub をクリックします。
    3. フィルターボックスに "Secrets Store CSI" と入力し、Secrets Store CSI Driver Operator を見つけます。
    4. Secrets Store CSI Driver Operator ボタンをクリックします。
    5. Secrets Store CSI Driver Operator ページで、Install をクリックします。
    6. Install Operator のページで、以下のことを確認してください。

      • All namespaces on the cluster (default) が選択されている。
      • Installed Namespaceopenshift-cluster-csi-drivers に設定されている。
    7. Install をクリックします。

      インストールが終了すると、Web コンソールの Installed Operators セクションに GCP Filestore CSI Driver Operator がリストされます。

  2. ドライバーの ClusterCSIDriver インスタンス (secrets-store.csi.k8s.io) を作成します。

    1. AdministrationCustomResourceDefinitionsClusterCSIDriver をクリックします。
    2. Instances タブで Create ClusterCSIDriver をクリックします。

      以下の YAML ファイルを使用します。

      apiVersion: operator.openshift.io/v1
      kind: ClusterCSIDriver
      metadata:
          name: secrets-store.csi.k8s.io
      spec:
        managementState: Managed
    3. Create をクリックします。

2.7.3. 外部シークレットストアから CSI ボリュームへのシークレットのマウント

Secrets Store CSI Driver Operator をインストールした後、次のいずれかの外部シークレットストアから CSI ボリュームにシークレットをマウントできます。

2.7.3.1. AWS Secrets Manager からのシークレットのマウント

Secrets Store CSI Driver Operator を使用して、AWS Secrets Manager から OpenShift Container Platform の CSI ボリュームにシークレットをマウントできます。AWS Secrets Manager からシークレットをマウントするには、クラスターが AWS にインストールされ、AWS Security Token Service (STS) を使用する必要があります。

重要

ホスト型コントロールプレーンクラスターで AWS Secrets Manager を使用する Secrets Store CSI Driver Operator を使用することはサポートされていません。

前提条件

  • クラスターが AWS にインストールされ、AWS Security Token Service (STS) を使用している。
  • Secrets Store CSI Driver Operator がインストールされている。手順は、Secrets Store CSI ドライバーのインストール を参照してください。
  • 必要なシークレットを保存するように AWS Secrets Manager を設定している。
  • ccoctl バイナリーを抽出して準備している。
  • jq CLI ツールがインストールされている。
  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。

手順

  1. AWS Secrets Manager プロバイダーをインストールします。

    1. プロバイダーリソース用に次の設定を使用して YAML ファイルを作成します。

      重要

      Secrets Store CSI ドライバーの AWS Secrets Manager プロバイダーは、アップストリームプロバイダーです。

      この設定は、OpenShift Container Platform で適切に動作するように、アップストリームの AWS ドキュメント で提供されている設定から変更されています。この設定を変更すると、機能に影響が出る場合があります。

      aws-provider.yaml ファイルの例

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: csi-secrets-store-provider-aws
        namespace: openshift-cluster-csi-drivers
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: csi-secrets-store-provider-aws-cluster-role
      rules:
      - apiGroups: [""]
        resources: ["serviceaccounts/token"]
        verbs: ["create"]
      - apiGroups: [""]
        resources: ["serviceaccounts"]
        verbs: ["get"]
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["get"]
      - apiGroups: [""]
        resources: ["nodes"]
        verbs: ["get"]
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: csi-secrets-store-provider-aws-cluster-rolebinding
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: csi-secrets-store-provider-aws-cluster-role
      subjects:
      - kind: ServiceAccount
        name: csi-secrets-store-provider-aws
        namespace: openshift-cluster-csi-drivers
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        namespace: openshift-cluster-csi-drivers
        name: csi-secrets-store-provider-aws
        labels:
          app: csi-secrets-store-provider-aws
      spec:
        updateStrategy:
          type: RollingUpdate
        selector:
          matchLabels:
            app: csi-secrets-store-provider-aws
        template:
          metadata:
            labels:
              app: csi-secrets-store-provider-aws
          spec:
            serviceAccountName: csi-secrets-store-provider-aws
            hostNetwork: false
            containers:
              - name: provider-aws-installer
                image: public.ecr.aws/aws-secrets-manager/secrets-store-csi-driver-provider-aws:1.0.r2-50-g5b4aca1-2023.06.09.21.19
                imagePullPolicy: Always
                args:
                    - --provider-volume=/etc/kubernetes/secrets-store-csi-providers
                resources:
                  requests:
                    cpu: 50m
                    memory: 100Mi
                  limits:
                    cpu: 50m
                    memory: 100Mi
                securityContext:
                  privileged: true
                volumeMounts:
                  - mountPath: "/etc/kubernetes/secrets-store-csi-providers"
                    name: providervol
                  - name: mountpoint-dir
                    mountPath: /var/lib/kubelet/pods
                    mountPropagation: HostToContainer
            tolerations:
            - operator: Exists
            volumes:
              - name: providervol
                hostPath:
                  path: "/etc/kubernetes/secrets-store-csi-providers"
              - name: mountpoint-dir
                hostPath:
                  path: /var/lib/kubelet/pods
                  type: DirectoryOrCreate
            nodeSelector:
              kubernetes.io/os: linux

    2. 次のコマンドを実行して、csi-secrets-store-provider-aws サービスアカウントへの特権アクセスを付与します。

      $ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-aws -n openshift-cluster-csi-drivers
    3. 次のコマンドを実行して、プロバイダーリソースを作成します。

      $ oc apply -f aws-provider.yaml
  2. サービスアカウントに AWS シークレットオブジェクトの読み取りを許可するアクセス許可を付与します。

    1. 次のコマンドを実行して、認証情報リクエストを含むディレクトリーを作成します。

      $ mkdir credentialsrequest-dir-aws
    2. 認証情報リクエスト用に次の設定を使用して YAML ファイルを作成します。

      credentialsrequest.yaml ファイルの例

      apiVersion: cloudcredential.openshift.io/v1
      kind: CredentialsRequest
      metadata:
        name: aws-provider-test
        namespace: openshift-cloud-credential-operator
      spec:
        providerSpec:
          apiVersion: cloudcredential.openshift.io/v1
          kind: AWSProviderSpec
          statementEntries:
          - action:
            - "secretsmanager:GetSecretValue"
            - "secretsmanager:DescribeSecret"
            effect: Allow
            resource: "arn:*:secretsmanager:*:*:secret:testSecret-??????"
        secretRef:
          name: aws-creds
          namespace: my-namespace
        serviceAccountNames:
        - aws-provider

    3. 次のコマンドを実行して、OIDC プロバイダーを取得します。

      $ oc get --raw=/.well-known/openid-configuration | jq -r '.issuer'

      出力例

      https://<oidc_provider_name>

      次のステップで使用するために、出力から OIDC プロバイダー名 <oidc_provider_name> をコピーします。

    4. ccoctl ツールを使用して、次のコマンドを実行して認証情報リクエストを処理します。

      $ ccoctl aws create-iam-roles \
          --name my-role --region=<aws_region> \
          --credentials-requests-dir=credentialsrequest-dir-aws \
          --identity-provider-arn arn:aws:iam::<aws_account>:oidc-provider/<oidc_provider_name> --output-dir=credrequests-ccoctl-output

      出力例

      2023/05/15 18:10:34 Role arn:aws:iam::<aws_account_id>:role/my-role-my-namespace-aws-creds created
      2023/05/15 18:10:34 Saved credentials configuration to: credrequests-ccoctl-output/manifests/my-namespace-aws-creds-credentials.yaml
      2023/05/15 18:10:35 Updated Role policy for Role my-role-my-namespace-aws-creds

      次のステップで使用するために、出力から <aws_role_arn> をコピーします。たとえば、arn:aws:iam::<aws_account_id>:role/my-role-my-namespace-aws-creds。 です

    5. 次のコマンドを実行して、ロール ARN を持つサービスアカウントをバインドします。

      $ oc annotate -n my-namespace sa/aws-provider eks.amazonaws.com/role-arn="<aws_role_arn>"
  3. シークレットプロバイダークラスを作成して、シークレットストアプロバイダーを定義します。

    1. SecretProviderClass オブジェクトを定義する YAML ファイルを作成します。

      secret-provider-class-aws.yaml の例

      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: my-aws-provider                   1
        namespace: my-namespace                 2
      spec:
        provider: aws                           3
        parameters:                             4
          objects: |
            - objectName: "testSecret"
              objectType: "secretsmanager"

      1 1
      シークレットプロバイダークラスの名前を指定します。
      2
      シークレットプロバイダークラスの namespace を指定します。
      3
      プロバイダーを aws として指定します。
      4
      プロバイダー固有の設定パラメーターを指定します。
    2. 次のコマンドを実行して SecretProviderClass オブジェクトを作成します。

      $ oc create -f secret-provider-class-aws.yaml
  4. このシークレットプロバイダークラスを使用するデプロイメントを作成します。

    1. Deployment オブジェクトを定義する YAML ファイルを作成します。

      deployment.yaml の例

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-aws-deployment                              1
        namespace: my-namespace                              2
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: my-storage
        template:
          metadata:
            labels:
              app: my-storage
          spec:
            serviceAccountName: aws-provider
            containers:
            - name: busybox
              image: k8s.gcr.io/e2e-test-images/busybox:1.29
              command:
                - "/bin/sleep"
                - "10000"
              volumeMounts:
              - name: secrets-store-inline
                mountPath: "/mnt/secrets-store"
                readOnly: true
            volumes:
              - name: secrets-store-inline
                csi:
                  driver: secrets-store.csi.k8s.io
                  readOnly: true
                  volumeAttributes:
                    secretProviderClass: "my-aws-provider" 3

      1
      デプロイメントの名前を指定します。
      2
      デプロイメントの namespace を指定します。これは、シークレットプロバイダークラスと同じ namespace である必要があります。
      3
      シークレットプロバイダークラスの名前を指定します。
    2. 次のコマンドを実行して、Deployment オブジェクトを作成します。

      $ oc create -f deployment.yaml

検証

  • Pod ボリュームマウントの AWS Secrets Manager からシークレットにアクセスできることを確認します。

    1. Pod マウント内のシークレットをリスト表示します。

      $ oc exec busybox-<hash> -n my-namespace -- ls /mnt/secrets-store/

      出力例

      testSecret

    2. Pod マウントのシークレットを表示します。

      $ oc exec busybox-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret

      出力例

      <secret_value>

2.7.3.2. AWS Systems Manager パラメーターストアからのシークレットのマウント

Secrets Store CSI Driver Operator を使用して、AWS Systems Manager Parameter Store から OpenShift Container Platform の CSI ボリュームにシークレットをマウントできます。AWS Systems Manager パラメーターストアからシークレットをマウントするには、クラスターが AWS にインストールされ、AWS Security Token Service (STS) を使用する必要があります。

重要

ホスト型コントロールプレーンクラスターで AWS Systems Manager パラメーターストアで Secrets Store CSI Driver Operator を使用することはサポートされていません。

前提条件

  • クラスターが AWS にインストールされ、AWS Security Token Service (STS) を使用している。
  • Secrets Store CSI Driver Operator がインストールされている。手順は、Secrets Store CSI ドライバーのインストール を参照してください。
  • 必要なシークレットを保存するように AWS Systems Manager パラメーターストアを設定している。
  • ccoctl バイナリーを抽出して準備している。
  • jq CLI ツールがインストールされている。
  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。

手順

  1. AWS Systems Manager Parameter Store プロバイダーをインストールします。

    1. プロバイダーリソース用に次の設定を使用して YAML ファイルを作成します。

      重要

      Secrets Store CSI ドライバーの AWS Systems Manager Parameter Store プロバイダーは、アップストリームのプロバイダーです。

      この設定は、OpenShift Container Platform で適切に動作するように、アップストリームの AWS ドキュメント で提供されている設定から変更されています。この設定を変更すると、機能に影響が出る場合があります。

      aws-provider.yaml ファイルの例

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: csi-secrets-store-provider-aws
        namespace: openshift-cluster-csi-drivers
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: csi-secrets-store-provider-aws-cluster-role
      rules:
      - apiGroups: [""]
        resources: ["serviceaccounts/token"]
        verbs: ["create"]
      - apiGroups: [""]
        resources: ["serviceaccounts"]
        verbs: ["get"]
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["get"]
      - apiGroups: [""]
        resources: ["nodes"]
        verbs: ["get"]
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: csi-secrets-store-provider-aws-cluster-rolebinding
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: csi-secrets-store-provider-aws-cluster-role
      subjects:
      - kind: ServiceAccount
        name: csi-secrets-store-provider-aws
        namespace: openshift-cluster-csi-drivers
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        namespace: openshift-cluster-csi-drivers
        name: csi-secrets-store-provider-aws
        labels:
          app: csi-secrets-store-provider-aws
      spec:
        updateStrategy:
          type: RollingUpdate
        selector:
          matchLabels:
            app: csi-secrets-store-provider-aws
        template:
          metadata:
            labels:
              app: csi-secrets-store-provider-aws
          spec:
            serviceAccountName: csi-secrets-store-provider-aws
            hostNetwork: false
            containers:
              - name: provider-aws-installer
                image: public.ecr.aws/aws-secrets-manager/secrets-store-csi-driver-provider-aws:1.0.r2-50-g5b4aca1-2023.06.09.21.19
                imagePullPolicy: Always
                args:
                    - --provider-volume=/etc/kubernetes/secrets-store-csi-providers
                resources:
                  requests:
                    cpu: 50m
                    memory: 100Mi
                  limits:
                    cpu: 50m
                    memory: 100Mi
                securityContext:
                  privileged: true
                volumeMounts:
                  - mountPath: "/etc/kubernetes/secrets-store-csi-providers"
                    name: providervol
                  - name: mountpoint-dir
                    mountPath: /var/lib/kubelet/pods
                    mountPropagation: HostToContainer
            tolerations:
            - operator: Exists
            volumes:
              - name: providervol
                hostPath:
                  path: "/etc/kubernetes/secrets-store-csi-providers"
              - name: mountpoint-dir
                hostPath:
                  path: /var/lib/kubelet/pods
                  type: DirectoryOrCreate
            nodeSelector:
              kubernetes.io/os: linux

    2. 次のコマンドを実行して、csi-secrets-store-provider-aws サービスアカウントへの特権アクセスを付与します。

      $ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-aws -n openshift-cluster-csi-drivers
    3. 次のコマンドを実行して、プロバイダーリソースを作成します。

      $ oc apply -f aws-provider.yaml
  2. サービスアカウントに AWS シークレットオブジェクトの読み取りを許可するアクセス許可を付与します。

    1. 次のコマンドを実行して、認証情報リクエストを含むディレクトリーを作成します。

      $ mkdir credentialsrequest-dir-aws
    2. 認証情報リクエスト用に次の設定を使用して YAML ファイルを作成します。

      credentialsrequest.yaml ファイルの例

      apiVersion: cloudcredential.openshift.io/v1
      kind: CredentialsRequest
      metadata:
        name: aws-provider-test
        namespace: openshift-cloud-credential-operator
      spec:
        providerSpec:
          apiVersion: cloudcredential.openshift.io/v1
          kind: AWSProviderSpec
          statementEntries:
          - action:
            - "ssm:GetParameter"
            - "ssm:GetParameters"
            effect: Allow
            resource: "arn:*:ssm:*:*:parameter/testParameter*"
        secretRef:
          name: aws-creds
          namespace: my-namespace
        serviceAccountNames:
        - aws-provider

    3. 次のコマンドを実行して、OIDC プロバイダーを取得します。

      $ oc get --raw=/.well-known/openid-configuration | jq -r '.issuer'

      出力例

      https://<oidc_provider_name>

      次のステップで使用するために、出力から OIDC プロバイダー名 <oidc_provider_name> をコピーします。

    4. ccoctl ツールを使用して、次のコマンドを実行して認証情報リクエストを処理します。

      $ ccoctl aws create-iam-roles \
          --name my-role --region=<aws_region> \
          --credentials-requests-dir=credentialsrequest-dir-aws \
          --identity-provider-arn arn:aws:iam::<aws_account>:oidc-provider/<oidc_provider_name> --output-dir=credrequests-ccoctl-output

      出力例

      2023/05/15 18:10:34 Role arn:aws:iam::<aws_account_id>:role/my-role-my-namespace-aws-creds created
      2023/05/15 18:10:34 Saved credentials configuration to: credrequests-ccoctl-output/manifests/my-namespace-aws-creds-credentials.yaml
      2023/05/15 18:10:35 Updated Role policy for Role my-role-my-namespace-aws-creds

      次のステップで使用するために、出力から <aws_role_arn> をコピーします。たとえば、arn:aws:iam::<aws_account_id>:role/my-role-my-namespace-aws-creds。 です

    5. 次のコマンドを実行して、ロール ARN を持つサービスアカウントをバインドします。

      $ oc annotate -n my-namespace sa/aws-provider eks.amazonaws.com/role-arn="<aws_role_arn>"
  3. シークレットプロバイダークラスを作成して、シークレットストアプロバイダーを定義します。

    1. SecretProviderClass オブジェクトを定義する YAML ファイルを作成します。

      secret-provider-class-aws.yaml の例

      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: my-aws-provider                   1
        namespace: my-namespace                 2
      spec:
        provider: aws                           3
        parameters:                             4
          objects: |
            - objectName: "testParameter"
              objectType: "ssmparameter"

      1
      シークレットプロバイダークラスの名前を指定します。
      2
      シークレットプロバイダークラスの namespace を指定します。
      3
      プロバイダーを aws として指定します。
      4
      プロバイダー固有の設定パラメーターを指定します。
    2. 次のコマンドを実行して SecretProviderClass オブジェクトを作成します。

      $ oc create -f secret-provider-class-aws.yaml
  4. このシークレットプロバイダークラスを使用するデプロイメントを作成します。

    1. Deployment オブジェクトを定義する YAML ファイルを作成します。

      deployment.yaml の例

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-aws-deployment                              1
        namespace: my-namespace                              2
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: my-storage
        template:
          metadata:
            labels:
              app: my-storage
          spec:
            serviceAccountName: aws-provider
            containers:
            - name: busybox
              image: k8s.gcr.io/e2e-test-images/busybox:1.29
              command:
                - "/bin/sleep"
                - "10000"
              volumeMounts:
              - name: secrets-store-inline
                mountPath: "/mnt/secrets-store"
                readOnly: true
            volumes:
              - name: secrets-store-inline
                csi:
                  driver: secrets-store.csi.k8s.io
                  readOnly: true
                  volumeAttributes:
                    secretProviderClass: "my-aws-provider" 3

      1
      デプロイメントの名前を指定します。
      2
      デプロイメントの namespace を指定します。これは、シークレットプロバイダークラスと同じ namespace である必要があります。
      3
      シークレットプロバイダークラスの名前を指定します。
    2. 次のコマンドを実行して、Deployment オブジェクトを作成します。

      $ oc create -f deployment.yaml

検証

  • Pod ボリュームマウントの AWS Systems Manager パラメーターストアからシークレットにアクセスできることを確認します。

    1. Pod マウント内のシークレットをリスト表示します。

      $ oc exec busybox-<hash> -n my-namespace -- ls /mnt/secrets-store/

      出力例

      testParameter

    2. Pod マウントのシークレットを表示します。

      $ oc exec busybox-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret

      出力例

      <secret_value>

2.7.3.3. Azure Key Vault からのシークレットのマウント

Secrets Store CSI Driver Operator を使用して、Azure Key Vault から OpenShift Container Platform の CSI ボリュームにシークレットをマウントできます。Azure Key Vault からシークレットをマウントするには、クラスターが Microsoft Azure にインストールされている必要があります。

前提条件

  • クラスターは Azure にインストールされている。
  • Secrets Store CSI Driver Operator がインストールされている。手順は、Secrets Store CSI ドライバーのインストール を参照してください。
  • 必要なシークレットを保存するように Azure Key Vault を設定している。
  • Azure CLI (az) がインストールされている。
  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。

手順

  1. Azure Key Vault プロバイダーをインストールします。

    1. プロバイダーリソース用に次の設定を使用して YAML ファイルを作成します。

      重要

      Secrets Store CSI ドライバーの Azure Key Vault プロバイダーは、アップストリームプロバイダーです。

      この設定は、OpenShift Container Platform で適切に動作するように、アップストリームの Azure ドキュメント で提供されている設定から変更されています。この設定を変更すると、機能に影響が出る場合があります。

      azure-provider.yaml ファイルの例

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: csi-secrets-store-provider-azure
        namespace: openshift-cluster-csi-drivers
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: csi-secrets-store-provider-azure-cluster-role
      rules:
      - apiGroups: [""]
        resources: ["serviceaccounts/token"]
        verbs: ["create"]
      - apiGroups: [""]
        resources: ["serviceaccounts"]
        verbs: ["get"]
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["get"]
      - apiGroups: [""]
        resources: ["nodes"]
        verbs: ["get"]
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: csi-secrets-store-provider-azure-cluster-rolebinding
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: csi-secrets-store-provider-azure-cluster-role
      subjects:
      - kind: ServiceAccount
        name: csi-secrets-store-provider-azure
        namespace: openshift-cluster-csi-drivers
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        namespace: openshift-cluster-csi-drivers
        name: csi-secrets-store-provider-azure
        labels:
          app: csi-secrets-store-provider-azure
      spec:
        updateStrategy:
          type: RollingUpdate
        selector:
          matchLabels:
            app: csi-secrets-store-provider-azure
        template:
          metadata:
            labels:
              app: csi-secrets-store-provider-azure
          spec:
            serviceAccountName: csi-secrets-store-provider-azure
            hostNetwork: true
            containers:
              - name: provider-azure-installer
                image: mcr.microsoft.com/oss/azure/secrets-store/provider-azure:v1.4.1
                imagePullPolicy: IfNotPresent
                args:
                  - --endpoint=unix:///provider/azure.sock
                  - --construct-pem-chain=true
                  - --healthz-port=8989
                  - --healthz-path=/healthz
                  - --healthz-timeout=5s
                livenessProbe:
                  httpGet:
                    path: /healthz
                    port: 8989
                  failureThreshold: 3
                  initialDelaySeconds: 5
                  timeoutSeconds: 10
                  periodSeconds: 30
                resources:
                  requests:
                    cpu: 50m
                    memory: 100Mi
                  limits:
                    cpu: 50m
                    memory: 100Mi
                securityContext:
                  allowPrivilegeEscalation: false
                  readOnlyRootFilesystem: true
                  runAsUser: 0
                  capabilities:
                    drop:
                    - ALL
                volumeMounts:
                  - mountPath: "/provider"
                    name: providervol
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                  - matchExpressions:
                    - key: type
                      operator: NotIn
                      values:
                      - virtual-kubelet
            volumes:
              - name: providervol
                hostPath:
                  path: "/var/run/secrets-store-csi-providers"
            tolerations:
            - operator: Exists
            nodeSelector:
              kubernetes.io/os: linux

    2. 次のコマンドを実行して、csi-secrets-store-provider-azure サービスアカウントへの特権アクセスを付与します。

      $ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-azure -n openshift-cluster-csi-drivers
    3. 次のコマンドを実行して、プロバイダーリソースを作成します。

      $ oc apply -f azure-provider.yaml
  2. Key Vault にアクセスするためのサービスプリンシパルを作成します。

    1. 次のコマンドを実行して、サービスプリンシパルのクライアントシークレットを環境変数として設定します。

      $ SERVICE_PRINCIPAL_CLIENT_SECRET="$(az ad sp create-for-rbac --name https://$KEYVAULT_NAME --query 'password' -otsv)"
    2. 次のコマンドを実行して、サービスプリンシパルのクライアント ID を環境変数として設定します。

      $ SERVICE_PRINCIPAL_CLIENT_ID="$(az ad sp list --display-name https://$KEYVAULT_NAME --query '[0].appId' -otsv)"
    3. 次のコマンドを実行して、サービスプリンシパルのクライアントシークレットと ID を使用して汎用シークレットを作成します。

      $ oc create secret generic secrets-store-creds -n my-namespace --from-literal clientid=${SERVICE_PRINCIPAL_CLIENT_ID} --from-literal clientsecret=${SERVICE_PRINCIPAL_CLIENT_SECRET}
    4. secrets-store.csi.k8s.io/used=true ラベルを適用して、プロバイダーがこの nodePublishSecretRef シークレットを検索できるようにします。

      $ oc -n my-namespace label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
  3. シークレットプロバイダークラスを作成して、シークレットストアプロバイダーを定義します。

    1. SecretProviderClass オブジェクトを定義する YAML ファイルを作成します。

      secret-provider-class-azure.yaml の例

      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: my-azure-provider                 1
        namespace: my-namespace                 2
      spec:
        provider: azure                         3
        parameters:                             4
          usePodIdentity: "false"
          useVMManagedIdentity: "false"
          userAssignedIdentityID: ""
          keyvaultName: "kvname"
          objects: |
            array:
              - |
                objectName: secret1
                objectType: secret
          tenantId: "tid"

      1
      シークレットプロバイダークラスの名前を指定します。
      2
      シークレットプロバイダークラスの namespace を指定します。
      3
      プロバイダーを azure として指定します。
      4
      プロバイダー固有の設定パラメーターを指定します。
    2. 次のコマンドを実行して SecretProviderClass オブジェクトを作成します。

      $ oc create -f secret-provider-class-azure.yaml
  4. このシークレットプロバイダークラスを使用するデプロイメントを作成します。

    1. Deployment オブジェクトを定義する YAML ファイルを作成します。

      deployment.yaml の例

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-azure-deployment                            1
        namespace: my-namespace                              2
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: my-storage
        template:
          metadata:
            labels:
              app: my-storage
          spec:
            containers:
            - name: busybox
              image: k8s.gcr.io/e2e-test-images/busybox:1.29
              command:
                - "/bin/sleep"
                - "10000"
              volumeMounts:
              - name: secrets-store-inline
                mountPath: "/mnt/secrets-store"
                readOnly: true
            volumes:
              - name: secrets-store-inline
                csi:
                  driver: secrets-store.csi.k8s.io
                  readOnly: true
                  volumeAttributes:
                    secretProviderClass: "my-azure-provider" 3
                  nodePublishSecretRef:
                    name: secrets-store-creds                4

      1
      デプロイメントの名前を指定します。
      2
      デプロイメントの namespace を指定します。これは、シークレットプロバイダークラスと同じ namespace である必要があります。
      3
      シークレットプロバイダークラスの名前を指定します。
      4
      Azure Key Vault にアクセスするためのサービスプリンシパル認証情報を含む Kubernetes シークレットの名前を指定します。
    2. 次のコマンドを実行して、Deployment オブジェクトを作成します。

      $ oc create -f deployment.yaml

検証

  • Pod ボリュームマウント内の Azure Key Vault からシークレットにアクセスできることを確認します。

    1. Pod マウント内のシークレットをリスト表示します。

      $ oc exec busybox-<hash> -n my-namespace -- ls /mnt/secrets-store/

      出力例

      secret1

    2. Pod マウントのシークレットを表示します。

      $ oc exec busybox-<hash> -n my-namespace -- cat /mnt/secrets-store/secret1

      出力例

      my-secret-value

2.7.4. マウントされたコンテンツを Kubernetes シークレットとして同期できるようにする

同期を有効にして、マウントされたボリューム上のコンテンツから Kubernetes シークレットを作成できます。同期を有効にする例としては、デプロイメント内で環境変数を使用して Kubernetes シークレットを参照することが挙げられます。

警告

シークレットを OpenShift Container Platform クラスターおよび etcd に保存しない場合は、同期を有効にしないでください。この機能は、環境変数を使用してシークレットを参照する場合など、必要な場合にのみ有効にしてください。

同期を有効にすると、シークレットをマウントする Pod を開始した後、マウントされたボリュームのシークレットが Kubernetes シークレットとして同期されます。

コンテンツをマウントしたすべての Pod が削除されると、同期された Kubernetes シークレットも削除されます。

前提条件

  • Secrets Store CSI Driver Operator がインストールされている。
  • シークレットストアプロバイダーがインストールされている。
  • シークレットプロバイダークラスが作成されている。
  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。

手順

  1. 次のコマンドを実行して、SecretProviderClass リソースを編集します。

    $ oc edit secretproviderclass my-azure-provider 1
    1
    my-azure-provider をシークレットプロバイダークラスの名前に置き換えます。
  2. 同期された Kubernetes シークレットの設定を含む secretsObjects セクションを追加します。

    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: my-azure-provider
      namespace: my-namespace
    spec:
      provider: azure
      secretObjects:                                   1
        - secretName: tlssecret                        2
          type: kubernetes.io/tls                      3
          labels:
            environment: "test"
          data:
            - objectName: tlskey                       4
              key: tls.key                             5
            - objectName: tlscrt
              key: tls.crt
      parameters:
        usePodIdentity: "false"
        keyvaultName: "kvname"
        objects:  |
          array:
            - |
              objectName: tlskey
              objectType: secret
            - |
              objectName: tlscrt
              objectType: secret
        tenantId: "tid"
    1
    同期された Kubernetes シークレットの設定を指定します。
    2
    作成する Kubernetes Secret オブジェクトの名前を指定します。
    3
    作成する Kubernetes Secret オブジェクトのタイプを指定します。たとえば、Opaque または kubernetes.io/tls です。
    4
    同期するマウントされたコンテンツのオブジェクト名またはエイリアスを指定します。
    5
    Kubernetes シークレットに設定するデータフィールドを、指定した objectName から指定します。
  3. 変更を適用するためにファイルを保存します。

2.7.5. Pod ボリュームマウント内のシークレットのステータスの表示

Pod ボリュームマウント内のシークレットのバージョンなどの詳細情報を表示できます。

Secrets Store CSI Driver Operator は、Pod と同じ namespace に SecretProviderClassPodStatus リソースを作成します。このリソースを確認すると、Pod ボリュームマウントのシークレットに関するバージョンなどの詳細情報を確認できます。

前提条件

  • Secrets Store CSI Driver Operator がインストールされている。
  • シークレットストアプロバイダーがインストールされている。
  • シークレットプロバイダークラスが作成されている。
  • Secrets Store CSI Driver Operator からボリュームをマウントする Pod をデプロイしている。
  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。

手順

  • 次のコマンドを実行して、Pod ボリュームマウントのシークレットに関する詳細情報を表示します。

    $ oc get secretproviderclasspodstatus <secret_provider_class_pod_status_name> -o yaml 1
    1
    シークレットプロバイダークラスの Pod ステータスオブジェクトの名前は、<pod_name>-<namespace>-<secret_provider_class_name> の形式になります。

    出力例

    ...
    status:
      mounted: true
      objects:
      - id: secret/tlscrt
        version: f352293b97da4fa18d96a9528534cb33
      - id: secret/tlskey
        version: 02534bc3d5df481cb138f8b2a13951ef
      podName: busybox-<hash>
      secretProviderClassName: my-azure-provider
      targetPath: /var/lib/kubelet/pods/f0d49c1e-c87a-4beb-888f-37798456a3e7/volumes/kubernetes.io~csi/secrets-store-inline/mount

2.7.6. Secrets Store CSI Driver Operator のアンインストール

前提条件

  • OpenShift Container Platform Web コンソールにアクセスできる。
  • 管理者としてクラスターにアクセスできる。

手順

Secrets Store CSI Driver Operator をアンインストールするには、以下を実行します。

  1. Secrets-store.csi.k8s.io プロバイダーを使用するすべてのアプリケーション Pod を停止します。
  2. 選択したシークレットストアのサードパーティープロバイダープラグインをすべて削除します。
  3. Container Storage Interface (CSI) ドライバーと関連するマニフェストを削除します。

    1. AdministrationCustomResourceDefinitionsClusterCSIDriver をクリックします。
    2. Instances タブの左端にある secrets-store.csi.k8s.io でドロップダウンメニューをクリックし、Delete ClusterCSIDriver をクリックします。
    3. プロンプトが表示されたら、Delete をクリックします。
  4. CSI ドライバー Pod が稼働していないことを確認します。
  5. Secrets Store CSI Driver Operator をアンインストールします。

    注記

    Operator をアンインストールする前に、まず CSI ドライバーを削除する必要があります。

    1. OperatorsInstalled Operators をクリックします。
    2. Installed Operators ページで、スクロールするか、Search by name ボックスに "Secrets Store CSI" と入力して Operator を見つけ、クリックします。
    3. Installed Operators > Operator details ページの右上に表示される ActionsUninstall Operator をクリックします。
    4. Uninstall Operator ウィンドウでプロンプトが表示されたら、Uninstall ボタンをクリックして namespace から Operator を削除します。Operator によってクラスターにデプロイされたアプリケーションは手動でクリーンアップする必要があります。

      アンインストールすると、Secrets Store CSI Driver Operator は Web コンソールの Installed Operators セクションにリストされなくなります。

2.8. 設定マップの作成および使用

以下のセクションでは、設定マップおよびそれらを作成し、使用する方法を定義します。

2.8.1. 設定マップについて

数多くのアプリケーションには、設定ファイル、コマンドライン引数、および環境変数の組み合わせを使用した設定が必要です。OpenShift Container Platform では、これらの設定アーティファクトは、コンテナー化されたアプリケーションを移植可能な状態に保つためにイメージコンテンツから切り離されます。

ConfigMap オブジェクトは、コンテナーを OpenShift Container Platform に依存させないようにする一方で、コンテナーに設定データを挿入するメカニズムを提供します。設定マップは、個々のプロパティーなどの粒度の細かい情報や、設定ファイル全体または JSON Blob などの粒度の荒い情報を保存するために使用できます。

ConfigMap オブジェクトは、Pod で使用したり、コントローラーなどのシステムコンポーネントの設定データを保存するために使用できる設定データのキーと値のペアを保持します。以下に例を示します。

ConfigMap オブジェクト定義

kind: ConfigMap
apiVersion: v1
metadata:
  creationTimestamp: 2016-02-18T19:14:38Z
  name: example-config
  namespace: my-namespace
data: 1
  example.property.1: hello
  example.property.2: world
  example.property.file: |-
    property.1=value-1
    property.2=value-2
    property.3=value-3
binaryData:
  bar: L3Jvb3QvMTAw 2

1
設定データが含まれます。
2
バイナリー Java キーストアファイルなどの UTF8 以外のデータを含むファイルを参照します。Base 64 のファイルデータを入力します。
注記

イメージなどのバイナリーファイルから設定マップを作成する場合に、binaryData フィールドを使用できます。

設定データはさまざまな方法で Pod 内で使用できます。設定マップは以下を実行するために使用できます。

  • コンテナーへの環境変数値の設定
  • コンテナーのコマンドライン引数の設定
  • ボリュームの設定ファイルの設定

ユーザーとシステムコンポーネントの両方が設定データを設定マップに保存できます。

設定マップはシークレットに似ていますが、機密情報を含まない文字列の使用をより効果的にサポートするように設計されています。

設定マップの制限

設定マップは、コンテンツを Pod で使用される前に作成する必要があります。

コントローラーは、設定データが不足していても、その状況を許容して作成できます。ケースごとに設定マップを使用して設定される個々のコンポーネントを参照してください。

ConfigMap オブジェクトはプロジェクト内にあります。

それらは同じプロジェクトの Pod によってのみ参照されます。

Kubelet は、API サーバーから取得する Pod の設定マップの使用のみをサポートします。

これには、CLI を使用して作成された Pod、またはレプリケーションコントローラーから間接的に作成された Pod が含まれます。これには、OpenShift Container Platform ノードの --manifest-url フラグ、その --config フラグ、またはその REST API を使用して作成された Pod は含まれません (これらは Pod を作成する一般的な方法ではありません)。

2.8.2. OpenShift Container Platform Web コンソールでの設定マップの作成

OpenShift Container Platform Web コンソールで設定マップを作成できます。

手順

  • クラスター管理者として設定マップを作成するには、以下を実行します。

    1. Administrator パースペクティブで WorkloadsConfig Maps を選択します。
    2. ページの右上にある Create Config Map を選択します。
    3. 設定マップの内容を入力します。
    4. Create を選択します。
  • 開発者として設定マップを作成するには、以下を実行します。

    1. 開発者パースペクティブで、Config Maps を選択します。
    2. ページの右上にある Create Config Map を選択します。
    3. 設定マップの内容を入力します。
    4. Create を選択します。

2.8.3. CLI を使用して設定マップを作成する

以下のコマンドを使用して、ディレクトリー、特定のファイルまたはリテラル値から設定マップを作成できます。

手順

  • 設定マップの作成

    $ oc create configmap <configmap_name> [options]
2.8.3.1. ディレクトリーからの設定マップの作成

--from-file フラグを使用すると、ディレクトリーから config map を作成できます。この方法では、ディレクトリー内の複数のファイルを使用して設定マップを作成できます。

ディレクトリー内の各ファイルは、config map にキーを設定するために使用されます。キーの名前はファイル名で、キーの値はファイルの内容です。

たとえば、次のコマンドは、example-files ディレクトリーの内容を使用して config map を作成します。

$ oc create configmap game-config --from-file=example-files/

config map 内のキーを表示します。

$ oc describe configmaps game-config

出力例

Name:           game-config
Namespace:      default
Labels:         <none>
Annotations:    <none>

Data

game.properties:        158 bytes
ui.properties:          83 bytes

マップにある 2 つのキーが、コマンドで指定されたディレクトリーのファイル名に基づいて作成されていることに気づかれることでしょう。これらのキーの内容は大きい可能性があるため、oc describe の出力にはキーの名前とそのサイズのみが表示されます。

前提条件

  • config map に追加するデータを含むファイルを含むディレクトリーが必要です。

    次の手順では、サンプルファイル game.properties および ui.properties を使用します。

    $ cat example-files/game.properties

    出力例

    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30

    $ cat example-files/ui.properties

    出力例

    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice

手順

  • 次のコマンドを入力して、このディレクトリー内の各ファイルの内容を保持する設定マップを作成します。

    $ oc create configmap game-config \
        --from-file=example-files/

検証

  • -o オプションを使用してオブジェクトの oc get コマンドを入力し、キーの値を表示します。

    $ oc get configmaps game-config -o yaml

    出力例

    apiVersion: v1
    data:
      game.properties: |-
        enemies=aliens
        lives=3
        enemies.cheat=true
        enemies.cheat.level=noGoodRotten
        secret.code.passphrase=UUDDLRLRBABAS
        secret.code.allowed=true
        secret.code.lives=30
      ui.properties: |
        color.good=purple
        color.bad=yellow
        allow.textmode=true
        how.nice.to.look=fairlyNice
    kind: ConfigMap
    metadata:
      creationTimestamp: 2016-02-18T18:34:05Z
      name: game-config
      namespace: default
      resourceVersion: "407"
      selflink: /api/v1/namespaces/default/configmaps/game-config
      uid: 30944725-d66e-11e5-8cd0-68f728db1985

2.8.3.2. ファイルから設定マップを作成する

--from-file フラグを使用すると、ファイルから config map を作成できます。--from-file オプションを CLI に複数回渡すことができます。

key=value 式を --from-file オプションに渡すことで、ファイルからインポートされたコンテンツの config map に設定するキーを指定することもできます。以下に例を示します。

$ oc create configmap game-config-3 --from-file=game-special-key=example-files/game.properties
注記

ファイルから設定マップを作成する場合、UTF8 以外のデータを破損することなく、UTF8 以外のデータを含むファイルをこの新規フィールドに配置できます。OpenShift Container Platform はバイナリーファイルを検出し、ファイルを MIME として透過的にエンコーディングします。サーバーでは、データを破損することなく MIME ペイロードがデコーディングされ、保存されます。

前提条件

  • config map に追加するデータを含むファイルを含むディレクトリーが必要です。

    次の手順では、サンプルファイル game.properties および ui.properties を使用します。

    $ cat example-files/game.properties

    出力例

    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30

    $ cat example-files/ui.properties

    出力例

    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice

手順

  • 特定のファイルを指定して設定マップを作成します。

    $ oc create configmap game-config-2 \
        --from-file=example-files/game.properties \
        --from-file=example-files/ui.properties
  • キーと値のペアを指定して、設定マップを作成します。

    $ oc create configmap game-config-3 \
        --from-file=game-special-key=example-files/game.properties

検証

  • -o オプションを使用してオブジェクトの oc get コマンドを入力し、ファイルからキーの値を表示します。

    $ oc get configmaps game-config-2 -o yaml

    出力例

    apiVersion: v1
    data:
      game.properties: |-
        enemies=aliens
        lives=3
        enemies.cheat=true
        enemies.cheat.level=noGoodRotten
        secret.code.passphrase=UUDDLRLRBABAS
        secret.code.allowed=true
        secret.code.lives=30
      ui.properties: |
        color.good=purple
        color.bad=yellow
        allow.textmode=true
        how.nice.to.look=fairlyNice
    kind: ConfigMap
    metadata:
      creationTimestamp: 2016-02-18T18:52:05Z
      name: game-config-2
      namespace: default
      resourceVersion: "516"
      selflink: /api/v1/namespaces/default/configmaps/game-config-2
      uid: b4952dc3-d670-11e5-8cd0-68f728db1985

  • -o オプションを使用してオブジェクトの oc get コマンドを入力し、key-value (キー/値) ペアからキーの値を表示します。

    $ oc get configmaps game-config-3 -o yaml

    出力例

    apiVersion: v1
    data:
      game-special-key: |- 1
        enemies=aliens
        lives=3
        enemies.cheat=true
        enemies.cheat.level=noGoodRotten
        secret.code.passphrase=UUDDLRLRBABAS
        secret.code.allowed=true
        secret.code.lives=30
    kind: ConfigMap
    metadata:
      creationTimestamp: 2016-02-18T18:54:22Z
      name: game-config-3
      namespace: default
      resourceVersion: "530"
      selflink: /api/v1/namespaces/default/configmaps/game-config-3
      uid: 05f8da22-d671-11e5-8cd0-68f728db1985

    1
    これは、先の手順で設定したキーです。
2.8.3.3. リテラル値からの設定マップの作成

設定マップにリテラル値を指定することができます。

--from-literal オプションは、リテラル値をコマンドラインに直接指定できる key=value 構文を取ります。

手順

  • リテラル値を指定して設定マップを作成します。

    $ oc create configmap special-config \
        --from-literal=special.how=very \
        --from-literal=special.type=charm

検証

  • -o オプションを使用してオブジェクトの oc get コマンドを入力し、キーの値を表示します。

    $ oc get configmaps special-config -o yaml

    出力例

    apiVersion: v1
    data:
      special.how: very
      special.type: charm
    kind: ConfigMap
    metadata:
      creationTimestamp: 2016-02-18T19:14:38Z
      name: special-config
      namespace: default
      resourceVersion: "651"
      selflink: /api/v1/namespaces/default/configmaps/special-config
      uid: dadce046-d673-11e5-8cd0-68f728db1985

2.8.4. ユースケース: Pod で設定マップを使用する

以下のセクションでは、Pod で ConfigMap オブジェクトを使用する際のいくつかのユースケースを説明します。

2.8.4.1. 設定マップの使用によるコンテナーでの環境変数の設定

config map を使用して、コンテナーで個別の環境変数を設定するために使用したり、有効な環境変数名を生成するすべてのキーを使用してコンテナーで環境変数を設定するために使用したりすることができます。

例として、以下の設定マップについて見てみましょう。

2 つの環境変数を含む ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config 1
  namespace: default 2
data:
  special.how: very 3
  special.type: charm 4

1
設定マップの名前。
2
設定マップが存在するプロジェクト。設定マップは同じプロジェクトの Pod によってのみ参照されます。
3 4
挿入する環境変数。

1 つの環境変数を含む ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config 1
  namespace: default
data:
  log_level: INFO 2

1
設定マップの名前。
2
挿入する環境変数。

手順

  • configMapKeyRef セクションを使用して、Pod のこの ConfigMap のキーを使用できます。

    特定の環境変数を挿入するように設定されている Pod 仕様のサンプル

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      containers:
        - name: test-container
          image: gcr.io/google_containers/busybox
          command: [ "/bin/sh", "-c", "env" ]
          env: 1
            - name: SPECIAL_LEVEL_KEY 2
              valueFrom:
                configMapKeyRef:
                  name: special-config 3
                  key: special.how 4
            - name: SPECIAL_TYPE_KEY
              valueFrom:
                configMapKeyRef:
                  name: special-config 5
                  key: special.type 6
                  optional: true 7
          envFrom: 8
            - configMapRef:
                name: env-config 9
      restartPolicy: Never

    1
    ConfigMap から指定された環境変数をプルするためのスタンザです。
    2
    キーの値を挿入する Pod 環境変数の名前です。
    3 5
    特定の環境変数のプルに使用する ConfigMap の名前です。
    4 6
    ConfigMap からプルする環境変数です。
    7
    環境変数をオプションにします。オプションとして、Pod は指定された ConfigMap およびキーが存在しない場合でも起動します。
    8
    ConfigMap からすべての環境変数をプルするためのスタンザです。
    9
    すべての環境変数のプルに使用する ConfigMap の名前です。

    この Pod が実行されると、Pod のログには以下の出力が含まれます。

    SPECIAL_LEVEL_KEY=very
    log_level=INFO
注記

SPECIAL_TYPE_KEY=charm は出力例にリスト表示されません。optional: true が設定されているためです。

2.8.4.2. 設定マップを使用したコンテナーコマンドのコマンドライン引数の設定

config map を使用すると、Kubernetes 置換構文 $(VAR_NAME) を使用してコンテナー内のコマンドまたは引数の値を設定できます。

例として、以下の設定マップについて見てみましょう。

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm

手順

  • コンテナー内のコマンドに値を挿入するには、環境変数として使用するキーを使用する必要があります。次に、$(VAR_NAME) 構文を使用してコンテナーのコマンドでそれらを参照することができます。

    特定の環境変数を挿入するように設定されている Pod 仕様のサンプル

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      containers:
        - name: test-container
          image: gcr.io/google_containers/busybox
          command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] 1
          env:
            - name: SPECIAL_LEVEL_KEY
              valueFrom:
                configMapKeyRef:
                  name: special-config
                  key: special.how
            - name: SPECIAL_TYPE_KEY
              valueFrom:
                configMapKeyRef:
                  name: special-config
                  key: special.type
      restartPolicy: Never

    1
    環境変数として使用するキーを使用して、コンテナーのコマンドに値を挿入します。

    この Pod が実行されると、test-container コンテナーで実行される echo コマンドの出力は以下のようになります。

    very charm
2.8.4.3. 設定マップの使用によるボリュームへのコンテンツの挿入

設定マップを使用して、コンテンツをボリュームに挿入することができます。

ConfigMap カスタムリソース (CR) の例

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm

手順

設定マップを使用してコンテンツをボリュームに挿入するには、2 つの異なるオプションを使用できます。

  • 設定マップを使用してコンテンツをボリュームに挿入するための最も基本的な方法は、キーがファイル名であり、ファイルの内容がキーの値になっているファイルでボリュームを設定する方法です。

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      containers:
        - name: test-container
          image: gcr.io/google_containers/busybox
          command: [ "/bin/sh", "-c", "cat", "/etc/config/special.how" ]
          volumeMounts:
          - name: config-volume
            mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: special-config 1
      restartPolicy: Never
    1
    キーを含むファイル。

    この Pod が実行されると、cat コマンドの出力は以下のようになります。

    very
  • 設定マップキーが投影されるボリューム内のパスを制御することもできます。

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      containers:
        - name: test-container
          image: gcr.io/google_containers/busybox
          command: [ "/bin/sh", "-c", "cat", "/etc/config/path/to/special-key" ]
          volumeMounts:
          - name: config-volume
            mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: special-config
            items:
            - key: special.how
              path: path/to/special-key 1
      restartPolicy: Never
    1
    設定マップキーへのパス。

    この Pod が実行されると、cat コマンドの出力は以下のようになります。

    very

2.9. Pod で外部リソースにアクセスするためのデバイスプラグインの使用

デバイスプラグインを使用すると、カスタムコードを作成せずに特定のデバイスタイプ (GPU、InfiniBand、またはベンダー固有の初期化およびセットアップを必要とする他の同様のコンピューティングリソース) を OpenShift Container Platform Pod で使用できます。

2.9.1. デバイスプラグインについて

デバイスプラグインは、クラスター間でハードウェアデバイスを使用する際の一貫した移植可能なソリューションを提供します。デバイスプラグインは、拡張メカニズムを通じてこれらのデバイスをサポートし (これにより、コンテナーがこれらのデバイスを利用できるようになります)、デバイスのヘルスチェックを実施し、それらを安全に共有します。

重要

OpenShift Container Platform はデバイスのプラグイン API をサポートしますが、デバイスプラグインコンテナーは個別のベンダーによりサポートされます。

デバイスプラグインは、特定のハードウェアリソースの管理を行う、ノード上で実行される gRPC サービスです (kubelet の外部にあります)。デバイスプラグインは以下のリモートプロシージャーコール (RPC) をサポートしている必要があります。

service DevicePlugin {
      // GetDevicePluginOptions returns options to be communicated with Device
      // Manager
      rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}

      // ListAndWatch returns a stream of List of Devices
      // Whenever a Device state change or a Device disappears, ListAndWatch
      // returns the new list
      rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}

      // Allocate is called during container creation so that the Device
      // Plug-in can run device specific operations and instruct Kubelet
      // of the steps to make the Device available in the container
      rpc Allocate(AllocateRequest) returns (AllocateResponse) {}

      // PreStartcontainer is called, if indicated by Device Plug-in during
      // registration phase, before each container start. Device plug-in
      // can run device specific operations such as resetting the device
      // before making devices available to the container
      rpc PreStartcontainer(PreStartcontainerRequest) returns (PreStartcontainerResponse) {}
}
デバイスプラグインの例
注記

デバイスプラグイン参照の実装を容易にするために、vendor/k8s.io/kubernetes/pkg/kubelet/cm/deviceplugin/device_plugin_stub.go という Device Manager コードのスタブデバイスプラグインを使用できます。

2.9.1.1. デバイスプラグインのデプロイ方法
  • デーモンセットは、デバイスプラグインのデプロイメントに推奨される方法です。
  • 起動時にデバイスプラグインは、Device Manager から RPC を送信するためにノードの /var/lib/kubelet/device-plugin/ での UNIX ドメインソケットの作成を試行します。
  • デバイスプラグインは、ソケットの作成のほかにもハードウェアリソース、ホストファイルシステムへのアクセスを管理する必要があるため、特権付きセキュリティーコンテキストで実行される必要があります。
  • デプロイメント手順の詳細は、それぞれのデバイスプラグインの実装で確認できます。

2.9.2. Device Manager について

Device Manager は、特殊なノードのハードウェアリソースを、デバイスプラグインとして知られるプラグインを使用して公開するメカニズムを提供します。

特殊なハードウェアは、アップストリームのコード変更なしに公開できます。

重要

OpenShift Container Platform はデバイスのプラグイン API をサポートしますが、デバイスプラグインコンテナーは個別のベンダーによりサポートされます。

Device Manager はデバイスを 拡張リソース として公開します。ユーザー Pod は、他の 拡張リソース を要求するために使用されるのと同じ 制限/要求 メカニズムを使用して Device Manager で公開されるデバイスを消費できます。

使用開始時に、デバイスプラグインは /var/lib/kubelet/device-plugins/kubelet.sockRegister を起動して Device Manager に自己登録し、Device Manager の要求を提供するために /var/lib/kubelet/device-plugins/<plugin>.sock で gRPC サービスを起動します。

Device Manager は、新規登録要求の処理時にデバイスプラグインサービスで ListAndWatch リモートプロシージャーコール (RPC) を起動します。応答として Device Manager は gRPC ストリームでプラグインから デバイス オブジェクトの一覧を取得します。Device Manager はプラグインからの新規の更新の有無についてストリームを監視します。プラグイン側では、プラグインはストリームを開いた状態にし、デバイスの状態に変更があった場合には常に新規デバイスの一覧が同じストリーム接続で Device Manager に送信されます。

新規 Pod の受付要求の処理時に、Kubelet はデバイスの割り当てのために要求された Extended Resource を Device Manager に送信します。Device Manager はそのデータベースにチェックインして対応するプラグインが存在するかどうかを確認します。プラグインが存在し、ローカルキャッシュと共に割り当て可能な空きデバイスがある場合、Allocate RPC がその特定デバイスのプラグインで起動します。

さらにデバイスプラグインは、ドライバーのインストール、デバイスの初期化、およびデバイスのリセットなどの他のいくつかのデバイス固有の操作も実行できます。これらの機能は実装ごとに異なります。

2.9.3. Device Manager の有効化

Device Manager を有効にし、デバイスプラグインを実装してアップストリームのコード変更なしに特殊なハードウェアを公開できるようにします。

Device Manager は、特殊なノードのハードウェアリソースを、デバイスプラグインとして知られるプラグインを使用して公開するメカニズムを提供します。

  1. 次のコマンドを入力して、設定するノードタイプの静的な MachineConfigPool CRD に関連付けられたラベルを取得します。以下のいずれかの手順を実行します。

    1. マシン設定を表示します。

      # oc describe machineconfig <name>

      以下に例を示します。

      # oc describe machineconfig 00-worker

      出力例

      Name:         00-worker
      Namespace:
      Labels:       machineconfiguration.openshift.io/role=worker 1

      1
      Device Manager に必要なラベル。

手順

  1. 設定変更のためのカスタムリソース (CR) を作成します。

    Device Manager CR の設定例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: devicemgr 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
           machineconfiguration.openshift.io: devicemgr 2
      kubeletConfig:
        feature-gates:
          - DevicePlugins=true 3

    1
    CR に名前を割り当てます。
    2
    Machine Config Pool からラベルを入力します。
    3
    DevicePlugins を 'true` に設定します。
  2. Device Manager を作成します。

    $ oc create -f devicemgr.yaml

    出力例

    kubeletconfig.machineconfiguration.openshift.io/devicemgr created

  3. Device Manager が実際に有効にされるように、/var/lib/kubelet/device-plugins/kubelet.sock がノードで作成されていることを確認します。これは、Device Manager の gRPC サーバーが新規プラグインの登録がないかどうかリッスンする UNIX ドメインソケットです。このソケットファイルは、Device Manager が有効にされている場合にのみ Kubelet の起動時に作成されます。

2.10. Pod スケジューリングの決定に Pod の優先順位を含める

クラスターで Pod の優先順位およびプリエンプションを有効にできます。Pod の優先度は、他の Pod との比較した Pod の重要度を示し、その優先度に基づいて Pod をキューに入れます。Pod のプリエンプションは、クラスターが優先順位の低い Pod のエビクトまたはプリエンプションを実行することを可能にするため、適切なノードに利用可能な領域がない場合に優先順位のより高い Pod をスケジュールできます。 Pod の優先順位は Pod のスケジューリングの順序にも影響を与え、リソース不足の場合のノード上でのエビクションの順序に影響を与えます。

優先順位およびプリエンプションを使用するには、Pod の相対的な重みを定義する優先順位クラスを作成します。次に Pod 仕様で優先順位クラスを参照し、スケジューリングの重みを適用します。

2.10.1. Pod の優先順位について

Pod の優先順位およびプリエンプション機能を使用する場合、スケジューラーは優先順位に基づいて保留中の Pod を順序付け、保留中の Pod はスケジューリングのキューで優先順位のより低い他の保留中の Pod よりも前に置かれます。その結果、より優先順位の高い Pod は、スケジューリングの要件を満たす場合に優先順位の低い Pod よりも早くスケジュールされる可能性があります。Pod をスケジュールできない場合、スケジューラーは引き続き他の優先順位の低い Pod をスケジュールします。

2.10.1.1. Pod の優先順位クラス

Pod には優先順位クラスを割り当てることができます。これは、名前から優先順位の整数値へのマッピングを定義する namespace を使用していないオブジェクトです。値が高いと優先順位が高くなります。

優先順位およびプリエンプションは、1000000000 (10 億) 以下の 32 ビットの整数値を取ることができます。プリエンプションやエビクションを実行すべきでない Critical Pod 用に 10 億以上の数値を予約する必要があります。デフォルトで、OpenShift Container Platform には 2 つの予約された優先順位クラスがあり、これらは重要なシステム Pod で保証されたスケジューリングが適用されるために使用されます。

$ oc get priorityclasses

出力例

NAME                      VALUE        GLOBAL-DEFAULT   AGE
system-node-critical      2000001000   false            72m
system-cluster-critical   2000000000   false            72m
openshift-user-critical   1000000000   false            3d13h
cluster-logging           1000000      false            29s

  • system-node-critical: この優先順位クラスには 2000001000 の値があり、ノードからエビクトすべきでないすべての Pod に使用されます。この優先順位クラスを持つ Pod の例として、sdn-ovssdn などがあります。数多くの重要なコンポーネントには、デフォルトで system-node-critical の優先順位クラスが含まれます。以下は例になります。

    • master-api
    • master-controller
    • master-etcd
    • sdn
    • sdn-ovs
    • sync
  • system-cluster-critical: この優先順位クラスには 2000000000 (20 億) の値があり、クラスターに重要な Pod に使用されます。この優先順位クラスの Pod は特定の状況でノードからエビクトされる可能性があります。たとえば、system-node-critical 優先順位クラスで設定される Pod が優先される可能性があります。この場合でも、この優先順位クラスではスケジューリングが保証されます。この優先順位クラスを持つ可能性のある Pod の例として、fluentd、descheduler などのアドオンコンポーネントなどがあります。数多くの重要なコンポーネントには、デフォルトで system-cluster-critical 優先順位クラスが含まれます。 以下はその一例です。

    • fluentd
    • metrics-server
    • descheduler
  • openshift-user-critical: priorityClassName フィールドを、リソース消費をバインドできず、予測可能なリソース消費動作がない重要な Pod で使用できます。openshift-monitoring および openshift-user-workload-monitoring namespace 下にある Prometheus Pod は、openshift-user-critical priorityClassName を使用します。モニタリングのワークロードは system-critical を最初の priorityClass として使用しますが、これにより、モニタリング時にメモリーが過剰に使用され、ノードがエビクトできない問題が発生します。その結果、モニタリングの優先順位が下がり、スケジューラーに柔軟性が与えられ、重要なノードの動作を維持するために重いワークロード発生します。
  • cluster-logging: この優先順位は、Fluentd Pod が他のアプリケーションより優先してノードにスケジュールされるようにするために Fluentd で使用されます。
2.10.1.2. Pod の優先順位名

1 つ以上の優先順位クラスを準備した後に、Pod 仕様に優先順位クラス名を指定する Pod を作成できます。優先順位の受付コントローラーは、優先順位クラス名フィールドを使用して優先順位の整数値を設定します。名前付きの優先順位クラスが見つからない場合、Pod は拒否されます。

2.10.2. Pod のプリエンプションについて

開発者が Pod を作成する場合、Pod はキューに入れられます。開発者が Pod の優先順位またはプリエンプションを設定している場合、スケジューラーはキューから Pod を選択し、Pod をノードにスケジュールしようとします。スケジューラーが Pod について指定されたすべての要件を満たす適切なノードに領域を見つけられない場合、プリエンプションロジックが保留中の Pod についてトリガーされます。

スケジューラーがノードで 1 つ以上の Pod のプリエンプションを実行する場合、優先順位の高い Pod 仕様の nominatedNodeName フィールドは、nodename フィールドと共にノードの名前に設定されます。スケジューラーは nominatedNodeName フィールドを使用して Pod の予約されたリソースを追跡し、またクラスターのプリエンプションに関する情報をユーザーに提供します。

スケジューラーが優先順位の低い Pod のプリエンプションを実行した後に、スケジューラーは Pod の正常な終了期間を許可します。スケジューラーが優先順位の低い Pod の終了を待機する間に別のノードが利用可能になると、スケジューラーはそのノードに優先順位の高い Pod をスケジュールできます。その結果、Pod 仕様の nominatedNodeName フィールドおよび nodeName フィールドが異なる可能性があります。

さらに、スケジューラーがノード上で Pod のプリエンプションを実行し、終了を待機している場合で、保留中の Pod よりも優先順位の高い Pod をスケジュールする必要がある場合、スケジューラーは代わりに優先順位の高い Pod をスケジュールできます。その場合、スケジューラーは保留中の Pod の nominatedNodeName をクリアし、その Pod を他のノードの対象とすることができます。

プリエンプションは、ノードから優先順位の低いすべての Pod を削除する訳ではありません。スケジューラーは、優先順位の低い Pod の一部を削除して保留中の Pod をスケジュールできます。

スケジューラーは、保留中の Pod をノードにスケジュールできる場合にのみ、Pod のプリエンプションを実行するノードを考慮します。

2.10.2.1. プリエンプションを実行しない優先順位クラス

プリエンプションポリシーが Never に設定された Pod は優先順位の低い Pod よりも前のスケジューリングキューに置かれますが、他の Pod のプリエンプションを実行することはできません。スケジュールを待機しているプリエンプションを実行しない Pod は、十分なリソースが解放され、これがスケジュールされるまでスケジュールキュー内に留まります。他の Pod などのプリエンプションを実行しない Pod はスケジューラーのバックオフの対象になります。つまり、スケジューラーがこれらの Pod のスケジュールの試行に成功しない場合、低頻度で再試行されるため、優先順位の低い他の Pod をそれらの Pod よりも前にスケジュールできます。

プリエンプションを実行しない Pod については、他の優先順位の高い Pod が依然としてプリエンプションを実行できます。

2.10.2.2. Pod プリエンプションおよび他のスケジューラーの設定

Pod の優先順位およびプリエンプションを有効にする場合、他のスケジューラー設定を考慮します。

Pod の優先順位および Pod の Disruption Budget (停止状態の予算)
Pod の Disruption Budget (停止状態の予算) は一度に稼働している必要のあるレプリカの最小数またはパーセンテージを指定します。Pod の Disruption Budget (停止状態の予算) を指定する場合、OpenShift Container Platform は、Best Effort レベルで Pod のプリエンプションを実行する際にそれらを適用します。スケジューラーは、Pod の Disruption Budget (停止状態の予算) に違反しない範囲で Pod のプリエンプションを試行します。該当する Pod が見つからない場合には、Pod の Disruption Budget (停止状態の予算) の要件を無視して優先順位の低い Pod のプリエンプションが実行される可能性があります。
Pod の優先順位およびアフィニティー
Pod のアフィニティーは、新規 Pod が同じラベルを持つ他の Pod と同じノードにスケジュールされることを要求します。

保留中の Pod にノード上の 1 つ以上の優先順位の低い Pod との Pod 間のアフィニティーがある場合、スケジューラーはアフィニティーの要件を違反せずに優先順位の低い Pod のプリエンプションを実行することはできません。この場合、スケジューラーは保留中の Pod をスケジュールするための別のノードを探します。ただし、スケジューラーが適切なノードを見つけることは保証できず、保留中の Pod がスケジュールされない可能性があります。

この状態を防ぐには、優先順位が等しい Pod との Pod のアフィニティーの設定を慎重に行ってください。

2.10.2.3. プリエンプションが実行された Pod の正常な終了

Pod のプリエンプションの実行中、スケジューラーは Pod の正常な終了期間が期限切れになるのを待機します。その後、Pod は機能を完了し、終了します。Pod がこの期間後も終了しない場合、スケジューラーは Pod を強制終了します。 この正常な終了期間により、スケジューラーによる Pod のプリエンプションの実行時と保留中の Pod のノードへのスケジュール時に時間差が出ます。

この時間差を最小限にするには、優先順位の低い Pod の正常な終了期間を短く設定します。

2.10.3. 優先順位およびプリエンプションの設定

Pod 仕様で priorityClassName を使用して優先順位クラスオブジェクトを作成し、Pod を優先順位に関連付けることで、Pod の優先度およびプリエンプションを適用できます。

注記

優先クラスを既存のスケジュール済み Pod に直接追加することはできません。

手順

優先順位およびプリエンプションを使用するようにクラスターを設定するには、以下を実行します。

  1. 1 つ以上の優先順位クラスを作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: scheduling.k8s.io/v1
      kind: PriorityClass
      metadata:
        name: high-priority 1
      value: 1000000 2
      preemptionPolicy: PreemptLowerPriority 3
      globalDefault: false 4
      description: "This priority class should be used for XYZ service pods only." 5
      1
      優先順位クラスオブジェクトの名前です。
      2
      オブジェクトの優先順位の値です。
      3
      オプション: この優先クラスがプリエンプティングであるか非プリエンプティングであるかを指定します。プリエンプションポリシーは、デフォルトで PreemptLowerPriority に設定されます。これにより、その優先順位クラスの Pod はそれよりも優先順位の低い Pod のプリエンプションを実行できます。プリエンプションポリシーが Never に設定される場合、その優先順位クラスの Pod はプリエンプションを実行しません。
      4
      オプション: 優先クラス名が指定されていない Pod にこの優先クラスを使用するかどうかを指定します。このフィールドはデフォルトで false です。globalDefaulttrue に設定される 1 つの優先順位クラスのみがクラスター内に存在できます。globalDefault:true が設定された優先順位クラスがない場合、優先順位クラス名が設定されていない Pod の優先順位はゼロになります。globalDefault:true が設定された優先順位クラスを追加すると、優先順位クラスが追加された後に作成された Pod のみがその影響を受け、これによって既存 Pod の優先順位は変更されません。
      5
      オプション: 開発者がこの優先クラスで使用する必要がある Pod を説明します。任意の文字列を入力します。
    2. 優先クラスを作成します。

      $ oc create -f <file-name>.yaml
  2. 優先クラスの名前を含む Pod 仕様を作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: nginx
        labels:
          env: test
      spec:
        containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
        priorityClassName: high-priority 1
      1
      この Pod で使用する優先順位クラスを指定します。
    2. Pod を作成します。

      $ oc create -f <file-name>.yaml

    優先順位の名前は Pod 設定または Pod テンプレートに直接追加できます。

2.11. ノードセレクターの使用による特定ノードへの Pod の配置

ノードセレクター は、キーと値のペアのマップを指定します。ルールは、ノード上のカスタムラベルと Pod で指定されたセレクターを使用して定義されます。

Pod がノードで実行する要件を満たすには、Pod はノードのラベルとして示されるキーと値のペアを持っている必要があります。

同じ Pod 設定でノードのアフィニティーとノードセレクターを使用している場合、以下の重要な考慮事項を参照してください。

2.11.1. ノードセレクターの使用による Pod 配置の制御

Pod でノードセレクターを使用し、ノードでラベルを使用して、Pod がスケジュールされる場所を制御できます。ノードセレクターにより、OpenShift Container Platform は一致するラベルが含まれるノード上に Pod をスケジュールします。

ラベルをノード、コンピュートマシンセット、またはマシン設定に追加します。コンピュートマシンセットにラベルを追加すると、ノードまたはマシンが停止した場合に、新規ノードにそのラベルが追加されます。ノードまたはマシン設定に追加されるラベルは、ノードまたはマシンが停止すると維持されません。

ノードセレクターを既存 Pod に追加するには、ノードセレクターを ReplicaSet オブジェクト、DaemonSet オブジェクト、StatefulSet オブジェクト、Deployment オブジェクト、または DeploymentConfig オブジェクトなどの Pod の制御オブジェクトに追加します。制御オブジェクト下の既存 Pod は、一致するラベルを持つノードで再作成されます。新規 Pod を作成する場合、ノードセレクターを Pod 仕様に直接追加できます。Pod に制御オブジェクトがない場合は、Pod を削除し、Pod 仕様を編集して、Pod を再作成する必要があります。

注記

ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。

前提条件

ノードセレクターを既存 Pod に追加するには、Pod の制御オブジェクトを判別します。たとえば、router-default-66d5cf9464-m2g75 Pod は router-default-66d5cf9464 レプリカセットによって制御されます。

$ oc describe pod router-default-66d5cf9464-7pwkc

出力例

kind: Pod
apiVersion: v1
metadata:
# ...
Name:               router-default-66d5cf9464-7pwkc
Namespace:          openshift-ingress
# ...
Controlled By:      ReplicaSet/router-default-66d5cf9464
# ...

Web コンソールでは、Pod YAML の ownerReferences に制御オブジェクトをリスト表示します。

apiVersion: v1
kind: Pod
metadata:
  name: router-default-66d5cf9464-7pwkc
# ...
  ownerReferences:
    - apiVersion: apps/v1
      kind: ReplicaSet
      name: router-default-66d5cf9464
      uid: d81dd094-da26-11e9-a48a-128e7edf0312
      controller: true
      blockOwnerDeletion: true
# ...

手順

  1. コンピュートマシンセットを使用するか、ノードを直接編集してラベルをノードに追加します。

    • MachineSet オブジェクトを使用して、ノードの作成時にコンピュートマシンセットによって管理されるノードにラベルを追加します。

      1. 以下のコマンドを実行してラベルを MachineSet オブジェクトに追加します。

        $ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]'  -n openshift-machine-api

        以下に例を示します。

        $ oc patch MachineSet abc612-msrtw-worker-us-east-1c  --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]'  -n openshift-machine-api
        ヒント

        あるいは、以下の YAML を適用してコンピュートマシンセットにラベルを追加することもできます。

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
        metadata:
          name: xf2bd-infra-us-east-2a
          namespace: openshift-machine-api
        spec:
          template:
            spec:
              metadata:
                labels:
                  region: "east"
                  type: "user-node"
        # ...
      2. oc edit コマンドを使用して、ラベルが MachineSet オブジェクトに追加されていることを確認します。

        以下に例を示します。

        $ oc edit MachineSet abc612-msrtw-worker-us-east-1c -n openshift-machine-api

        MachineSet オブジェクトの例

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
        
        # ...
        
        spec:
        # ...
          template:
            metadata:
        # ...
            spec:
              metadata:
                labels:
                  region: east
                  type: user-node
        # ...

    • ラベルをノードに直接追加します。

      1. ノードの Node オブジェクトを編集します。

        $ oc label nodes <name> <key>=<value>

        たとえば、ノードにラベルを付けるには、以下を実行します。

        $ oc label nodes ip-10-0-142-25.ec2.internal type=user-node region=east
        ヒント

        あるいは、以下の YAML を適用してノードにラベルを追加することもできます。

        kind: Node
        apiVersion: v1
        metadata:
          name: hello-node-6fbccf8d9
          labels:
            type: "user-node"
            region: "east"
        # ...
      2. ラベルがノードに追加されていることを確認します。

        $ oc get nodes -l type=user-node,region=east

        出力例

        NAME                          STATUS   ROLES    AGE   VERSION
        ip-10-0-142-25.ec2.internal   Ready    worker   17m   v1.27.3

  2. 一致するノードセレクターを Pod に追加します。

    • ノードセレクターを既存 Pod および新規 Pod に追加するには、ノードセレクターを Pod の制御オブジェクトに追加します。

      ラベルを含む ReplicaSet オブジェクトのサンプル

      kind: ReplicaSet
      apiVersion: apps/v1
      metadata:
        name: hello-node-6fbccf8d9
      # ...
      spec:
      # ...
        template:
          metadata:
            creationTimestamp: null
            labels:
              ingresscontroller.operator.openshift.io/deployment-ingresscontroller: default
              pod-template-hash: 66d5cf9464
          spec:
            nodeSelector:
              kubernetes.io/os: linux
              node-role.kubernetes.io/worker: ''
              type: user-node 1
      # ...

      1
      ノードセレクターを追加します。
    • ノードセレクターを特定の新規 Pod に追加するには、セレクターを Pod オブジェクトに直接追加します。

      ノードセレクターを持つ Pod オブジェクトの例

      apiVersion: v1
      kind: Pod
      metadata:
        name: hello-node-6fbccf8d9
      # ...
      spec:
        nodeSelector:
          region: east
          type: user-node
      # ...

      注記

      ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。

2.12. Run Once Duration Override Operator

2.12.1. Run once Duration Override Operator の概要

Run Once Duration Override Operator を使用して、1 回実行 Pod をアクティブにできる最大時間制限を指定できます。

2.12.1.1. Run Once Duration Override Operator について

OpenShift Container Platform は 1 回実行 (run-once) Pod を使用して Pod のデプロイやビルドの実行などのタスクを実行します。1 回実行 (run-once) Pod は、RestartPolicyNever または OnFailure の Pod です。

クラスター管理者は Run Once Duration Override Operator を使用して、1 回実行 Pod がアクティブになる時間を強制的に制限できます。期限が切れると、クラスターはそれらの Pod をアクティブに終了しようとします。このような制限を設ける主な理由は、ビルドなどのタスクが長い時間にわたって実行されることを防ぐことにあります。

Run Once Duration Override Operator から run-once duration override を 1 回実行 (run-once) Pod に適用するには、該当する各 namespace でそれを有効にする必要があります。

1 回実行 Pod と Run Once Duration Override Operator の両方に activeDeadlineSeconds 値が設定されている場合、2 つの値のうち小さい方が使用されます。

2.12.2. Run Once Duration Override Operator のリリースノート

クラスター管理者は Run Once Duration Override Operator を使用して、1 回実行 Pod がアクティブになる時間を強制的に制限できます。制限時間が経過すると、クラスターは 1 回実行 Pod を終了しようとします。このような制限を設ける主な理由は、ビルドなどのタスクが長い時間にわたって実行されることを防ぐことにあります。

Run Once Duration Override Operator から run-once duration override を 1 回実行 (run-once) Pod に適用するには、該当する各 namespace でそれを有効にする必要があります。

これらのリリースノートでは、OpenShift Container Platform の Run Once Duration Override Operator の開発を追跡します。

Run Once Duration Override Operator の概要は、Run Once Duration Override Operator について を参照してください。

2.12.2.1. Run Once Duration Override Operator 1.2.0

発行日: 2024 年 11 月 20 日

Run Once Duration Override Operator 1.1.0 については、以下のアドバイザリーが利用できます。

2.12.2.1.1. バグ修正
  • Run Once Duration Override Operator のこのリリースでは、いくつかの Common Vulnerabilities and Exposures (CVE) に対処しています。
2.12.2.2. Run Once Duration Override Operator 1.0.1

発行日: 2023 年 10 月 31 日

次のアドバイザリーは、Run Once Duration Override Operator 1.0.1 に対して利用可能です。

2.12.2.2.1. バグ修正
  • Run Once Duration Override Operator のこのリリースでは、いくつかの Common Vulnerabilities and Exposures (CVE) に対処しています。
2.12.2.3. Run Once Duration Override Operator 1.0.0

発行日: 2024 年 5 月 16 日

次のアドバイザリーは、Run Once Duration Override Operator 1.0.0 に対して利用可能です。

2.12.2.3.1. 新機能および機能拡張

2.12.3. 1 回実行 Pod のアクティブな期限をオーバーライドする

Run Once Duration Override Operator を使用して、1 回実行 Pod をアクティブにできる最大時間制限を指定できます。namespace で Run Once Duration Override Operator を有効にすると、その namespace で今後作成または更新されるすべての 1 回実行 (run-once) Pod の activeDeadlineSeconds フィールドが、Run Once Duration Override Operator で指定された値に設定されます。

注記

1 回実行 Pod と Run Once Duration Override Operator の両方に activeDeadlineSeconds 値が設定されている場合、2 つの値のうち小さい方が使用されます。

2.12.3.1. Run Once Duration Override Operator のインストール

Web コンソールを使用して、Run Once Period Override Operator をインストールできます。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • OpenShift Container Platform Web コンソールにアクセスできる。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. Run Once Duration Override Operator に必要な namespace を作成します。

    1. AdministrationNamespaces に移動し、Create Namespace をクリックします。
    2. Name フィールドに openshift-run-once-duration-override-operator と入力し、Create をクリックします。
  3. Run Once Duration Override Operator をインストールします。

    1. OperatorsOperatorHub に移動します。
    2. フィルターボックスに Run Once Duration Override Operator と入力します。
    3. Run Once Duration Override Operator を選択し、Install をクリックします。
    4. Install Operator ページで以下を行います。

      1. Update channelstable に設定されており、これにより、Run Once Duration Override Operator の最新の安定リリースがインストールされます。
      2. A specific namespace on the cluster を選択します。
      3. openshift-run-once-duration-override-operator の下のドロップダウンメニューから openshift-run-once-duration-override-operator を選択します。
      4. Update approval strategy を選択します。

        • Automatic ストラテジーにより、Operator Lifecycle Manager (OLM) は新規バージョンが利用可能になると Operator を自動的に更新できます。
        • Manual ストラテジーには、Operator の更新を承認するための適切な認証情報を持つユーザーが必要です。
      5. Install をクリックします。
  4. RunOnceDurationOverride インスタンスを作成します。

    1. OperatorsInstalled Operators ページから、Run Once Duration Override Operator をクリックします。
    2. Run Once Duration Override タブを選択し、Create RunOnceDurationOverride をクリックします。
    3. 必要に応じて設定を編集します。

      runOnceDurationOverride セクションで、必要に応じて spec.activeDeadlineSeconds 値を更新できます。事前定義された値は 3600 秒、つまり 1 時間です。

    4. Create をクリックします。

検証

  1. OpenShift CLI にログインします。
  2. すべての Pod が作成され、適切に実行されていることを確認します。

    $ oc get pods -n openshift-run-once-duration-override-operator

    出力例

    NAME                                                   READY   STATUS    RESTARTS   AGE
    run-once-duration-override-operator-7b88c676f6-lcxgc   1/1     Running   0          7m46s
    runoncedurationoverride-62blp                          1/1     Running   0          41s
    runoncedurationoverride-h8h8b                          1/1     Running   0          41s
    runoncedurationoverride-tdsqk                          1/1     Running   0          41s

2.12.3.2. namespace での run-once duration override の有効化

Run Once Duration Override Operator から run-once duration override を 1 回実行 (run-once) Pod に適用するには、該当する各 namespace でそれを有効にする必要があります。

前提条件

  • Run Once Duration Override Operator がインストールされます。

手順

  1. OpenShift CLI にログインします。
  2. ラベルを追加して、run-once duration override を有効にします。

    $ oc label namespace <namespace> \ 1
        runoncedurationoverrides.admission.runoncedurationoverride.openshift.io/enabled=true
    1
    run-once duration override を有効にする namespace を指定します。

この namespace で run-once duration override を有効にすると、今後この namespace で作成される 1 回実行 Pod の activeDeadlineSeconds フィールドが、Run Once Duration Override Operator からのオーバーライド値に設定されます。この namespace の既存 Pod には、次の更新時に activeDeadlineSeconds 値も設定されます。

検証

  1. run-once duration override を有効にした namespace に、1 回実行 Pod を作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: example
      namespace: <namespace>                 1
    spec:
      restartPolicy: Never                   2
      containers:
        - name: busybox
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
            runAsNonRoot:
              true
            seccompProfile:
              type: "RuntimeDefault"
          image: busybox:1.25
          command:
            - /bin/sh
            - -ec
            - |
              while sleep 5; do date; done
    1
    <namespace> を namespace の名前に置き換えます。
    2
    1 回実行 (run-once) Pod には、restartPolicyNever または OnFailure である必要があります。
  2. Pod に activeDeadlineSeconds フィールドが設定されていることを確認します。

    $ oc get pods -n <namespace> -o yaml | grep activeDeadlineSeconds

    出力例

        activeDeadlineSeconds: 3600

2.12.3.3. run-once active deadline override 値の更新

Run Once Duration Override Operator が 1 回実行 Pod (run-once Pod) に適用されるオーバーライド値をカスタマイズできます。事前定義された値は 3600 秒、つまり 1 時間です。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • Run Once Duration Override Operator をインストールしました。

手順

  1. OpenShift CLI にログインします。
  2. RunOnceDurationOverride リソースを編集します。

    $ oc edit runoncedurationoverride cluster
  3. activeDeadlineSeconds フィールドを更新します。

    apiVersion: operator.openshift.io/v1
    kind: RunOnceDurationOverride
    metadata:
    # ...
    spec:
      runOnceDurationOverride:
        spec:
          activeDeadlineSeconds: 1800 1
    # ...
    1
    activeDeadlineSeconds フィールドを必要な値に設定します (秒単位)。
  4. 変更を適用するためにファイルを保存します。

run-once duration override が有効になっている namespace で今後作成される 1 回実行 Pod では、activeDeadlineSeconds フィールドがこの新しい値に設定されます。これらの namespace 内の既存の 1 回実行 Pod は、更新時にこの新しい値を受け取ります。

2.12.4. Run Once Duration Override Operator のアンインストール

Operator をアンインストールし、その関連リソースを削除することで、OpenShift Container Platform から Run Once Duration Override Operator を削除できます。

2.12.4.1. Run Once Duration Override Operator のアンインストール

Web コンソールを使用して、Run Once Period Override Operator をアンインストールできます。Run Once Duration Override Operator をアンインストールしても、1 回実行 (run-once) Pod の activeDeadlineSeconds フィールドの設定が解除されませんが、上書き値は今後の 1 回実行 (run-once) Pod に適用されなくなります。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • OpenShift Container Platform Web コンソールにアクセスできる。
  • Run Once Duration Override Operator をインストールしました。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. OperatorsInstalled Operators に移動します。
  3. Project ドロップダウンリストから openshift-run-once-duration-override-operator を選択します。
  4. RunOnceDurationOverride インスタンスを削除します。

    1. Run Once Duration Override Operator をクリックし、Run Once Duration Override タブを選択します。
    2. クラスター エントリーの横にある Options メニュー kebab をクリックし、Delete RunOnceDurationOverride を選択します。
    3. 確認ダイアログで Delete をクリックします。
  5. Run Once Duration Override Operator Operator をアンインストールします。

    1. OperatorsInstalled Operators に移動します。
    2. Run Once Duration Override Operator エントリーの横にある Options メニュー kebab をクリックし、Uninstall Operator をクリックします。
    3. 確認ダイアログで、Uninstall をクリックします。
2.12.4.2. Run Once Duration Override Operator リソースのアンインストール

必要に応じて、Run Once Duration Override Operator をアンインストールした後、その関連リソースをクラスターから削除できます。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • OpenShift Container Platform Web コンソールにアクセスできる。
  • Run Once Duration Override Operator をアンインストールしている。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. Run Once Duration Override Operator のインストール時に作成された CRD を削除します。

    1. AdministrationCustomResourceDefinitions に移動します。
    2. Name フィールドに RunOnceDurationOverride を入力し、CRD をフィルタリングします。
    3. RunOnceDurationOverride CRD の横にある Options メニュー kebab をクリックし、Delete CustomResourceDefinition を選択します。
    4. 確認ダイアログで Delete をクリックします。
  3. openshift-run-once-duration-override-operator namespace を削除します。

    1. AdministrationNamespaces に移動します。
    2. openshift-run-once-duration-override-operator をフィルターボックスに入力します。
    3. openshift-run-once-duration-override-operator エントリーの横にある Options メニュー kebab をクリックし、Delete Namespace を選択します。
    4. 確認ダイアログで、openshift-run-once-duration-override-operator を入力し、Delete をクリックします。
  4. 有効にされた namespace から run-once duration override ラベルを削除します。

    1. AdministrationNamespaces に移動します。
    2. namespace を選択します。
    3. Labels フィールドの横にある Edit をクリックします。
    4. runoncedurationoverrides.admission.runoncedurationoverride.openshift.io/enabled=true ラベルを削除し、Save をクリックします。

第3章 Custom Metrics Autoscaler Operator を使用した Pod の自動スケーリング

3.1. リリースノート

3.1.1. Custom Metrics Autoscaler Operator リリースノート

Red Hat OpenShift の Custom Metrics Autoscaler Operator のリリースノートでは、新機能および拡張機能、非推奨となった機能、および既知の問題を説明しています。

Custom Metrics Autoscaler Operator は、Kubernetes ベースの Event Driven Autoscaler (KEDA) を使用し、OpenShift Container Platform の Horizontal Pod Autoscaler (HPA) の上に構築されます。

注記

Red Hat OpenShift の Custom Metrics Autoscaler Operator のロギングサブシステムは、インストール可能なコンポーネントとして提供され、コアの OpenShift Container Platform とは異なるリリースサイクルを備えています。Red Hat OpenShift Container Platform ライフサイクルポリシー はリリースの互換性を概説しています。

3.1.1.1. サポート対象バージョン

以下の表は、各 OpenShift Container Platform バージョンの Custom Metrics Autoscaler Operator バージョンを定義しています。

バージョンOpenShift Container Platform バージョン一般公開

2.14.1

4.16

一般公開

2.14.1

4.15

一般公開

2.14.1

4.14

一般公開

2.14.1

4.13

一般公開

2.14.1

4.12

一般公開

3.1.1.2. Custom Metrics Autoscaler Operator 2.14.1-467 リリースノート

Custom Metrics Autoscaler Operator 2.14.1-467 のこのリリースでは、OpenShift Container Platform クラスターで Operator を実行するための CVE とバグ修正が提供されています。RHSA-2024:7348 に関する次のアドバイザリーが利用可能です。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの Kubernetes ベースの Event Driven Autoscaler (KEDA) を削除します。

3.1.1.2.1. バグ修正
  • 以前は、Custom Metrics Autoscaler Operator Pod のルートファイルシステムが書き込み可能でした。これは不要であり、セキュリティー上の問題を引き起こす可能性がありました。この更新により、Pod のルートファイルシステムが読み取り専用になり、潜在的なセキュリティー問題が解決されました。(OCPBUGS-37989)

3.1.2. Custom Metrics Autoscaler Operator の過去リリースに関するリリースノート

次のリリースノートは、以前の Custom Metrics Autoscaler Operator バージョンを対象としています。

現在のバージョンについては、Custom Metrics Autoscaler Operator リリースノート を参照してください。

3.1.2.1. Custom Metrics Autoscaler Operator 2.14.1-454 リリースノート

この Custom Metrics Autoscaler Operator 2.14.1-454 リリースでは、OpenShift Container Platform クラスターで Operator を実行するための CVE、新機能、およびバグ修正を使用できます。RHBA-2024:5865 に関する次のアドバイザリーが利用可能です。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの Kubernetes ベースの Event Driven Autoscaler (KEDA) を削除します。

3.1.2.1.1. 新機能および機能拡張
3.1.2.1.1.1. Custom Metrics Autoscaler Operator による Cron トリガーのサポート

Custom Metrics Autoscaler Operator が、Cron トリガーを使用して、時間単位のスケジュールに基づいて Pod をスケーリングできるようになりました。指定した時間枠が開始すると、Custom Metrics Autoscaler Operator が Pod を必要な数にスケーリングします。時間枠が終了すると、Operator は以前のレベルまでスケールダウンします。

詳細は、Cron トリガーについて を参照してください。

3.1.2.1.2. バグ修正
  • 以前は、KedaController カスタムリソースの監査設定パラメーターに変更を加えても、keda-metrics-server-audit-policy config map が更新されませんでした。その結果、Custom Metrics Autoscaler の初期デプロイ後に監査設定パラメーターを変更することができませんでした。この修正により、監査設定への変更が config map に適切に反映されるようになり、インストール後いつでも監査設定を変更できるようになりました。(OCPBUGS-32521)
3.1.2.2. Custom Metrics Autoscaler Operator 2.13.1 リリースノート

Custom Metrics Autoscaler Operator 2.13.1-421 のこのリリースでは、OpenShift Container Platform クラスターで Operator を実行するための新機能およびバグ修正が提供されています。RHBA-2024:4837 に関する次のアドバイザリーが利用可能です。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの Kubernetes ベースの Event Driven Autoscaler (KEDA) を削除します。

3.1.2.2.1. 新機能および機能拡張
3.1.2.2.1.1. Custom Metrics Autoscaler Operator によるカスタム証明書のサポート

Custom Metrics Autoscaler Operator は、カスタムサービス CA 証明書を使用して、外部 Kafka クラスターや外部 Prometheus サービスなどの TLS 対応メトリクスソースに安全に接続できるようになりました。デフォルトでは、Operator は自動生成されたサービス証明書を使用して、クラスター上のサービスにのみ接続します。KedaController オブジェクトには、config map を使用して外部サービスに接続するためのカスタムサーバー CA 証明書を読み込むことができる新しいフィールドがあります。

詳細は、Custom Metrics Autoscaler のカスタム CA 証明書 を参照してください。

3.1.2.2.2. バグ修正
  • 以前は、custom-metrics-autoscaler および custom-metrics-autoscaler-adapter イメージにタイムゾーン情報がありませんでした。その結果、コントローラーがタイムゾーン情報を見つけられなかったため、cron トリガーを使用した scaled object は機能しなくなりました。この修正により、Image Build が更新され、タイムゾーン情報が含まれるようになりました。その結果、cron トリガーを含む scaled object が正常に機能するようになりました。cron トリガーを含むスケールされたオブジェクトは現在、カスタムメトリクスオートスケーラーではサポートされていません。(OCPBUGS-34018)
3.1.2.3. Custom Metrics Autoscaler Operator 2.12.1-394 リリースノート

Custom Metrics Autoscaler Operator 2.12.1-394 のこのリリースでは、OpenShift Container Platform クラスターで Operator を実行するためのバグ修正が提供されています。RHSA-2024:2901 には、次のアドバイザリーを利用できます。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの Kubernetes ベースの Event Driven Autoscaler (KEDA) を削除します。

3.1.2.3.1. バグ修正
  • 以前は、protojson.Unmarshal 関数は、特定の形式の無効な JSON をアンマーシャリングするときに無限ループに入りました。この状態は、google.protobuf.Any 値を含むメッセージにアンマーシャリングするとき、または UnmarshalOptions.DiscardUnknown オプションが設定されているときに発生する可能性があります。このリリースではこの問題が修正されています。(OCPBUGS-30305)
  • 以前は、Request.ParseMultipartForm メソッドを使用して明示的に、または Request.FormValueRequest.PostFormValueRequest.FormFile メソッドを使用して暗黙的にマルチパートフォームを解析する場合、解析されたフォームの合計サイズの制限は、消費されるメモリーには適用されませんでした。これによりメモリー不足が発生する可能性があります。この修正により、解析プロセスでは、単一のフォーム行を読み取る際に、フォーム行の最大サイズが正しく制限されるようになりました。(OCPBUGS-30360)
  • 以前は、一致するサブドメイン上または最初のドメインと完全に一致しないドメインへの HTTP リダイレクトに従う場合、HTTP クライアントは AuthorizationCookie などの機密ヘッダーを転送しませんでした。たとえば、example.com から www.example.com へのリダイレクトでは Authorization ヘッダーが転送されますが、www.example.org へのリダイレクトではヘッダーは転送されません。このリリースではこの問題が修正されています。(OCPBUGS-30365)
  • 以前は、不明な公開鍵アルゴリズムを持つ証明書を含む証明書チェーンを検証すると、証明書検証プロセスがパニックに陥っていました。この状況は、Config.ClientAuth パラメーターを VerifyClientCertIfGiven または RequireAndVerifyClientCert 値に設定するすべての暗号化および Transport Layer Security (TLS) クライアントとサーバーに影響しました。デフォルトの動作では、TLS サーバーはクライアント証明書を検証しません。このリリースではこの問題が修正されています。(OCPBUGS-30370)
  • 以前は、MarshalJSON メソッドから返されるエラーにユーザーが制御するデータが含まれている場合、攻撃者はそのデータを使用して HTML テンプレートパッケージのコンテキスト自動エスケープ動作を破ることができた可能性があります。この条件により、後続のアクションによってテンプレートに予期しないコンテンツが挿入される可能性があります。このリリースではこの問題が修正されています。(OCPBUGS-30397)
  • 以前は、Go パッケージ net/http および golang.org/x/net/http2 では、HTTP/2 リクエストの CONTINUATION フレームの数に制限がありませんでした。この状態により、CPU が過剰に消費される可能性があります。このリリースではこの問題が修正されています。(OCPBUGS-30894)
3.1.2.4. Custom Metrics Autoscaler Operator 2.12.1-384 リリースノート

Custom Metrics Autoscaler Operator 2.12.1-384 のこのリリースでは、OpenShift Container Platform クラスターで Operator を実行するためのバグ修正が提供されています。RHBA-2024:2043 に関する次のアドバイザリーが利用可能です。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの KEDA を削除します。

3.1.2.4.1. バグ修正
  • 以前は、custom-metrics-autoscaler および custom-metrics-autoscaler-adapter イメージにタイムゾーン情報がありませんでした。その結果、コントローラーがタイムゾーン情報を見つけられなかったため、cron トリガーを使用した scaled object は機能しなくなりました。この修正により、Image Build が更新され、タイムゾーン情報が含まれるようになりました。その結果、cron トリガーを含む scaled object が正常に機能するようになりました。(OCPBUGS-32395)
3.1.2.5. Custom Metrics Autoscaler Operator 2.12.1-376 リリースノート

Custom Metrics Autoscaler Operator 2.12.1-376 のこのリリースでは、OpenShift Container Platform クラスターで Operator を実行するためのセキュリティー更新とバグ修正が提供されます。RHSA-2024:1812 には、次のアドバイザリーを利用できます。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの KEDA を削除します。

3.1.2.5.1. バグ修正
  • 以前は、存在しない namespace などの無効な値が scaled object メタデータに指定されている場合、基盤となるスケーラークライアントはクライアント記述子を解放または終了できず、低速のメモリーリークが発生していました。この修正により、エラーが発生した場合に基礎となるクライアント記述子が適切に終了され、メモリーのリークが防止されます。(OCPBUGS-30145)
  • 以前は、keda-metrics-apiserver Pod の ServiceMonitor カスタムリソース (CR) が機能していませんでした。これは、CR が http という誤ったメトリクスポート名を参照していたためです。この修正により、ServiceMonitor CR が修正され、metrics の適切なポート名が参照されるようになります。その結果、Service Monitor が正常に機能します。(OCPBUGS-25806)
3.1.2.6. Custom Metrics Autoscaler Operator 2.11.2-322 リリースノート

Custom Metrics Autoscaler Operator 2.11.2-322 のこのリリースでは、OpenShift Container Platform クラスターで Operator を実行するためのセキュリティー更新とバグ修正が提供されます。RHSA-2023:6144 には、次のアドバイザリーを利用できます。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの KEDA を削除します。

3.1.2.6.1. バグ修正
  • Custom Metrics Autoscaler Operator バージョン 3.11.2-311 は、Operator デプロイメントで必要なボリュームマウントなしにリリースされたため、Custom Metrics Autoscaler Operator Pod は 15 分ごとに再起動しました。この修正により、必要なボリュームマウントが Operator デプロイメントに追加されました。その結果、Operator は 15 分ごとに再起動しなくなりました。(OCPBUGS-22361)
3.1.2.7. Custom Metrics Autoscaler Operator 2.11.2-311 リリースノート

この Custom Metrics Autoscaler Operator 2.11.2-311 リリースでは、OpenShift Container Platform クラスターで Operator を実行するための新機能とバグ修正を使用できます。Custom Metrics Autoscaler Operator 2.11.2-311 のコンポーネントは RHBA-2023:5981 でリリースされました。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの KEDA を削除します。

3.1.2.7.1. 新機能および機能拡張
3.1.2.7.1.1. Red Hat OpenShift Service on AWS (ROSA) と OpenShift Dedicated がサポートされるようになりました

Custom Metrics Autoscaler Operator 2.11.2-311 は、OpenShift ROSA および OpenShift Dedicated マネージドクラスターにインストールできます。Custom Metrics Autoscaler Operator の以前のバージョンは、openshift-keda namespace にのみインストールできました。これにより、Operator を OpenShift ROSA クラスターおよび OpenShift Dedicated クラスターにインストールできなくなりました。このバージョンの Custom Metrics Autoscaler では、openshift-operatorskeda などの他の namespace へのインストールが可能になり、ROSA クラスターや Dedicated クラスターへのインストールが可能になります。

3.1.2.7.2. バグ修正
  • 以前は、Custom Metrics Autoscaler Operator がインストールおよび設定されているが使用されていない場合、OpenShift CLI では、oc コマンドを入力すると、couldn’t get resource list for external.metrics.k8s.io/v1beta1: Got empty response for: external.metrics.k8s.io/v1beta1 エラーが報告されていました。このメッセージは無害ではありますが、混乱を引き起こす可能性がありました。この修正により、Got empty response for: external.metrics…​ エラーが不適切に表示されなくなりました。(OCPBUGS-15779)
  • 以前は、設定変更後など、Keda Controller が変更されるたびに、Custom Metrics Autoscaler Operator によって管理されるオブジェクトに対するアノテーションやラベルの変更は、Custom Metrics Autoscaler Operator によって元に戻されました。これにより、オブジェクト内のラベルが継続的に変更されてしまいました。Custom Metrics Autoscaler は、独自のアノテーションを使用してラベルとアノテーションを管理するようになり、アノテーションやラベルが不適切に元に戻されることがなくなりました。(OCPBUGS-15590)
3.1.2.8. Custom Metrics Autoscaler Operator 2.10.1-267 リリースノート

この Custom Metrics Autoscaler Operator 2.10.1-267 リリースでは、OpenShift Container Platform クラスターで Operator を実行するための新機能とバグ修正を使用できます。Custom Metrics Autoscaler Operator 2.10.1-267 のコンポーネントは RHBA-2023:4089 でリリースされました。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの KEDA を削除します。

3.1.2.8.1. バグ修正
  • 以前は、custom-metrics-autoscaler イメージcustom-metrics-autoscaler-adapter イメージにはタイムゾーン情報が含まれていませんでした。このため、コントローラーがタイムゾーン情報を見つけることができず、cron トリガーを使用してスケーリングされたオブジェクトが機能しませんでした。今回の修正により、イメージビルドにタイムゾーン情報が含まれるようになりました。その結果、cron トリガーを含むスケールされたオブジェクトが適切に機能するようになりました。(OCPBUGS-15264)
  • 以前のバージョンでは、Custom Metrics Autoscaler Operator は、他の namespace 内のオブジェクトやクラスタースコープのオブジェクトを含む、すべてのマネージドオブジェクトの所有権を取得しようとしていました。このため、Custom Metrics Autoscaler Operator は API サーバーに必要な認証情報を読み取るためのロールバインディングを作成できませんでした。これにより、kube-system namespace でエラーが発生しました。今回の修正により、Custom Metrics Autoscaler Operator は、別の namespace 内のオブジェクトまたはクラスタースコープのオブジェクトへの ownerReference フィールドの追加をスキップします。その結果、ロールバインディングがエラーなしで作成されるようになりました。(OCPBUGS-15038)
  • 以前のバージョンでは、Custom Metrics Autoscaler Operator は、ownshift-keda namespace に ownerReferences フィールドを追加しました。これによって機能上の問題が発生することはありませんでしたが、このフィールドの存在によりクラスター管理者が混乱する可能性がありました。今回の修正により、Custom Metrics Autoscaler Operator は ownerReference フィールドを openshift-keda namespace に追加しなくなりました。その結果、openshift-keda namespace には余分な ownerReference フィールドが含まれなくなりました。(OCPBUGS-15293)
  • 以前のバージョンでは、Pod ID 以外の認証方法で設定された Prometheus トリガーを使用し、podIdentity パラメーターが none に設定されている場合、トリガーはスケーリングに失敗しました。今回の修正により、OpenShift の Custom Metrics Autoscaler は、Pod ID プロバイダータイプ none を適切に処理できるようになりました。その結果、Pod ID 以外の認証方法で設定され、podIdentity パラメーターが none に設定された Prometheus トリガーが適切にスケーリングされるようになりました。(OCPBUGS-15274)
3.1.2.9. Custom Metrics Autoscaler Operator 2.10.1 リリースノート

この Custom Metrics Autoscaler Operator 2.10.1 リリースでは、OpenShift Container Platform クラスターで Operator を実行するための新機能とバグ修正を使用できます。Custom Metrics Autoscaler Operator 2.10.1 のコンポーネントは RHEA-2023:3199 でリリースされました。

重要

このバージョンの Custom Metrics Autoscaler Operator をインストールする前に、以前にインストールされたテクノロジープレビューバージョンまたはコミュニティーがサポートするバージョンの KEDA を削除します。

3.1.2.9.1. 新機能および機能拡張
3.1.2.9.1.1. Custom Metrics Autoscaler Operator の一般提供

Custom Metrics Autoscaler Operator バージョン 2.10.1 以降で、Custom Metrics Autoscaler Operator の一般提供が開始されました。

重要

スケーリングされたジョブを使用したスケーリングはテクノロジープレビュー機能です。テクノロジープレビュー機能は、Red Hat 製品のサービスレベルアグリーメント (SLA) の対象外であり、機能的に完全ではないことがあります。Red Hat は、実稼働環境でこれらを使用することを推奨していません。テクノロジープレビューの機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。

Red Hat のテクノロジープレビュー機能のサポート範囲に関する詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。

3.1.2.9.1.2. パフォーマンスメトリクス

Prometheus Query Language (PromQL) を使用して、Custom Metrics Autoscaler Operator でメトリクスのクエリーを行えるようになりました。

3.1.2.9.1.3. スケーリングされたオブジェクトのカスタムメトリクス自動スケーリングの一時停止

必要に応じてスケーリングされたオブジェクトの自動スケーリングを一時停止し、準備ができたら再開できるようになりました。

3.1.2.9.1.4. スケーリングされたオブジェクトのレプリカフォールバック

スケーリングされたオブジェクトがソースからメトリクスを取得できなかった場合に、フォールバックするレプリカの数を指定できるようになりました。

3.1.2.9.1.5. スケーリングされたオブジェクトのカスタマイズ可能な HPA 命名

スケーリングされたオブジェクトで、水平 Pod オートスケーラーのカスタム名を指定できるようになりました。

3.1.2.9.1.6. アクティブ化およびスケーリングのしきい値

水平 Pod オートスケーラー (HPA) は 0 レプリカへの、または 0 レプリカからのスケーリングができないため、Custom Metrics Autoscaler Operator がそのスケーリングを実行し、その後 HPA がスケーリングを実行します。レプリカの数に基づき HPA が自動スケーリングを引き継ぐタイミングを指定できるようになりました。これにより、スケーリングポリシーの柔軟性が向上します。

3.1.2.10. Custom Metrics Autoscaler Operator 2.8.2-174 リリースノート

この Custom Metrics Autoscaler Operator 2.8.2-174 リリースでは、OpenShift Container Platform クラスターで Operator を実行するための新機能とバグ修正を使用できます。Custom Metrics Autoscaler Operator 2.8.2-174 のコンポーネントは RHEA-2023:1683 でリリースされました。

重要

Custom Metrics Autoscaler Operator バージョン 2.8.2-174 は、テクノロジープレビュー 機能です。

3.1.2.10.1. 新機能および機能拡張
3.1.2.10.1.1. Operator のアップグレードサポート

以前の Custom Metrics Autoscaler Operator バージョンからアップグレードできるようになりました。Operator のアップグレードの詳細は、関連情報の「Operator の更新チャネルの変更」を参照してください。

3.1.2.10.1.2. must-gather サポート

OpenShift Container Platform must-gather ツールを使用して、Custom Metrics Autoscaler Operator およびそのコンポーネントに関するデータを収集できるようになりました。現時点で、Custom Metrics Autoscaler で must-gather ツールを使用するプロセスは、他の Operator とは異なります。詳細は、関連情報の「デバッグデータの収集」を参照してください。

3.1.2.11. Custom Metrics Autoscaler Operator 2.8.2 リリースノート

Custom Metrics Autoscaler Operator 2.8.2 のこのリリースは、OpenShift Container Platform クラスターで Operator を実行するための新機能とバグ修正を提供します。Custom Metrics Autoscaler Operator 2.8.2 のコンポーネントは RHSA-2023:1042 でリリースされました。

重要

Custom Metrics Autoscaler Operator バージョン 2.8.2 は テクノロジープレビュー 機能です。

3.1.2.11.1. 新機能および機能拡張
3.1.2.11.1.1. 監査ロギング

Custom Metrics Autoscaler Operator とその関連コンポーネントの監査ログを収集して表示できるようになりました。監査ログは、システムに影響を与えた一連のアクティビティーを個別のユーザー、管理者その他システムのコンポーネント別に記述したセキュリティー関連の時系列のレコードです。

3.1.2.11.1.2. Apache Kafka メトリクスに基づくアプリケーションのスケーリング

KEDA Apache kafka トリガー/スケーラーを使用して、Apache Kafka トピックに基づいてデプロイメントをスケーリングできるようになりました。

3.1.2.11.1.3. CPU メトリクスに基づくアプリケーションのスケーリング

KEDA CPU トリガー/スケーラーを使用して、CPU メトリクスに基づいてデプロイメントをスケーリングできるようになりました。

3.1.2.11.1.4. メモリーメトリクスに基づくアプリケーションのスケーリング

KEDA メモリートリガー/スケーラーを使用して、メモリーメトリクスに基づいてデプロイメントをスケーリングできるようになりました。

3.2. Custom Metrics Autoscaler Operator の概要

開発者は、Red Hat OpenShift の Custom Metrics Autoscaler Operator を使用して、OpenShift Container Platform が CPU またはメモリーのみに基づくものではないカスタメトリクスに基づきデプロイメント、ステートフルセット、カスタムリソース、またはジョブの Pod 数を自動的に増減する方法を指定できます。

Custom Metrics Autoscaler Operator は、Kubernetes Event Driven Autoscaler (KEDA) に基づくオプションの Operator であり、Pod メトリクス以外の追加のメトリクスソースを使用してワークロードをスケーリングできます。

カスタムメトリクスオートスケーラーは現在、Prometheus、CPU、メモリー、および Apache Kafka メトリクスのみをサポートしています。

Custom Metrics Autoscaler Operator は、特定のアプリケーションからのカスタムの外部メトリクスに基づいて、Pod をスケールアップおよびスケールダウンします。他のアプリケーションは引き続き他のスケーリング方法を使用します。スケーラーとも呼ばれる トリガー を設定します。これは、カスタムメトリックオートスケーラーがスケーリング方法を決定するために使用するイベントとメトリックのソースです。カスタムメトリックオートスケーラーはメトリック API を使用して、外部メトリックを OpenShift Container Platform が使用できる形式に変換します。カスタムメトリクスオートスケーラーは、実際のスケーリングを実行する Horizontal Pod Autoscaler (HPA) を作成します。

カスタムメトリクスオートスケーラーを使用するには、ワークロード用の ScaledObject または ScaledJob オブジェクトを作成します。これらは、スケーリングメタデータを定義するカスタムリソース (CR) です。スケーリングするデプロイメントまたはジョブ、スケーリングするメトリクスのソース (トリガー)、許可される最小および最大レプリカ数などのその他のパラメーターを指定します。

注記

スケーリングするワークロードごとに、スケーリングされたオブジェクトまたはスケーリングされたジョブを 1 つだけ作成できます。また、スケーリングされたオブジェクトまたはスケーリングされたジョブと Horizontal Pod Autoscaler (HPA) を同じワークロードで使用することはできません。

カスタムメトリクスオートスケーラーは、HPA とは異なり、ゼロにスケーリングできます。カスタムメトリクスオートスケーラー CR の minReplicaCount 値を 0 に設定すると、カスタムメトリクスオートスケーラーはワークロードを 1 レプリカから 0 レプリカにスケールダウンするか、0 レプリカから 1 にスケールアップします。これは、アクティベーションフェーズ として知られています。1 つのレプリカにスケールアップした後、HPA はスケーリングを制御します。これは スケーリングフェーズ として知られています。

一部のトリガーにより、クラスターメトリクスオートスケーラーによってスケーリングされるレプリカの数を変更できます。いずれの場合も、アクティベーションフェーズを設定するパラメーターは、activation で始まる同じフレーズを常に使用します。たとえば、threshold パラメーターがスケーリングを設定する場合、activationThreshold はアクティベーションを設定します。アクティベーションフェーズとスケーリングフェーズを設定すると、スケーリングポリシーの柔軟性が向上します。たとえば、アクティベーションフェーズをより高く設定することで、メトリクスが特に低い場合にスケールアップまたはスケールダウンを防ぐことができます。

それぞれ異なる決定を行う場合は、スケーリングの値よりもアクティベーションの値が優先されます。たとえば、threshold10 に設定されていて、activationThreshold50 である場合にメトリクスが 40 を報告した場合、スケーラーはアクティブにならず、HPA が 4 つのインスタンスを必要とする場合でも Pod はゼロにスケーリングされます。

図3.1 カスタムメトリクスオートスケーラーのワークフロー

カスタムメトリクスオートスケーラーのワークフロー
  1. クラスター上のワークロード用のスケーリングされたオブジェクトのカスタムリソースを作成または変更します。オブジェクトには、そのワークロードのスケーリング設定を含めます。OpenShift API サーバーは、新しいオブジェクトを受け入れる前に、そのオブジェクトをカスタムメトリクスオートスケーラーのアドミッション Webhook プロセスに送信して、オブジェクトが有効であることを確認します。検証が成功すると、API サーバーはオブジェクトを永続化します。
  2. カスタムメトリクスオートスケーラーコントローラーが、スケーリングされたオブジェクトの更新または変更を監視します。OpenShift API サーバーがコントローラーに変更を通知すると、コントローラーは、オブジェクト内で指定されている外部トリガーソース (データソースとも呼ばれる) を監視して、メトリクスデータの変更を確認します。1 つ以上のスケーラーが外部トリガーソースからのスケーリングデータを要求します。たとえば、Kafka トリガータイプの場合、コントローラーは Kafka スケーラーを使用して Kafka インスタンスと通信し、トリガーによって要求されたデータを取得します。
  3. コントローラーが、スケーリングされたオブジェクトの水平 Pod オートスケーラーオブジェクトを作成します。その結果、Horizontal Pod Autoscaler (HPA) Operator が、トリガーに関連付けられたスケーリングデータの監視を開始します。HPA は、クラスターの OpenShift API サーバーエンドポイントからスケーリングデータを要求します。
  4. OpenShift API サーバーエンドポイントが、カスタムメトリクスオートスケーラーのメトリクスアダプターによって提供されます。メトリクスアダプターは、カスタムメトリクスの要求を受信すると、コントローラーへの GRPC 接続を使用して、スケーラーから受信した最新のトリガーデータを要求します。
  5. HPA がメトリクスアダプターから受信したデータに基づいてスケーリングを決定し、レプリカを増減することでワークロードをスケールアップまたはスケールダウンします。
  6. 運用中に、ワークロードがスケーリングメトリクスに影響を与えることがあります。たとえば、Kafka キュー内の作業を処理するためにワークロードがスケールアップされた場合、ワークロードがすべての作業を処理した後、キューのサイズが減少します。その結果、ワークロードがスケールダウンされます。
  7. メトリクスが minReplicaCount 値で指定された範囲内にある場合、カスタムメトリクスオートスケーラーコントローラーがすべてのスケーリングを無効にして、レプリカ数を一定に維持します。メトリクスがその範囲を超える場合、カスタムメトリクスオートスケーラーコントローラーはスケーリングを有効にして、HPA がワークロードをスケーリングできるようにします。スケーリングが無効になっている間、HPA は何もアクションを実行しません。

3.2.1. Custom Metrics Autoscaler 用のカスタム CA 証明書

デフォルトでは、Custom Metrics Autoscaler Operator は、自動的に生成されたサービス CA 証明書を使用して、クラスター上のサービスに接続します。

カスタム CA 証明書を必要とするクラスター外のサービスを使用する場合は、必要な証明書を config map に追加できます。次に、カスタムメトリクスオートスケーラーのインストール の説明に従って、KedaController カスタムリソースに config map を追加します。Operator は起動時にこれらの証明書を読み込み、Operator によって信頼されたものとして登録します。

config map には、1 つ以上の PEM エンコードされた CA 証明書を含む 1 つ以上の証明書ファイルを含めることができます。または、証明書ファイルごとに個別の config map を使用することもできます。

注記

後で config map を更新して追加の証明書を追加する場合は、変更を有効にするために keda-operator-* Pod を再起動する必要があります。

3.3. カスタムメトリクスオートスケーラーのインストール

OpenShift Container Platform Web コンソールを使用して Custom Metrics Autoscaler Operator をインストールすることができます。

インストールにより、以下の 5 つの CRD が作成されます。

  • ClusterTriggerAuthentication
  • KedaController
  • ScaledJob
  • ScaledObject
  • TriggerAuthentication

3.3.1. カスタムメトリクスオートスケーラーのインストール

次の手順を使用して、Custom Metrics Autoscaler Operator をインストールできます。

前提条件

  • これまでにインストールしたテクノロジープレビューバージョンの Cluster Metrics Autoscaler Operator を削除する。
  • コミュニティーベースの KEDA バージョンをすべて削除する。

    次のコマンドを実行して、KEDA 1.x カスタムリソース定義を削除する。

    $ oc delete crd scaledobjects.keda.k8s.io
    $ oc delete crd triggerauthentications.keda.k8s.io
  • オプション: Custom Metrics Autoscaler Operator を外部 Kafka クラスターや外部 Prometheus サービスなどのクラスター外のサービスに接続する必要がある場合は、必要なサービス CA 証明書を config map に配置します。config map は、Operator がインストールされているのと同じ namespace に存在する必要があります。以下に例を示します。

    $ oc create configmap -n openshift-keda thanos-cert  --from-file=ca-cert.pem

手順

  1. OpenShift Container Platform Web コンソールで、OperatorsOperatorHub をクリックします。
  2. 使用可能な Operator のリストから Custom Metrics Autoscaler を選択し、Install をクリックします。
  3. Install Operator ページで、Installation ModeAll namespaces on the cluster (default) オプションが選択されていることを確認します。これにより、Operator がすべての namespace にインストールされます。
  4. Installed Namespaceopenshift-keda namespace が選択されていることを確認します。クラスターに存在しない場合、OpenShift Container Platform は namespace を作成します。
  5. Install をクリックします。
  6. Custom Metrics Autoscaler Operator コンポーネントをリスト表示して、インストールを確認します。

    1. WorkloadsPods に移動します。
    2. ドロップダウンメニューから openshift-keda プロジェクトを選択し、custom-metrics-autoscaler-operator-* Pod が実行されていることを確認します。
    3. WorkloadsDeployments に移動して、custom-metrics-autoscaler-operator デプロイメントが実行されていることを確認します。
  7. オプション: 次のコマンドを使用して、OpenShift CLI でインストールを確認します。

    $ oc get all -n openshift-keda

    以下のような出力が表示されます。

    出力例

    NAME                                                      READY   STATUS    RESTARTS   AGE
    pod/custom-metrics-autoscaler-operator-5fd8d9ffd8-xt4xp   1/1     Running   0          18m
    
    NAME                                                 READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/custom-metrics-autoscaler-operator   1/1     1            1           18m
    
    NAME                                                            DESIRED   CURRENT   READY   AGE
    replicaset.apps/custom-metrics-autoscaler-operator-5fd8d9ffd8   1         1         1       18m

  8. 必要な CRD を作成する KedaController カスタムリソースをインストールします。

    1. OpenShift Container Platform Web コンソールで、OperatorsInstalled Operators をクリックします。
    2. Custom Metrics Autoscaler をクリックします。
    3. Operator Details ページで、KedaController タブをクリックします。
    4. KedaController タブで、Create KedaController をクリックしてファイルを編集します。

      kind: KedaController
      apiVersion: keda.sh/v1alpha1
      metadata:
        name: keda
        namespace: openshift-keda
      spec:
        watchNamespace: '' 1
        operator:
          logLevel: info 2
          logEncoder: console 3
          caConfigMaps: 4
          - thanos-cert
          - kafka-cert
        metricsServer:
          logLevel: '0' 5
          auditConfig: 6
            logFormat: "json"
            logOutputVolumeClaim: "persistentVolumeClaimName"
            policy:
              rules:
              - level: Metadata
              omitStages: ["RequestReceived"]
              omitManagedFields: false
            lifetime:
              maxAge: "2"
              maxBackup: "1"
              maxSize: "50"
        serviceAccount: {}
      1
      Custom Metrics Autoscaler Operator がアプリケーションをスケーリングする単一の namespace を指定します。空白のままにするか、または空にして、すべての namespace でアプリケーションをスケーリングします。このフィールドは、namespace があるか、空である必要があります。デフォルト値は空です。
      2
      Custom Metrics Autoscaler Operator ログメッセージの詳細レベルを指定します。許可される値は debuginfoerror です。デフォルトは info です。
      3
      Custom Metrics Autoscaler Operator ログメッセージのログ形式を指定します。許可される値は console または json です。デフォルトは コンソール です。
      4
      オプション: CA 証明書を持つ 1 つ以上の config map を指定します。Custom Metrics Autoscaler Operator はこれを使用して、TLS 対応のメトリクスソースに安全に接続できます。
      5
      Custom Metrics Autoscaler Metrics Server のログレベルを指定します。許可される値は、info の場合は 0 で、debug の場合は 4 です。デフォルトは 0 です。
      6
      Custom Metrics Autoscaler Operator の監査ログをアクティブにして、使用する監査ポリシーを指定します (「監査ログの設定」セクションを参照)。
    5. Create をクリックして KEDA コントローラーを作成します。

3.4. カスタムメトリクスオートスケーラートリガーについて

スケーラーとも呼ばれるトリガーは、Custom Metrics Autoscaler Operator が Pod をスケーリングするために使用するメトリクスを提供します。

カスタムメトリクスオートスケーラーは現在、Prometheus、CPU、メモリー、および Apache Kafka トリガーのみをサポートしています。

以下のセクションで説明するように、ScaledObject または ScaledJob カスタムリソースを使用して、特定のオブジェクトのトリガーを設定します。

scaled object で使用 する認証局、または クラスター内のすべてのスケーラー用 の認証局を設定できます。

3.4.1. Prometheus トリガーについて

Prometheus メトリクスに基づいて Pod をスケーリングできます。このメトリクスは、インストール済みの OpenShift Container Platform モニタリングまたは外部 Prometheus サーバーをメトリクスソースとして使用できます。OpenShift Container Platform モニタリングをメトリクスのソースとして使用するために必要な設定は、「OpenShift Container Platform モニタリングを使用するためのカスタムメトリクスオートスケーラーの設定」を参照してください。

注記

カスタムメトリクスオートスケーラーがスケーリングしているアプリケーションから Prometheus がメトリクスを収集している場合は、カスタムリソースで最小レプリカ数を 0 に設定しないでください。アプリケーション Pod がないと、カスタムメトリクスオートスケーラーにスケーリングの基準となるメトリクスが提供されません。

Prometheus ターゲットを使用した scaled object の例

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: prom-scaledobject
  namespace: my-namespace
spec:
# ...
  triggers:
  - type: prometheus 1
    metadata:
      serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9092 2
      namespace: kedatest 3
      metricName: http_requests_total 4
      threshold: '5' 5
      query: sum(rate(http_requests_total{job="test-app"}[1m])) 6
      authModes: basic 7
      cortexOrgID: my-org 8
      ignoreNullValues: "false" 9
      unsafeSsl: "false" 10

1
Prometheus をトリガータイプとして指定します。
2
Prometheus サーバーのアドレスを指定します。この例では、OpenShift Container Platform モニタリングを使用します。
3
オプション: スケーリングするオブジェクトの namespace を指定します。メトリクスのソースとして OpenShift Container Platform モニタリングを使用する場合、このパラメーターは必須です。
4
external.metrics.k8s.io API でメトリクスを識別する名前を指定します。複数のトリガーを使用している場合、すべてのメトリクス名が一意である必要があります。
5
スケーリングをトリガーする値を指定します。引用符で囲まれた文字列値として指定する必要があります。
6
使用する Prometheus クエリーを指定します。
7
使用する認証方法を指定します。Prometheus スケーラーは、ベアラー認証 (bearer)、Basic 認証 (basic)、または TLS 認証 (tls) をサポートしています。以下のセクションで説明するように、トリガー認証で特定の認証パラメーターを設定します。必要に応じて、シークレットを使用することもできます。
8
オプション: X-Scope-OrgID ヘッダーを Prometheus のマルチテナント Cortex または Mimir ストレージに渡します。このパラメーターは、Prometheus が返す必要のあるデータを示すために、マルチテナント Prometheus ストレージでのみ必要です。
9
オプション: Prometheus ターゲットが失われた場合のトリガーの処理方法を指定します。
  • true の場合、Prometheus ターゲットが失われても、トリガーは動作し続けます。これがデフォルトの動作です。
  • false の場合、Prometheus ターゲットが失われると、トリガーはエラーを返します。
10
オプション: 証明書チェックをスキップするかどうかを指定します。たとえば、テスト環境で実行しており、Prometheus エンドポイントで自己署名証明書を使用している場合は、チェックをスキップできます。
  • false の場合、証明書のチェックが実行されます。これがデフォルトの動作です。
  • true の場合、証明書のチェックは実行されません。

    重要

    チェックのスキップは推奨されません。

3.4.1.1. OpenShift Container Platform モニタリングを使用するためのカスタムメトリクスオートスケーラーの設定

カスタムメトリクスオートスケーラーが使用するメトリクスのソースとして、インストール済みの OpenShift Container Platform Prometheus モニタリングを使用できます。ただし、実行する必要がある追加の設定がいくつかあります。

注記

これらの手順は、外部 Prometheus ソースには必要ありません。

このセクションで説明するように、次のタスクを実行する必要があります。

  • サービスアカウントを作成します。
  • サービスアカウントのトークンを生成するシークレットを作成します。
  • トリガー認証を作成します。
  • ロールを作成します。
  • そのロールをサービスアカウントに追加します。
  • Prometheus が使用するトリガー認証オブジェクトでトークンを参照します。

前提条件

  • OpenShift Container Platform モニタリングをインストールしている必要がある。
  • ユーザー定義のワークロードのモニタリングを、OpenShift Container Platform モニタリングで有効にする必要がある (ユーザー定義のワークロードモニタリング設定マップの作成 セクションで説明)。
  • Custom Metrics Autoscaler Operator をインストールしている。

手順

  1. スケーリングするオブジェクトを含むプロジェクトに変更します。

    $ oc project my-project
  2. クラスターにサービスアカウントおよびトークンがない場合は、これを作成します。

    1. 次のコマンドを使用して、service account オブジェクトを作成します。

      $ oc create serviceaccount thanos 1
      1
      サービスアカウントの名前を指定します。
    2. secret YAML を作成し、サービスアカウントトークンを生成します。

      重要

      ImageRegistry 機能を無効にした場合、または Cluster Image Registry Operator の設定で統合済みの OpenShift イメージレジストリーを無効にした場合、イメージプルシークレットはサービスアカウントごとに生成されません。この状況では、この手順を実行する必要があります。

      apiVersion: v1
      kind: Secret
      metadata:
        name: thanos-token
        annotations:
          kubernetes.io/service-account.name: thanos 1
      type: kubernetes.io/service-account-token
      1
      サービスアカウントの名前を指定します。
    3. 次のコマンドを使用してシークレットオブジェクトを作成します。

      $ oc create -f <file_name>.yaml
    4. 次のコマンドを使用して、サービスアカウントに割り当てられたトークンを見つけます。

      $ oc describe serviceaccount thanos 1
      1
      サービスアカウントの名前を指定します。

      出力例

      Name:                thanos
      Namespace:           my-project
      Labels:              <none>
      Annotations:         <none>
      Image pull secrets:  thanos-dockercfg-nnwgj
      Mountable secrets:   thanos-dockercfg-nnwgj
      Tokens:              thanos-token 1
      Events:              <none>

      1
      トリガー認証でこのトークンを使用します。
  3. サービスアカウントトークンを使用してトリガー認証を作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: keda.sh/v1alpha1
      kind: TriggerAuthentication
      metadata:
        name: keda-trigger-auth-prometheus
      spec:
        secretTargetRef: 1
        - parameter: bearerToken 2
          name: thanos-token 3
          key: token 4
        - parameter: ca
          name: thanos-token
          key: ca.crt
      1
      このオブジェクトが承認にシークレットを使用することを指定します。
      2
      トークンを使用して提供する認証パラメーターを指定します。
      3
      使用するトークンの名前を指定します。
      4
      指定されたパラメーターで使用するトークン内のキーを指定します。
    2. CR オブジェクトを作成します。

      $ oc create -f <file-name>.yaml
  4. Thanos メトリクスを読み取るためのロールを作成します。

    1. 次のパラメーターを使用して YAML ファイルを作成します。

      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: thanos-metrics-reader
      rules:
      - apiGroups:
        - ""
        resources:
        - pods
        verbs:
        - get
      - apiGroups:
        - metrics.k8s.io
        resources:
        - pods
        - nodes
        verbs:
        - get
        - list
        - watch
    2. CR オブジェクトを作成します。

      $ oc create -f <file-name>.yaml
  5. Thanos メトリクスを読み取るためのロールバインディングを作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: thanos-metrics-reader 1
        namespace: my-project 2
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: thanos-metrics-reader
      subjects:
      - kind: ServiceAccount
        name: thanos 3
        namespace: my-project 4
      1
      作成したロールの名前を指定します。
      2
      スケーリングするオブジェクトの namespace を指定します。
      3
      ロールにバインドするサービスアカウントの名前を指定します。
      4
      スケーリングするオブジェクトの namespace を指定します。
    2. CR オブジェクトを作成します。

      $ oc create -f <file-name>.yaml

「カスタムメトリクスオートスケーラーの追加方法について」で説明されているとおり、スケーリングされたオブジェクトまたはスケーリングされたジョブをデプロイして、アプリケーションの自動スケーリングを有効化できます。OpenShift Container Platform モニタリングをソースとして使用するには、トリガーまたはスケーラーに以下のパラメーターを含める必要があります。

  • triggers.typeprometheus にしてください。
  • triggers.metadata.serverAddresshttps://thanos-querier.openshift-monitoring.svc.cluster.local:9092 にしてください。
  • triggers.metadata.authModesbearer にしてください。
  • triggers.metadata.namespace は、スケーリングするオブジェクトの namespace に設定してください。
  • triggers.authenticationRef は、直前の手順で指定されたトリガー認証リソースを指す必要があります。

3.4.2. CPU トリガーについて

CPU メトリクスに基づいて Pod をスケーリングできます。このトリガーは、クラスターメトリクスをメトリクスのソースとして使用します。

カスタムメトリクスオートスケーラーは、オブジェクトに関連付けられた Pod をスケーリングして、指定された CPU 使用率を維持します。オートスケーラーは、すべての Pod で指定された CPU 使用率を維持するために、最小数と最大数の間でレプリカ数を増減します。メモリートリガーは、Pod 全体のメモリー使用率を考慮します。Pod に複数のコンテナーがある場合、メモリートリガーは Pod 内にあるすべてのコンテナーの合計メモリー使用率を考慮します。

注記
  • このトリガーは、ScaledJob カスタムリソースでは使用できません。
  • メモリートリガーを使用してオブジェクトをスケーリングすると、複数のトリガーを使用している場合でも、オブジェクトは 0 にスケーリングされません。

CPU ターゲットを使用した scaled object の例

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: cpu-scaledobject
  namespace: my-namespace
spec:
# ...
  triggers:
  - type: cpu 1
    metricType: Utilization 2
    metadata:
      value: '60' 3
  minReplicaCount: 1 4

1
トリガータイプとして CPU を指定します。
2
使用するメトリクスのタイプ (Utilization または AverageValue のいずれか) を指定します。
3
スケーリングをトリガーする値を指定します。引用符で囲まれた文字列値として指定する必要があります。
  • Utilization を使用する場合、ターゲット値は、関連する全 Pod のリソースメトリクスの平均値であり、Pod のリソースの要求値に占めるパーセンテージとして表されます。
  • AverageValue を使用する場合、ターゲット値は、関連する全 Pod のメトリクスの平均値です。
4
スケールダウン時のレプリカの最小数を指定します。CPU トリガーの場合は、1 以上の値を入力します。CPU メトリクスのみを使用している場合、HPA はゼロにスケールできないためです。

3.4.3. メモリートリガーについて

メモリーメトリクスに基づいて Pod をスケーリングできます。このトリガーは、クラスターメトリクスをメトリクスのソースとして使用します。

カスタムメトリクスオートスケーラーは、オブジェクトに関連付けられた Pod をスケーリングして、指定されたメモリー使用率を維持します。オートスケーラーは、すべての Pod で指定のメモリー使用率を維持するために、最小数と最大数の間でレプリカ数を増減します。メモリートリガーは、Pod 全体のメモリー使用率を考慮します。Pod に複数のコンテナーがある場合、メモリー使用率はすべてのコンテナーの合計になります。

注記
  • このトリガーは、ScaledJob カスタムリソースでは使用できません。
  • メモリートリガーを使用してオブジェクトをスケーリングすると、複数のトリガーを使用している場合でも、オブジェクトは 0 にスケーリングされません。

メモリーターゲットを使用した scaled object の例

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: memory-scaledobject
  namespace: my-namespace
spec:
# ...
  triggers:
  - type: memory 1
    metricType: Utilization 2
    metadata:
      value: '60' 3
      containerName: api 4

1
トリガータイプとしてメモリーを指定します。
2
使用するメトリクスのタイプ (Utilization または AverageValue のいずれか) を指定します。
3
スケーリングをトリガーする値を指定します。引用符で囲まれた文字列値として指定する必要があります。
  • Utilization を使用する場合、ターゲット値は、関連する全 Pod のリソースメトリクスの平均値であり、Pod のリソースの要求値に占めるパーセンテージとして表されます。
  • AverageValue を使用する場合、ターゲット値は、関連する全 Pod のメトリクスの平均値です。
4
オプション: Pod 全体ではなく、そのコンテナーのみのメモリー使用率に基づいて、スケーリングする個々のコンテナーを指定します。この例では、api という名前のコンテナーのみがスケーリングされます。

3.4.4. Kafka トリガーについて

Apache Kafka トピックまたは Kafka プロトコルをサポートするその他のサービスに基づいて Pod をスケーリングできます。カスタムメトリクスオートスケーラーは、スケーリングされるオブジェクトまたはスケーリングされるジョブで allowIdleConsumers パラメーターを true に設定しない限り、Kafka パーティションの数を超えてスケーリングしません。

注記

コンシューマーグループの数がトピック内のパーティションの数を超えると、余分なコンシューマーグループはそのままアイドル状態になります。これを回避するために、デフォルトではレプリカの数は次の値を超えません。

  • トピックのパーティションの数 (トピックが指定されている場合)。
  • コンシューマーグループ内の全トピックのパーティション数 (トピックが指定されていない場合)。
  • スケーリングされるオブジェクトまたはスケーリングされるジョブの CR で指定された maxReplicaCount

これらのデフォルトの動作は、allowIdleConsumers パラメーターを使用して無効にすることができます。

Kafka ターゲットを使用した scaled object の例

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-scaledobject
  namespace: my-namespace
spec:
# ...
  triggers:
  - type: kafka 1
    metadata:
      topic: my-topic 2
      bootstrapServers: my-cluster-kafka-bootstrap.openshift-operators.svc:9092 3
      consumerGroup: my-group 4
      lagThreshold: '10' 5
      activationLagThreshold: '5' 6
      offsetResetPolicy: latest 7
      allowIdleConsumers: true 8
      scaleToZeroOnInvalidOffset: false 9
      excludePersistentLag: false 10
      version: '1.0.0' 11
      partitionLimitation: '1,2,10-20,31' 12
      tls: enable 13

1
トリガータイプとして Kafka を指定します。
2
Kafka がオフセットラグを処理している Kafka トピックの名前を指定します。
3
接続する Kafka ブローカーのコンマ区切りリストを指定します。
4
トピックのオフセットの確認と、関連するラグの処理に使用される Kafka コンシューマーグループの名前を指定します。
5
オプション: スケーリングをトリガーする平均ターゲット値を指定します。引用符で囲まれた文字列値として指定する必要があります。デフォルトは 5 です。
6
オプション: アクティベーションフェーズのターゲット値を指定します。引用符で囲まれた文字列値として指定する必要があります。
7
オプション: Kafka コンシューマーの Kafka オフセットリセットポリシーを指定します。使用可能な値は latest および earliest です。デフォルトは latest です。
8
オプション: Kafka レプリカの数がトピックのパーティションの数を超えることを許可するかどうかを指定します。
  • true の場合、Kafka レプリカの数はトピックのパーティションの数を超えることができます。これにより、Kafka コンシューマーがアイドル状態になることが許容されます。
  • false の場合、Kafka レプリカの数はトピックのパーティションの数を超えることはできません。これはデフォルトになります。
9
Kafka パーティションに有効なオフセットがない場合のトリガーの動作を指定します。
  • true の場合、そのパーティションのコンシューマーはゼロにスケーリングされます。
  • false の場合、スケーラーはそのパーティションのために 1 つのコンシューマーを保持します。これはデフォルトになります。
10
オプション: 現在のオフセットが前のポーリングサイクルの現在のオフセットと同じであるパーティションのパーティションラグをトリガーに含めるか除外するかを指定します。
  • true の場合、スケーラーはこれらのパーティションのパーティションラグを除外します。
  • false の場合、すべてのパーティションのコンシューマーラグがすべてトリガーに含まれます。これはデフォルトになります。
11
オプション: Kafka ブローカーのバージョンを指定します。引用符で囲まれた文字列値として指定する必要があります。デフォルトは 1.0.0 です。
12
オプション: スケーリングのスコープを適用するパーティション ID のコンマ区切りリストを指定します。指定されている場合、ラグの計算時にリスト内の ID のみが考慮されます。引用符で囲まれた文字列値として指定する必要があります。デフォルトでは、すべてのパーティションが考慮されます。
13
オプション: Kafka に TSL クライアント認証を使用するかどうかを指定します。デフォルトは disable です。TLS の設定の詳細は、「カスタムメトリクスオートスケーラートリガー認証について」を参照してください。

3.4.5. Cron トリガーについて

Pod は時間範囲に基づいてスケーリングできます。

時間範囲の開始時に、カスタムメトリクスオートスケーラーが、オブジェクトに関連する Pod を、設定された最小 Pod 数から指定された必要な Pod 数にスケーリングします。時間範囲の終了時に、Pod は設定された最小値にスケールダウンされます。期間は cron 形式 で設定する必要があります。

次の例では、この scaled object に関連する Pod を、インド標準時の午前 6 時から午後 6 時 30 分まで 0 から 100 にスケーリングします。

Cron トリガーを使用した scaled object の例

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: cron-scaledobject
  namespace: default
spec:
  scaleTargetRef:
    name: my-deployment
  minReplicaCount: 0 1
  maxReplicaCount: 100 2
  cooldownPeriod: 300
  triggers:
  - type: cron 3
    metadata:
      timezone: Asia/Kolkata 4
      start: "0 6 * * *" 5
      end: "30 18 * * *" 6
      desiredReplicas: "100" 7

1
時間枠の終了時にスケールダウンする Pod の最小数を指定します。
2
スケールアップ時のレプリカの最大数を指定します。この値は desiredReplicas と同じである必要があります。デフォルトは 100 です。
3
Cron トリガーを指定します。
4
時間枠のタイムゾーンを指定します。この値は、IANA Time Zone Database から取得する必要があります。
5
時間枠の始点を指定します。
6
時間枠の終点を指定します。
7
時間枠の始点から終点までの間にスケーリングする Pod の数を指定します。この値は maxReplicaCount と同じである必要があります。

3.5. カスタムメトリクスオートスケーラートリガー認証について

トリガー認証を使用すると、関連付けられたコンテナーで使用できるスケーリングされたオブジェクトまたはスケーリングされたジョブに認証情報を含めることができます。トリガー認証を使用して、OpenShift Container Platform シークレット、プラットフォームネイティブの Pod 認証メカニズム、環境変数などを渡すことができます。

スケーリングするオブジェクトと同じ namespace に TriggerAuthentication オブジェクトを定義します。そのトリガー認証は、その namespace 内のオブジェクトによってのみ使用できます。

または、複数の namespace のオブジェクト間で認証情報を共有するには、すべての namespace で使用できる ClusterTriggerAuthentication オブジェクトを作成できます。

トリガー認証とクラスタートリガー認証は同じ設定を使用します。ただし、クラスタートリガー認証では、スケーリングされたオブジェクトの認証参照に追加の kind パラメーターが必要です。

Basic 認証のシークレットの例

apiVersion: v1
kind: Secret
metadata:
  name: my-basic-secret
  namespace: default
data:
  username: "dXNlcm5hbWU=" 1
  password: "cGFzc3dvcmQ="

1
トリガー認証に提供するユーザー名とパスワード。data スタンザ内の値は、Base64 でエンコードされている必要があります。

Basic 認証のシークレットを使用したトリガー認証の例

kind: TriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata:
  name: secret-triggerauthentication
  namespace: my-namespace 1
spec:
  secretTargetRef: 2
  - parameter: username 3
    name: my-basic-secret 4
    key: username 5
  - parameter: password
    name: my-basic-secret
    key: password

1
スケーリングするオブジェクトの namespace を指定します。
2
このトリガー認証では、メトリクスエンドポイントに接続するときに、認可にシークレットを使用することを指定します。
3
シークレットを使用して提供する認証パラメーターを指定します。
4
使用するシークレットの名前を指定します。
5
指定されたパラメーターで使用するシークレットのキーを指定します。

Basic 認証のシークレットを使用したクラスタートリガー認証の例

kind: ClusterTriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata: 1
  name: secret-cluster-triggerauthentication
spec:
  secretTargetRef: 2
  - parameter: username 3
    name: my-basic-secret 4
    key: username 5
  - parameter: password
    name: my-basic-secret
    key: password

1
クラスタートリガー認証では namespace が使用されないことに注意してください。
2
このトリガー認証では、メトリクスエンドポイントに接続するときに、認可にシークレットを使用することを指定します。
3
シークレットを使用して提供する認証パラメーターを指定します。
4
使用するシークレットの名前を指定します。
5
指定されたパラメーターで使用するシークレットのキーを指定します。

認証局 (CA) の詳細を含むシークレットの例

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
  namespace: my-namespace
data:
  ca-cert.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0... 1
  client-cert.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0... 2
  client-key.pem: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0t...

1
メトリクスエンドポイントの認証用の TLS CA 証明書を指定します。値は Base64 でエンコードされている必要があります。
2
TLS クライアント認証用の TLS 証明書と鍵を指定します。値は Base64 でエンコードされている必要があります。

CA の詳細用のシークレットを使用したトリガー認証の例

kind: TriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata:
  name: secret-triggerauthentication
  namespace: my-namespace 1
spec:
  secretTargetRef: 2
    - parameter: key 3
      name: my-secret 4
      key: client-key.pem 5
    - parameter: ca 6
      name: my-secret 7
      key: ca-cert.pem 8

1
スケーリングするオブジェクトの namespace を指定します。
2
このトリガー認証では、メトリクスエンドポイントに接続するときに、認可にシークレットを使用することを指定します。
3
使用する認証の種類を指定します。
4
使用するシークレットの名前を指定します。
5
指定されたパラメーターで使用するシークレットのキーを指定します。
6
メトリクスエンドポイントに接続するときに、カスタム CA の認証パラメーターを指定します。
7
使用するシークレットの名前を指定します。
8
指定されたパラメーターで使用するシークレットのキーを指定します。

ベアラートークンを使用したシークレットの例

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
  namespace: my-namespace
data:
  bearerToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXV" 1

1
ベアラー認証で使用するベアラートークンを指定します。data スタンザ内の値は、Base64 でエンコードされている必要があります。

ベアラートークンを使用したトリガー認証の例

kind: TriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata:
  name: token-triggerauthentication
  namespace: my-namespace 1
spec:
  secretTargetRef: 2
  - parameter: bearerToken 3
    name: my-secret 4
    key: bearerToken 5

1
スケーリングするオブジェクトの namespace を指定します。
2
このトリガー認証では、メトリクスエンドポイントに接続するときに、認可にシークレットを使用することを指定します。
3
使用する認証の種類を指定します。
4
使用するシークレットの名前を指定します。
5
指定されたパラメーターで使用するトークン内のキーを指定します。

環境変数を使用したトリガー認証の例

kind: TriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata:
  name: env-var-triggerauthentication
  namespace: my-namespace 1
spec:
  env: 2
  - parameter: access_key 3
    name: ACCESS_KEY 4
    containerName: my-container 5

1
スケーリングするオブジェクトの namespace を指定します。
2
このトリガー認証では、メトリクスエンドポイントに接続するときに、認可に環境変数を使用することを指定します。
3
この変数で設定するパラメーターを指定します。
4
環境変数の名前を指定します。
5
オプション: 認証が必要なコンテナーを指定します。コンテナーは、スケーリングされたオブジェクトの scaleTargetRef によって参照されるものと同じリソースにある必要があります。

Pod 認証プロバイダーを使用したトリガー認証の例

kind: TriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata:
  name: pod-id-triggerauthentication
  namespace: my-namespace 1
spec:
  podIdentity: 2
    provider: aws-eks 3

1
スケーリングするオブジェクトの namespace を指定します。
2
このトリガー認証では、メトリクスエンドポイントに接続するときに、プラットフォームネイティブの Pod 認証を使用することを指定します。
3
Pod ID を指定します。サポートされている値は、noneazuregcpaws-eks、または aws-kiam です。デフォルト値は none です。

関連情報

3.5.1. トリガー認証の使用

トリガー認証とクラスタートリガー認証は、カスタムリソースを使用して認証を作成し、スケーリングされたオブジェクトまたはスケーリングされたジョブへの参照を追加することで使用します。

前提条件

  • Custom Metrics Autoscaler Operator をインストールしている。
  • シークレットを使用している場合は、Secret オブジェクトが存在する必要があります。次に例を示します。

    シークレットの例

    apiVersion: v1
    kind: Secret
    metadata:
      name: my-secret
    data:
      user-name: <base64_USER_NAME>
      password: <base64_USER_PASSWORD>

手順

  1. TriggerAuthentication または ClusterTriggerAuthentication オブジェクトを作成します。

    1. オブジェクトを定義する YAML ファイルを作成します。

      シークレットを使用したトリガー認証の例

      kind: TriggerAuthentication
      apiVersion: keda.sh/v1alpha1
      metadata:
        name: prom-triggerauthentication
        namespace: my-namespace
      spec:
        secretTargetRef:
        - parameter: user-name
          name: my-secret
          key: USER_NAME
        - parameter: password
          name: my-secret
          key: USER_PASSWORD

    2. TriggerAuthentication オブジェクトを作成します。

      $ oc create -f <filename>.yaml
  2. トリガー認証を使用する ScaledObject YAML ファイルを作成または編集します。

    1. 次のコマンドを実行して、オブジェクトを定義する YAML ファイルを作成します。

      トリガー認証を使用したスケーリングされたオブジェクトの例

      apiVersion: keda.sh/v1alpha1
      kind: ScaledObject
      metadata:
        name: scaledobject
        namespace: my-namespace
      spec:
        scaleTargetRef:
          name: example-deployment
        maxReplicaCount: 100
        minReplicaCount: 0
        pollingInterval: 30
        triggers:
        - type: prometheus
          metadata:
            serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9092
            namespace: kedatest # replace <NAMESPACE>
            metricName: http_requests_total
            threshold: '5'
            query: sum(rate(http_requests_total{job="test-app"}[1m]))
            authModes: "basic"
          authenticationRef:
            name: prom-triggerauthentication 1
            kind: TriggerAuthentication 2

      1
      トリガー認証オブジェクトの名前を指定します。
      2
      TriggerAuthentication を指定します。TriggerAuthentication がデフォルトです。

      クラスタートリガー認証を使用したスケーリングされたオブジェクトの例

      apiVersion: keda.sh/v1alpha1
      kind: ScaledObject
      metadata:
        name: scaledobject
        namespace: my-namespace
      spec:
        scaleTargetRef:
          name: example-deployment
        maxReplicaCount: 100
        minReplicaCount: 0
        pollingInterval: 30
        triggers:
        - type: prometheus
          metadata:
            serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9092
            namespace: kedatest # replace <NAMESPACE>
            metricName: http_requests_total
            threshold: '5'
            query: sum(rate(http_requests_total{job="test-app"}[1m]))
            authModes: "basic"
          authenticationRef:
            name: prom-cluster-triggerauthentication 1
            kind: ClusterTriggerAuthentication 2

      1
      トリガー認証オブジェクトの名前を指定します。
      2
      ClusterTriggerAuthentication を指定します。
    2. 次のコマンドを実行して、スケーリングされたオブジェクトを作成します。

      $ oc apply -f <filename>

3.6. スケーリングされたオブジェクトのカスタムメトリクスオートスケーラーの一時停止

必要に応じて、ワークロードの自動スケーリングを一時停止および再開できます。

たとえば、クラスターのメンテナンスを実行する前に自動スケーリングを一時停止したり、ミッションクリティカルではないワークロードを削除してリソース不足を回避したりできます。

3.6.1. カスタムメトリクスオートスケーラーの一時停止

スケーリングされたオブジェクトの自動スケーリングを一時停止するには、そのスケーリングされたオブジェクトのカスタムメトリクスオートスケーラーに autoscaling.keda.sh/paused-replicas アノテーションを追加します。カスタムメトリクスオートスケーラーは、そのワークロードのレプリカを指定された値にスケーリングし、アノテーションが削除されるまで自動スケーリングを一時停止します。

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  annotations:
    autoscaling.keda.sh/paused-replicas: "4"
# ...

手順

  1. 次のコマンドを使用して、ワークロードの ScaledObject CR を編集します。

    $ oc edit ScaledObject scaledobject
  2. autoscaling.keda.sh/paused-replicas アノテーションに任意の値を追加します。

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      annotations:
        autoscaling.keda.sh/paused-replicas: "4" 1
      creationTimestamp: "2023-02-08T14:41:01Z"
      generation: 1
      name: scaledobject
      namespace: my-project
      resourceVersion: '65729'
      uid: f5aec682-acdf-4232-a783-58b5b82f5dd0
    1
    Custom Metrics Autoscaler Operator がレプリカを指定された値にスケーリングし、自動スケーリングを停止するよう指定します。

3.6.2. スケーリングされたオブジェクトのカスタムメトリクスオートスケーラーの再開

一時停止されたカスタムメトリクスオートスケーラーを再開するには、その ScaledObjectautoscaling.keda.sh/paused-replicas アノテーションを削除します。

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  annotations:
    autoscaling.keda.sh/paused-replicas: "4"
# ...

手順

  1. 次のコマンドを使用して、ワークロードの ScaledObject CR を編集します。

    $ oc edit ScaledObject scaledobject
  2. autoscaling.keda.sh/paused-replicas アノテーションを削除します。

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      annotations:
        autoscaling.keda.sh/paused-replicas: "4" 1
      creationTimestamp: "2023-02-08T14:41:01Z"
      generation: 1
      name: scaledobject
      namespace: my-project
      resourceVersion: '65729'
      uid: f5aec682-acdf-4232-a783-58b5b82f5dd0
    1
    このアノテーションを削除して、一時停止されたカスタムメトリクスオートスケーラーを再開します。

3.7. 監査ログの収集

システムに影響を与えた一連のアクティビティーを個別のユーザー、管理者その他システムのコンポーネント別に記述したセキュリティー関連の時系列のレコードを提供する、監査ログを収集できます。

たとえば、監査ログは、自動スケーリングリクエストの送信元を理解するのに役立ちます。これは、ユーザーアプリケーションによる自動スケーリングリクエストによってバックエンドが過負荷になり、問題のあるアプリケーションを特定する必要がある場合に重要な情報です。

3.7.1. 監査ログの設定

KedaController カスタムリソースを編集することで、Custom Metrics Autoscaler Operator の監査を設定できます。ログは、KedaController CR の永続ボリューム要求を使用して保護されたボリューム上の監査ログファイルに送信されます。

前提条件

  • Custom Metrics Autoscaler Operator をインストールしている。

手順

  1. KedaController カスタムリソースを編集して、auditConfig スタンザを追加します。

    kind: KedaController
    apiVersion: keda.sh/v1alpha1
    metadata:
      name: keda
      namespace: openshift-keda
    spec:
    # ...
      metricsServer:
    # ...
        auditConfig:
          logFormat: "json" 1
          logOutputVolumeClaim: "pvc-audit-log" 2
          policy:
            rules: 3
            - level: Metadata
            omitStages: "RequestReceived" 4
            omitManagedFields: false 5
          lifetime: 6
            maxAge: "2"
            maxBackup: "1"
            maxSize: "50"
    1
    監査ログの出力形式を legacy または json のいずれかで指定します。
    2
    ログデータを格納するための既存の永続ボリューム要求を指定します。API サーバーに送信されるすべてのリクエストは、この永続ボリューム要求に記録されます。このフィールドを空のままにすると、ログデータは stdout に送信されます。
    3
    どのイベントを記録し、どのデータを含めるかを指定します。
    • None: イベントをログに記録しません。
    • Metadata: ユーザー、タイムスタンプなど、リクエストのメタデータのみをログに記録します。リクエストテキストと応答テキストはログに記録しないでください。これはデフォルトになります。
    • Request: メタデータと要求テキストのみをログに記録しますが、応答テキストはログに記録しません。このオプションは、リソース以外の要求には適用されません。
    • RequestResponse: イベントのメタデータ、要求テキスト、および応答テキストをログに記録します。このオプションは、リソース以外の要求には適用されません。
    4
    イベントを作成しないステージを指定します。
    5
    リクエストおよび応答本文のマネージドフィールドが API 監査ログに書き込まれないようにするかどうかを指定します。フィールドを省略する場合は true、フィールドを含める場合は false を指定します。
    6
    監査ログのサイズと有効期間を指定します。
    • maxAge: ファイル名にエンコードされたタイムスタンプに基づく、監査ログファイルを保持する最大日数。
    • maxBackup: 保持する監査ログファイルの最大数。すべての監査ログファイルを保持するには、0 に設定します。
    • maxSize: ローテーションされる前の監査ログファイルの最大サイズ (メガバイト単位)。

検証

  1. 監査ログファイルを直接表示します。

    1. keda-metrics-apiserver-* Pod の名前を取得します。

      oc get pod -n openshift-keda

      出力例

      NAME                                                  READY   STATUS    RESTARTS   AGE
      custom-metrics-autoscaler-operator-5cb44cd75d-9v4lv   1/1     Running   0          8m20s
      keda-metrics-apiserver-65c7cc44fd-rrl4r               1/1     Running   0          2m55s
      keda-operator-776cbb6768-zpj5b                        1/1     Running   0          2m55s

    2. 次のようなコマンドを使用して、ログデータを表示します。

      $ oc logs keda-metrics-apiserver-<hash>|grep -i metadata 1
      1
      オプション: grep コマンドを使用して、表示するログレベル (MetadataRequestRequestResponse) を指定できます。

      以下に例を示します。

      $ oc logs keda-metrics-apiserver-65c7cc44fd-rrl4r|grep -i metadata

      出力例

       ...
      {"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"4c81d41b-3dab-4675-90ce-20b87ce24013","stage":"ResponseComplete","requestURI":"/healthz","verb":"get","user":{"username":"system:anonymous","groups":["system:unauthenticated"]},"sourceIPs":["10.131.0.1"],"userAgent":"kube-probe/1.27","responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2023-02-16T13:00:03.554567Z","stageTimestamp":"2023-02-16T13:00:03.555032Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":""}}
       ...

  2. または、特定のログを表示できます。

    1. 次のようなコマンドを使用して、keda-metrics-apiserver-* Pod にログインします。

      $ oc rsh pod/keda-metrics-apiserver-<hash> -n openshift-keda

      以下に例を示します。

      $ oc rsh pod/keda-metrics-apiserver-65c7cc44fd-rrl4r -n openshift-keda
    2. /var/audit-policy/ ディレクトリーに移動します。

      sh-4.4$ cd /var/audit-policy/
    3. 利用可能なログを一覧表示します。

      sh-4.4$ ls

      出力例

      log-2023.02.17-14:50  policy.yaml

    4. 必要に応じてログを表示します。

      sh-4.4$ cat <log_name>/<pvc_name>|grep -i <log_level> 1
      1
      オプション: grep コマンドを使用して、表示するログレベル (MetadataRequestRequestResponse) を指定できます。

      以下に例を示します。

      sh-4.4$ cat log-2023.02.17-14:50/pvc-audit-log|grep -i Request

      出力例

       ...
      {"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Request","auditID":"63e7f68c-04ec-4f4d-8749-bf1656572a41","stage":"ResponseComplete","requestURI":"/openapi/v2","verb":"get","user":{"username":"system:aggregator","groups":["system:authenticated"]},"sourceIPs":["10.128.0.1"],"responseStatus":{"metadata":{},"code":304},"requestReceivedTimestamp":"2023-02-17T13:12:55.035478Z","stageTimestamp":"2023-02-17T13:12:55.038346Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"system:discovery\" of ClusterRole \"system:discovery\" to Group \"system:authenticated\""}}
       ...

3.8. デバッグデータの収集

サポートケースを作成する際、ご使用のクラスターのデバッグ情報を Red Hat サポートに提供していただくと Red Hat のサポートに役立ちます。

問題のトラブルシューティングに使用するため、以下の情報を提供してください。

  • must-gather ツールを使用して収集されるデータ。
  • 一意のクラスター ID。

must-gather ツールを使用して、以下を含む Custom Metrics Autoscaler Operator とそのコンポーネントに関するデータを収集できます。

  • openshift-keda namespace とその子オブジェクト。
  • Custom Metric Autoscaler Operator のインストールオブジェクト。
  • Custom Metric Autoscaler Operator の CRD オブジェクト。

3.8.1. デバッグデータの収集

以下のコマンドは、Custom Metrics Autoscaler Operator の must-gather ツールを実行します。

$ oc adm must-gather --image="$(oc get packagemanifests openshift-custom-metrics-autoscaler-operator \
-n openshift-marketplace \
-o jsonpath='{.status.channels[?(@.name=="stable")].currentCSVDesc.annotations.containerImage}')"
注記

標準の OpenShift Container Platform must-gather コマンドである oc adm must-gather は、Custom Metrics Autoscaler Operator データを収集しません。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。
  • OpenShift Container Platform CLI (oc) がインストールされている。

手順

  1. must-gather データを保存するディレクトリーに移動します。

    注記

    クラスターがネットワークが制限された環境を使用している場合、追加の手順を実行する必要があります。ミラーレジストリーに信頼される CA がある場合、まず信頼される CA をクラスターに追加する必要があります。制限されたネットワーク上のすべてのクラスターでは、次のコマンドを実行して、デフォルトの must-gather イメージをイメージストリームとしてインポートする必要があります。

    $ oc import-image is/must-gather -n openshift
  2. 以下のいずれかを実行します。

    • Custom Metrics Autoscaler Operator の must-gather データのみを取得するには、以下のコマンドを使用します。

      $ oc adm must-gather --image="$(oc get packagemanifests openshift-custom-metrics-autoscaler-operator \
      -n openshift-marketplace \
      -o jsonpath='{.status.channels[?(@.name=="stable")].currentCSVDesc.annotations.containerImage}')"

      must-gather コマンドのカスタムイメージは、Operator パッケージマニフェストから直接プルされます。そうすることで、Custom Metric Autoscaler Operator が利用可能なクラスター上で機能します。

    • Custom Metric Autoscaler Operator 情報に加えてデフォルトの must-gather データを収集するには、以下を実行します。

      1. 以下のコマンドを使用して Custom Metrics Autoscaler Operator イメージを取得し、これを環境変数として設定します。

        $ IMAGE="$(oc get packagemanifests openshift-custom-metrics-autoscaler-operator \
          -n openshift-marketplace \
          -o jsonpath='{.status.channels[?(@.name=="stable")].currentCSVDesc.annotations.containerImage}')"
      2. Custom Metrics Autoscaler Operator イメージで oc adm must-gather を使用するには、以下を実行します。

        $ oc adm must-gather --image-stream=openshift/must-gather --image=${IMAGE}

    例3.1 Custom Metric Autoscaler の must-gather 出力例:

    └── openshift-keda
        ├── apps
        │   ├── daemonsets.yaml
        │   ├── deployments.yaml
        │   ├── replicasets.yaml
        │   └── statefulsets.yaml
        ├── apps.openshift.io
        │   └── deploymentconfigs.yaml
        ├── autoscaling
        │   └── horizontalpodautoscalers.yaml
        ├── batch
        │   ├── cronjobs.yaml
        │   └── jobs.yaml
        ├── build.openshift.io
        │   ├── buildconfigs.yaml
        │   └── builds.yaml
        ├── core
        │   ├── configmaps.yaml
        │   ├── endpoints.yaml
        │   ├── events.yaml
        │   ├── persistentvolumeclaims.yaml
        │   ├── pods.yaml
        │   ├── replicationcontrollers.yaml
        │   ├── secrets.yaml
        │   └── services.yaml
        ├── discovery.k8s.io
        │   └── endpointslices.yaml
        ├── image.openshift.io
        │   └── imagestreams.yaml
        ├── k8s.ovn.org
        │   ├── egressfirewalls.yaml
        │   └── egressqoses.yaml
        ├── keda.sh
        │   ├── kedacontrollers
        │   │   └── keda.yaml
        │   ├── scaledobjects
        │   │   └── example-scaledobject.yaml
        │   └── triggerauthentications
        │       └── example-triggerauthentication.yaml
        ├── monitoring.coreos.com
        │   └── servicemonitors.yaml
        ├── networking.k8s.io
        │   └── networkpolicies.yaml
        ├── openshift-keda.yaml
        ├── pods
        │   ├── custom-metrics-autoscaler-operator-58bd9f458-ptgwx
        │   │   ├── custom-metrics-autoscaler-operator
        │   │   │   └── custom-metrics-autoscaler-operator
        │   │   │       └── logs
        │   │   │           ├── current.log
        │   │   │           ├── previous.insecure.log
        │   │   │           └── previous.log
        │   │   └── custom-metrics-autoscaler-operator-58bd9f458-ptgwx.yaml
        │   ├── custom-metrics-autoscaler-operator-58bd9f458-thbsh
        │   │   └── custom-metrics-autoscaler-operator
        │   │       └── custom-metrics-autoscaler-operator
        │   │           └── logs
        │   ├── keda-metrics-apiserver-65c7cc44fd-6wq4g
        │   │   ├── keda-metrics-apiserver
        │   │   │   └── keda-metrics-apiserver
        │   │   │       └── logs
        │   │   │           ├── current.log
        │   │   │           ├── previous.insecure.log
        │   │   │           └── previous.log
        │   │   └── keda-metrics-apiserver-65c7cc44fd-6wq4g.yaml
        │   └── keda-operator-776cbb6768-fb6m5
        │       ├── keda-operator
        │       │   └── keda-operator
        │       │       └── logs
        │       │           ├── current.log
        │       │           ├── previous.insecure.log
        │       │           └── previous.log
        │       └── keda-operator-776cbb6768-fb6m5.yaml
        ├── policy
        │   └── poddisruptionbudgets.yaml
        └── route.openshift.io
            └── routes.yaml
  3. 作業ディレクトリーに作成された must-gather ディレクトリーから圧縮ファイルを作成します。たとえば、Linux オペレーティングシステムを使用するコンピューターで以下のコマンドを実行します。

    $ tar cvaf must-gather.tar.gz must-gather.local.5421342344627712289/ 1
    1
    must-gather-local.5421342344627712289/ を実際のディレクトリー名に置き換えます。
  4. 圧縮ファイルを Red Hat カスタマーポータル で作成したサポートケースに添付します。

3.9. Operator メトリクスの表示

Custom Metrics Autoscaler Operator は、クラスター上のモニタリングコンポーネントからプルした、すぐに使用可能なメトリクスを公開します。Prometheus Query Language (PromQL) を使用してメトリクスをクエリーし、問題を分析および診断できます。コントローラー Pod の再起動時にすべてのメトリクスがリセットされます。

3.9.1. パフォーマンスメトリックへのアクセス

OpenShift Container Platform Web コンソールを使用し、メトリクスにアクセスしてクエリーを実行できます。

手順

  1. OpenShift Container Platform Web コンソールの Administrator パースペクティブを選択します。
  2. ObserveMetrics の順に選択します。
  3. カスタムクエリーを作成するには、PromQL クエリーを Expression フィールドに追加します。
  4. 複数のクエリーを追加するには、Add Query を選択します。
3.9.1.1. 提供される Operator メトリクス

Custom Metrics Autoscaler Operator は、以下のメトリクスを公開します。メトリクスは、OpenShift Container Platform Web コンソールを使用して表示できます。

表3.1 Custom Metric Autoscaler Operator メトリクス
メトリクス名説明

keda_scaler_activity

特定のスケーラーがアクティブか非アクティブかを示します。値が 1 の場合はスケーラーがアクティブであることを示し、値が 0 の場合はスケーラーが非アクティブであることを示します。

keda_scaler_metrics_value

各スケーラーのメトリクスの現在の値。ターゲットの平均を計算する際に Horizontal Pod Autoscaler (HPA) によって使用されます。

keda_scaler_metrics_latency

各スケーラーから現在のメトリクスを取得する際のレイテンシー。

keda_scaler_errors

各スケーラーで発生したエラーの数。

keda_scaler_errors_total

すべてのスケーラーで発生したエラーの合計数。

keda_scaled_object_errors

スケーリングされた各オブジェクトで発生したエラーの数。

keda_resource_totals

各カスタムリソースタイプの各 namespace における Custom Metrics Autoscaler カスタムリソースの合計数。

keda_trigger_totals

トリガータイプごとのトリガー合計数。

Custom Metrics Autoscaler Admission Webhook メトリクス

Custom Metrics Autoscaler Admission Webhook は、以下の Prometheus メトリクスも公開します。

メトリクス名説明

keda_scaled_object_validation_total

スケーリングされたオブジェクトの検証数。

keda_scaled_object_validation_errors

検証エラーの数。

3.10. カスタムメトリクスオートスケーラーの追加方法について

カスタムメトリクスオートスケーラーを追加するには、デプロイメント、ステートフルセット、またはカスタムリソース用の ScaledObject カスタムリソースを作成します。ジョブの ScaledJob カスタムリソースを作成します。

スケーリングするワークロードごとに、スケーリングされたオブジェクトを 1 つだけ作成できます。スケーリングされたオブジェクトと水平 Pod オートスケーラー (HPA) は、同じワークロードで使用できません。

3.10.1. ワークロードへのカスタムメトリクスオートスケーラーの追加

DeploymentStatefulSet、または custom resource オブジェクトによって作成されるワークロード用のカスタムメトリクスオートスケーラーを作成できます。

前提条件

  • Custom Metrics Autoscaler Operator をインストールしている。
  • CPU またはメモリーに基づくスケーリングにカスタムメトリクスオートスケーラーを使用する場合:

    • クラスター管理者は、クラスターメトリクスを適切に設定する必要があります。メトリクスが設定されているかどうかは、oc describe PodMetrics <pod-name> コマンドを使用して判断できます。メトリクスが設定されている場合、出力は以下の Usage の下にある CPU と Memory のように表示されます。

      $ oc describe PodMetrics openshift-kube-scheduler-ip-10-0-135-131.ec2.internal

      出力例

      Name:         openshift-kube-scheduler-ip-10-0-135-131.ec2.internal
      Namespace:    openshift-kube-scheduler
      Labels:       <none>
      Annotations:  <none>
      API Version:  metrics.k8s.io/v1beta1
      Containers:
        Name:  wait-for-host-port
        Usage:
          Memory:  0
        Name:      scheduler
        Usage:
          Cpu:     8m
          Memory:  45440Ki
      Kind:        PodMetrics
      Metadata:
        Creation Timestamp:  2019-05-23T18:47:56Z
        Self Link:           /apis/metrics.k8s.io/v1beta1/namespaces/openshift-kube-scheduler/pods/openshift-kube-scheduler-ip-10-0-135-131.ec2.internal
      Timestamp:             2019-05-23T18:47:56Z
      Window:                1m0s
      Events:                <none>

    • スケーリングするオブジェクトに関連付けられた Pod には、指定されたメモリーと CPU の制限が含まれている必要があります。以下に例を示します。

      Pod 仕様の例

      apiVersion: v1
      kind: Pod
      # ...
      spec:
        containers:
        - name: app
          image: images.my-company.example/app:v4
          resources:
            limits:
              memory: "128Mi"
              cpu: "500m"
      # ...

手順

  1. 以下のような YAML ファイルを作成します。名前 <2>、オブジェクト名 <4>、およびオブジェクトの種類 <5> のみが必要です。

    スケーリングされたオブジェクトの例

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      annotations:
        autoscaling.keda.sh/paused-replicas: "0" 1
      name: scaledobject 2
      namespace: my-namespace
    spec:
      scaleTargetRef:
        apiVersion: apps/v1 3
        name: example-deployment 4
        kind: Deployment 5
        envSourceContainerName: .spec.template.spec.containers[0] 6
      cooldownPeriod:  200 7
      maxReplicaCount: 100 8
      minReplicaCount: 0 9
      metricsServer: 10
        auditConfig:
          logFormat: "json"
          logOutputVolumeClaim: "persistentVolumeClaimName"
          policy:
            rules:
            - level: Metadata
            omitStages: "RequestReceived"
            omitManagedFields: false
          lifetime:
            maxAge: "2"
            maxBackup: "1"
            maxSize: "50"
      fallback: 11
        failureThreshold: 3
        replicas: 6
      pollingInterval: 30 12
      advanced:
        restoreToOriginalReplicaCount: false 13
        horizontalPodAutoscalerConfig:
          name: keda-hpa-scale-down 14
          behavior: 15
            scaleDown:
              stabilizationWindowSeconds: 300
              policies:
              - type: Percent
                value: 100
                periodSeconds: 15
      triggers:
      - type: prometheus 16
        metadata:
          serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9092
          namespace: kedatest
          metricName: http_requests_total
          threshold: '5'
          query: sum(rate(http_requests_total{job="test-app"}[1m]))
          authModes: basic
        authenticationRef: 17
          name: prom-triggerauthentication
          kind: TriggerAuthentication

    1
    オプション: 「ワークロードのカスタムメトリクスオートスケーラーの一時停止」セクションで説明されているように、Custom Metrics Autoscaler Operator がレプリカを指定された値にスケーリングし、自動スケーリングを停止するよう指定します。
    2
    このカスタムメトリクスオートスケーラーの名前を指定します。
    3
    オプション: ターゲットリソースの API バージョンを指定します。デフォルトは apps/v1 です。
    4
    スケーリングするオブジェクトの名前を指定します。
    5
    kindDeploymentStatefulSet または CustomResource として指定します。
    6
    オプション: カスタムメトリクスオートスケーラーがシークレットなどを保持する環境変数を取得する、ターゲットリソース内のコンテナーの名前を指定します。デフォルトは .spec.template.spec.containers[0] です。
    7
    オプション: minReplicaCount0 に設定されている場合、最後のトリガーが報告されてからデプロイメントを 0 にスケールバックするまでの待機時間を秒単位で指定します。デフォルトは 300 です。
    8
    オプション: スケールアップ時のレプリカの最大数を指定します。デフォルトは 100 です。
    9
    オプション: スケールダウン時のレプリカの最小数を指定します。
    10
    オプション: 「監査ログの設定」セクションで説明されているように、監査ログのパラメーターを指定します。
    11
    オプション: failureThreshold パラメーターで定義された回数だけスケーラーがソースからメトリクスを取得できなかった場合に、フォールバックするレプリカの数を指定します。フォールバック動作の詳細は、KEDA のドキュメント を参照してください。
    12
    オプション: 各トリガーをチェックする間隔を秒単位で指定します。デフォルトは 30 です。
    13
    オプション: スケーリングされたオブジェクトが削除された後に、ターゲットリソースを元のレプリカ数にスケールバックするかどうかを指定します。デフォルトは false で、スケーリングされたオブジェクトが削除されたときのレプリカ数をそのまま保持します。
    14
    オプション: Horizontal Pod Autoscaler の名前を指定します。デフォルトは keda-hpa-{scaled-object-name} です。
    15
    オプション: 「スケーリングポリシー」セクションで説明されているように、Pod をスケールアップまたはスケールダウンするレートを制御するために使用するスケーリングポリシーを指定します。
    16
    「カスタムメトリクスオートスケーラートリガーについて」セクションで説明されているように、スケーリングの基準として使用するトリガーを指定します。この例では、OpenShift Container Platform モニタリングを使用します。
    17
    オプション: トリガー認証またはクラスタートリガー認証を指定します。詳細は、関連情報 セクションの カスタムメトリクスオートスケーラー認証について を参照してください。
    • トリガー認証を使用するには、TriggerAuthentication と入力します。これはデフォルトになります。
    • クラスタートリガー認証を使用するには、ClusterTriggerAuthentication と入力します。
  2. 次のコマンドを実行して、カスタムメトリクスオートスケーラーを作成します。

    $ oc create -f <filename>.yaml

検証

  • コマンド出力を表示して、カスタムメトリクスオートスケーラーが作成されたことを確認します。

    $ oc get scaledobject <scaled_object_name>

    出力例

    NAME            SCALETARGETKIND      SCALETARGETNAME        MIN   MAX   TRIGGERS     AUTHENTICATION               READY   ACTIVE   FALLBACK   AGE
    scaledobject    apps/v1.Deployment   example-deployment     0     50    prometheus   prom-triggerauthentication   True    True     True       17s

    出力の次のフィールドに注意してください。

    • TRIGGERS: 使用されているトリガーまたはスケーラーを示します。
    • AUTHENTICATION: 使用されているトリガー認証の名前を示します。
    • READY: スケーリングされたオブジェクトがスケーリングを開始する準備ができているかどうかを示します。

      • True の場合、スケーリングされたオブジェクトの準備は完了しています。
      • False の場合、作成したオブジェクトの 1 つ以上に問題があるため、スケーリングされたオブジェクトの準備は完了していません。
    • ACTIVE: スケーリングが行われているかどうかを示します。

      • True の場合、スケーリングが行われています。
      • False の場合、メトリクスがないか、作成したオブジェクトの 1 つ以上に問題があるため、スケーリングは行われていません。
    • FALLBACK: カスタムメトリクスオートスケーラーがソースからメトリクスを取得できるかどうかを示します。

      • False の場合、カスタムメトリクスオートスケーラーはメトリクスを取得しています。
      • True の場合、メトリクスがないか、作成したオブジェクトの 1 つ以上に問題があるため、カスタムメトリクスオートスケーラーはメトリクスを取得しています。

3.10.2. ジョブへのカスタムメトリックオートスケーラーの追加

任意の Job オブジェクトに対してカスタムメトリックオートスケーラーを作成できます。

重要

スケーリングされたジョブを使用したスケーリングはテクノロジープレビュー機能です。テクノロジープレビュー機能は、Red Hat 製品のサービスレベルアグリーメント (SLA) の対象外であり、機能的に完全ではないことがあります。Red Hat は、実稼働環境でこれらを使用することを推奨していません。テクノロジープレビューの機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。

Red Hat のテクノロジープレビュー機能のサポート範囲に関する詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。

前提条件

  • Custom Metrics Autoscaler Operator をインストールしている。

手順

  1. 以下のような YAML ファイルを作成します。

    kind: ScaledJob
    apiVersion: keda.sh/v1alpha1
    metadata:
      name: scaledjob
      namespace: my-namespace
    spec:
      failedJobsHistoryLimit: 5
      jobTargetRef:
        activeDeadlineSeconds: 600 1
        backoffLimit: 6 2
        parallelism: 1 3
        completions: 1 4
        template:  5
          metadata:
            name: pi
          spec:
            containers:
            - name: pi
              image: perl
              command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      maxReplicaCount: 100 6
      pollingInterval: 30 7
      successfulJobsHistoryLimit: 5 8
      failedJobsHistoryLimit: 5 9
      envSourceContainerName: 10
      rolloutStrategy: gradual 11
      scalingStrategy: 12
        strategy: "custom"
        customScalingQueueLengthDeduction: 1
        customScalingRunningJobPercentage: "0.5"
        pendingPodConditions:
          - "Ready"
          - "PodScheduled"
          - "AnyOtherCustomPodCondition"
        multipleScalersCalculation : "max"
      triggers:
      - type: prometheus 13
        metadata:
          serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9092
          namespace: kedatest
          metricName: http_requests_total
          threshold: '5'
          query: sum(rate(http_requests_total{job="test-app"}[1m]))
          authModes: "bearer"
        authenticationRef: 14
          name: prom-cluster-triggerauthentication
    1
    ジョブを実行できる最大期間を指定します。
    2
    ジョブの再試行回数を指定します。デフォルト値は 6 です。
    3
    オプション: ジョブを並行して実行する Pod レプリカの数を指定します。デフォルトは 1 です。
    • 非並列ジョブの場合は、未設定のままにします。設定されていない場合、デフォルトは 1 になります。
    4
    オプション: ジョブを完了したとマークするために必要な、正常に完了した Pod 数を指定します。
    • 非並列ジョブの場合は、未設定のままにします。設定されていない場合、デフォルトは 1 になります。
    • 固定の完了数を持つ並列ジョブの場合、完了の数を指定します。
    • ワークキューのある並列ジョブでは、未設定のままにします。設定されていない場合、デフォルトは parallelism パラメーターの値になります。
    5
    コントローラーが作成する Pod のテンプレートを指定します。
    6
    オプション: スケールアップ時のレプリカの最大数を指定します。デフォルトは 100 です。
    7
    オプション: 各トリガーをチェックする間隔を秒単位で指定します。デフォルトは 30 です。
    8
    オプション: 保持する必要がある正常に終了したジョブの数を指定します。デフォルトは 100 です。
    9
    オプション: 保持する必要がある失敗したジョブの数を指定します。デフォルトは 100 です。
    10
    オプション: カスタムオートスケーラーがシークレットなどを保持する環境変数を取得するターゲットリソース内のコンテナーの名前を指定します。デフォルトは .spec.template.spec.containers[0] です。
    11
    オプション: スケーリングされたジョブが更新されるたびに、既存のジョブを終了するかどうかを指定します。
    • default: 関連する scaled job が更新された場合、オートスケーラーは既存のジョブを終了します。オートスケーラーは、最新の仕様でジョブを再作成します。
    • gradual: 関連する scaled job が更新された場合、オートスケーラーは既存のジョブを終了しません。オートスケーラーは、最新の仕様で新しいジョブを作成します。
    12
    オプション: スケーリングストラテジーを指定します: defaultcustom、または accurate。デフォルトは default です。詳細は、以下の「関連情報」セクションのリンクを参照してください。
    13
    「カスタムメトリクスオートスケーラートリガーについて」セクションで説明されているように、スケーリングの基準として使用するトリガーを指定します。
    14
    オプション: トリガー認証またはクラスタートリガー認証を指定します。詳細は、関連情報 セクションの カスタムメトリクスオートスケーラー認証について を参照してください。
    • トリガー認証を使用するには、TriggerAuthentication と入力します。これはデフォルトになります。
    • クラスタートリガー認証を使用するには、ClusterTriggerAuthentication と入力します。
  2. 次のコマンドを実行して、カスタムメトリクスオートスケーラーを作成します。

    $ oc create -f <filename>.yaml

検証

  • コマンド出力を表示して、カスタムメトリクスオートスケーラーが作成されたことを確認します。

    $ oc get scaledjob <scaled_job_name>

    出力例

    NAME        MAX   TRIGGERS     AUTHENTICATION              READY   ACTIVE    AGE
    scaledjob   100   prometheus   prom-triggerauthentication  True    True      8s

    出力の次のフィールドに注意してください。

    • TRIGGERS: 使用されているトリガーまたはスケーラーを示します。
    • AUTHENTICATION: 使用されているトリガー認証の名前を示します。
    • READY: スケーリングされたオブジェクトがスケーリングを開始する準備ができているかどうかを示します。

      • True の場合、スケーリングされたオブジェクトの準備は完了しています。
      • False の場合、作成したオブジェクトの 1 つ以上に問題があるため、スケーリングされたオブジェクトの準備は完了していません。
    • ACTIVE: スケーリングが行われているかどうかを示します。

      • True の場合、スケーリングが行われています。
      • False の場合、メトリクスがないか、作成したオブジェクトの 1 つ以上に問題があるため、スケーリングは行われていません。

3.10.3. 関連情報

3.11. Custom Metrics Autoscaler Operator の削除

OpenShift Container Platform クラスターからカスタムメトリックオートスケーラーを削除できます。Custom Metrics Autoscaler Operator を削除した後、潜在的な問題を回避するために、Operator に関連付けられている他のコンポーネントを削除します。

注記

最初に KedaController カスタムリソース (CR) を削除します。KedaController CR を削除しない場合、openshift-keda プロジェクトを削除すると OpenShift Container Platform がハングする可能性があります。CR を削除する前に Custom Metrics Autoscaler Operator を削除すると、CR を削除することはできません。

3.11.1. Custom Metrics Autoscaler Operator のアンインストール

以下の手順を使用して、OpenShift Container Platform クラスターからカスタムメトリクスオートスケーラーを削除します。

前提条件

  • Custom Metrics Autoscaler Operator をインストールしている。

手順

  1. OpenShift Container Platform Web コンソールで、OperatorsInstalled Operators をクリックします。
  2. openshift-keda プロジェクトに切り替えます。
  3. KedaController カスタムリソースを削除します。

    1. CustomMetricsAutoscaler Operator を見つけて、KedaController タブをクリックします。
    2. カスタムリソースを見つけてから、Delete KedaController をクリックします。
    3. Uninstall をクリックします。
  4. Custom Metrics Autoscaler Operator を削除します。

    1. OperatorsInstalled Operators をクリックします。
    2. CustomMetricsAutoscaler Operator を見つけて Options メニュー kebab をクリックし、Uninstall Operator を選択します。
    3. Uninstall をクリックします。
  5. オプション: OpenShift CLI を使用して、カスタムメトリクスオートスケーラーのコンポーネントを削除します。

    1. カスタムメトリクスオートスケーラーの CRD を削除します。

      • clustertriggerauthentications.keda.sh
      • kedacontrollers.keda.sh
      • scaledjobs.keda.sh
      • scaledobjects.keda.sh
      • triggerauthentications.keda.sh
      $ oc delete crd clustertriggerauthentications.keda.sh kedacontrollers.keda.sh scaledjobs.keda.sh scaledobjects.keda.sh triggerauthentications.keda.sh

      CRD を削除すると、関連付けられたロール、クラスターロール、およびロールバインディングが削除されます。ただし、手動で削除する必要のあるクラスターロールがいくつかあります。

    2. カスタムメトリクスオートスケーラークラスターのロールをリスト表示します。

      $ oc get clusterrole | grep keda.sh
    3. リスト表示されているカスタムメトリクスオートスケーラークラスターのロールを削除します。以下に例を示します。

      $ oc delete clusterrole.keda.sh-v1alpha1-admin
    4. カスタムメトリクスオートスケーラークラスターのロールバインディングをリスト表示します。

      $ oc get clusterrolebinding | grep keda.sh
    5. リスト表示されているカスタムメトリクスオートスケーラークラスターのロールバインディングを削除します。以下に例を示します。

      $ oc delete clusterrolebinding.keda.sh-v1alpha1-admin
  6. カスタムメトリクスオートスケーラーのプロジェクトを削除します。

    $ oc delete project openshift-keda
  7. Cluster Metric Autoscaler Operator を削除します。

    $ oc delete operator/openshift-custom-metrics-autoscaler-operator.openshift-keda

第4章 Pod のノードへの配置の制御 (スケジューリング)

4.1. スケジューラーによる Pod 配置の制御

Pod のスケジューリングは、クラスター内のノードへの新規 Pod の配置を決定する内部プロセスです。

スケジューラーコードは、新規 Pod の作成時にそれらを確認し、それらをホストするのに最も適したノードを識別します。次に、マスター API を使用して Pod のバインディング (Pod とノードのバインディング) を作成します。

デフォルトの Pod スケジューリング
OpenShift Container Platform には、ほとんどのユーザーのニーズに対応するデフォルトスケジューラーが同梱されます。デフォルトスケジューラーは、Pod に最適なノードを判別するために固有のツールとカスタマイズ可能なツールの両方を使用します。
詳細な Pod スケジューリング

新規 Pod の配置場所に対する制御を強化する必要がある場合、OpenShift Container Platform の詳細スケジューリング機能を使用すると、Pod が特定ノード上か、特定の Pod と共に実行されることを要求する (または実行されることが優先される) よう Pod を設定することができます。

以下のスケジューリング機能を使用して、Pod の配置を制御できます。

4.1.1. デフォルトスケジューラーについて

OpenShift Container Platform のデフォルトの Pod スケジューラーは、クラスター内のノードにおける新規 Pod の配置場所を判別します。スケジューラーは Pod からのデータを読み取り、設定されるプロファイルに基づいて適切なノードを見つけます。これは完全に独立した機能であり、スタンドアロンソリューションです。Pod を変更することはなく、Pod を特定ノードに関連付ける Pod のバインディングを作成します。

4.1.1.1. デフォルトスケジューリングについて

既存の汎用スケジューラーはプラットフォームで提供されるデフォルトのスケジューラー エンジン であり、Pod をホストするノードを 3 つの手順で選択します。

ノードのフィルター
利用可能なノードは、指定される制約や要件に基づいてフィルターされます。フィルターは、各ノードで述語またはフィルターというフィルター関数の一覧を使用して実行されます。
フィルターされたノードリストの優先順位付け
優先順位付けは、各ノードに一連の 優先度 または スコアリング 関数を実行することによって行われます。この関数は 0 -10 までのスコアをノードに割り当て、0 は不適切であることを示し、10 は Pod のホストに適していることを示します。スケジューラー設定は、それぞれのスコアリング関数について単純な重み (正の数値) を取ることができます。各スコアリング関数で指定されるノードのスコアは重み (ほとんどのスコアのデフォルトの重みは 1) で乗算され、すべてのスコアで指定されるそれぞれのノードのスコアを追加して組み合わされます。この重み属性は、一部のスコアにより重きを置くようにするなどの目的で管理者によって使用されます。
最適ノードの選択
ノードの並び替えはそれらのスコアに基づいて行われ、最高のスコアを持つノードが Pod をホストするように選択されます。複数のノードに同じ高スコアが付けられている場合、それらのいずれかがランダムに選択されます。

4.1.2. スケジューラーの使用例

OpenShift Container Platform 内でのスケジューリングの重要な使用例として、柔軟なアフィニティーと非アフィニティーポリシーのサポートを挙げることができます。

4.1.2.1. インフラストラクチャーのトポロジーレベル

管理者は、ノードにラベルを指定することで、インフラストラクチャー (ノード) の複数のトポロジーレベルを定義することができます。たとえば、region=r1zone=z1rack=s1 などはそれらの例になります。

これらのラベル名には特別な意味はなく、管理者はそれらのインフラストラクチャーラベルに任意の名前 (例: 都市/建物/部屋) を付けることができます。さらに、管理者はインフラストラクチャートポロジーに任意の数のレベルを定義できます。通常は、(regionszonesracks) などの 3 つのレベルが適切なサイズです。管理者はこれらのレベルのそれぞれにアフィニティーと非アフィニティールールを任意の組み合わせで指定することができます。

4.1.2.2. アフィニティー

管理者は、任意のトポロジーレベルまたは複数のレベルでもアフィニティーを指定できるようにスケジューラーを設定することができます。特定レベルのアフィニティーは、同じサービスに属するすべての Pod が同じレベルに属するノードにスケジュールされることを示します。これは、管理者がピア Pod が地理的に離れ過ぎないようにすることでアプリケーションの待機時間の要件に対応します。同じアフィニティーグループ内で Pod をホストするために利用できるノードがない場合、Pod はスケジュールされません。

Pod がスケジュールされる場所をより詳細に制御する必要がある場合は、ノードアフィニティールールを使用したノードでの Pod 配置の制御 および アフィニティールールと非アフィニティールールを使用した他の Pod に対する相対的な Pod の配置 を参照してください。

これらの高度なスケジュール機能を使うと、管理者は Pod をスケジュールするノードを指定でき、他の Pod との比較でスケジューリングを実行したり、拒否したりすることができます。

4.1.2.3. アンチアフィニティー

管理者は、任意のトポロジーレベルまたは複数のレベルでもアンチアフィニティーを設定できるようスケジューラーを設定することができます。特定レベルのアンチアフィニティー (または '分散') は、同じサービスに属するすべての Pod が該当レベルに属するノード全体に分散されることを示します。これにより、アプリケーションが高可用性の目的で適正に分散されます。スケジューラーは、可能な限り均等になるようにすべての適用可能なノード全体にサービス Pod を配置しようとします。

Pod がスケジュールされる場所をより詳細に制御する必要がある場合は、ノードアフィニティールールを使用したノードでの Pod 配置の制御 および アフィニティールールと非アフィニティールールを使用した他の Pod に対する相対的な Pod の配置 を参照してください。

これらの高度なスケジュール機能を使うと、管理者は Pod をスケジュールするノードを指定でき、他の Pod との比較でスケジューリングを実行したり、拒否したりすることができます。

4.2. スケジューラープロファイルを使用した Pod のスケジューリング

OpenShift Container Platform は、スケジューリングプロファイルを使用して Pod をクラスター内のノードにスケジュールするように設定できます。

4.2.1. スケジューラープロファイルについて

スケジューラープロファイルを指定して、Pod をノードにスケジュールする方法を制御できます。

以下のスケジューラープロファイルを利用できます。

LowNodeUtilization
このプロファイルは、ノードごとのリソースの使用量を減らすためにノード間で Pod を均等に分散しようとします。このプロファイルは、デフォルトのスケジューラー動作を提供します。
HighNodeUtilization
このプロファイルは、できるだけ少ないノードにできるだけ多くの Pod を配置することを試行します。これによりノード数が最小限に抑えられ、ノードごとのリソースの使用率が高くなります。
NoScoring
これは、すべての score プラグインを無効にして最速のスケジューリングサイクルを目指す低レイテンシープロファイルです。これにより、スケジューリングの高速化がスケジューリングにおける意思決定の質に対して優先されます。

4.2.2. スケジューラープロファイルの設定

スケジューラーがスケジューラープロファイルを使用するように設定できます。

前提条件

  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。

手順

  1. Scheduler オブジェクトを編集します。

    $ oc edit scheduler cluster
  2. spec.profile フィールドで使用するプロファイルを指定します。

    apiVersion: config.openshift.io/v1
    kind: Scheduler
    metadata:
      name: cluster
    #...
    spec:
      mastersSchedulable: false
      profile: HighNodeUtilization 1
    #...
    1
    LowNodeUtilizationHighNodeUtilization、または NoScoring に設定されます。
  3. 変更を適用するためにファイルを保存します。

4.3. アフィニティールールと非アフィニティールールの使用による他の Pod との相対での Pod の配置

アフィニティーとは、スケジュールするノードを制御する Pod の特性です。非アフィニティーとは、Pod がスケジュールされることを拒否する Pod の特性です。

OpenShift Container Platform では、Pod のアフィニティーPod の非アフィニティー によって、他の Pod のキー/値ラベルに基づいて、Pod のスケジュールに適したノードを制限できます。

4.3.1. Pod のアフィニティーについて

Pod のアフィニティーPod の非アフィニティー によって、他の Pod のキー/値ラベルに基づいて、Pod をスケジュールすることに適したノードを制限することができます。

  • Pod のアフィニティーはスケジューラーに対し、新規 Pod のラベルセレクターが現在の Pod のラベルに一致する場合に他の Pod と同じノードで新規 Pod を見つけるように指示します。
  • Pod の非アフィニティーは、新規 Pod のラベルセレクターが現在の Pod のラベルに一致する場合に、同じラベルを持つ Pod と同じノードで新規 Pod を見つけることを禁止します。

たとえば、アフィニティールールを使用することで、サービス内で、または他のサービスの Pod との関連で Pod を分散したり、パックしたりすることができます。非アフィニティールールにより、特定のサービスの Pod がそののサービスの Pod のパフォーマンスに干渉すると見なされる別のサービスの Pod と同じノードでスケジュールされることを防ぐことができます。または、関連する障害を減らすために複数のノード、アベイラビリティーゾーン、またはアベイラビリティーセットの間でサービスの Pod を分散することもできます。

注記

ラベルセレクターは、複数の Pod デプロイメントを持つ Pod に一致する可能性があります。非アフィニティールールを設定して Pod が一致しないようにする場合は、一意のラベル組み合わせを使用します。

Pod のアフィニティーには、required (必須) および preferred (優先) の 2 つのタイプがあります。

Pod をノードにスケジュールする前に、required (必須) ルールを 満たしている必要があります。preferred (優先) ルールは、ルールを満たす場合に、スケジューラーはルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。

注記

Pod の優先順位およびプリエンプションの設定により、スケジューラーはアフィニティーの要件に違反しなければ Pod の適切なノードを見つけられない可能性があります。その場合、Pod はスケジュールされない可能性があります。

この状態を防ぐには、優先順位が等しい Pod との Pod のアフィニティーの設定を慎重に行ってください。

Pod のアフィニティー/非アフィニティーは Pod 仕様ファイルで設定します。required (必須) ルール、preferred (優先) ルールのいずれか、その両方を指定することができます。両方を指定する場合、ノードは最初に required (必須) ルールを満たす必要があり、その後に preferred (優先) ルールを満たそうとします。

以下の例は、Pod のアフィニティーおよび非アフィニティーに設定される Pod 仕様を示しています。

この例では、Pod のアフィニティールールは、ノードにキー security と値 S1 を持つラベルの付いた 1 つ以上の Pod がすでに実行されている場合にのみ Pod をノードにスケジュールできることを示しています。Pod の非アフィニティールールは、ノードがキー security と値 S2 を持つラベルが付いた Pod がすでに実行されている場合は Pod をノードにスケジュールしないように設定することを示しています。

Pod のアフィニティーが設定された Pod 設定ファイルのサンプル

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity: 1
      requiredDuringSchedulingIgnoredDuringExecution: 2
      - labelSelector:
          matchExpressions:
          - key: security 3
            operator: In 4
            values:
            - S1 5
        topologyKey: topology.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: docker.io/ocpqe/hello-pod

1
Pod のアフィニティーを設定するためのスタンザです。
2
required (必須) ルールを定義します。
3 5
ルールを適用するために一致している必要のあるキーと値 (ラベル) です。
4
演算子は、既存 Pod のラベルと新規 Pod の仕様の matchExpression パラメーターの値のセットの間の関係を表します。これには InNotInExists、または DoesNotExist のいずれかを使用できます。

Pod の非アフィニティーが設定された Pod 設定ファイルのサンプル

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-antiaffinity
spec:
  affinity:
    podAntiAffinity: 1
      preferredDuringSchedulingIgnoredDuringExecution: 2
      - weight: 100  3
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security 4
              operator: In 5
              values:
              - S2
          topologyKey: kubernetes.io/hostname
  containers:
  - name: with-pod-affinity
    image: docker.io/ocpqe/hello-pod

1
Pod の非アフィニティーを設定するためのスタンザです。
2
preferred (優先) ルールを定義します。
3
preferred (優先) ルールの重みを指定します。最も高い重みを持つノードが優先されます。
4
非アフィニティールールが適用される時を決定する Pod ラベルの説明です。ラベルのキーおよび値を指定します。
5
演算子は、既存 Pod のラベルと新規 Pod の仕様の matchExpression パラメーターの値のセットの間の関係を表します。これには InNotInExists、または DoesNotExist のいずれかを使用できます。
注記

ノードのラベルに、Pod のノードのアフィニティールールを満たさなくなるような結果になる変更がランタイム時に生じる場合も、Pod はノードで引き続き実行されます。

4.3.2. Pod アフィニティールールの設定

以下の手順は、ラベルの付いた Pod と Pod のスケジュールを可能にするアフィニティーを使用する Pod を作成する 2 つの Pod の単純な設定を示しています。

注記

アフィニティーをスケジュールされた Pod に直接追加することはできません。

手順

  1. Pod 仕様の特定のラベルの付いた Pod を作成します。

    1. 以下の内容を含む YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: security-s1
        labels:
          security: S1
      spec:
        containers:
        - name: security-s1
          image: docker.io/ocpqe/hello-pod
    2. Pod を作成します。

      $ oc create -f <pod-spec>.yaml
  2. 他の Pod の作成時に、以下のパラメーターを設定してアフィニティーを追加します。

    1. 以下の内容を含む YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: security-s1-east
      #...
      spec
        affinity 1
          podAffinity:
            requiredDuringSchedulingIgnoredDuringExecution: 2
            - labelSelector:
                matchExpressions:
                - key: security 3
                  values:
                  - S1
                  operator: In 4
              topologyKey: topology.kubernetes.io/zone 5
      #...
      1
      Pod のアフィニティーを追加します。
      2
      requiredDuringSchedulingIgnoredDuringExecution パラメーターまたは preferredDuringSchedulingIgnoredDuringExecution パラメーターを設定します。
      3
      満たす必要のある key および values を指定します。新規 Pod を他の Pod と共にスケジュールする必要がある場合、最初の Pod のラベルと同じ key および values パラメーターを使用します。
      4
      Operator を指定します。演算子は InNotInExists、または DoesNotExist にすることができます。たとえば、演算子 In を使用してラベルをノードで必要になるようにします。
      5
      topologyKey を指定します。これは、システムがトポロジードメインを表すために使用する事前にデータが設定された Kubernetes ラベル です。
    2. Pod を作成します。

      $ oc create -f <pod-spec>.yaml

4.3.3. Pod 非アフィニティールールの設定

以下の手順は、ラベルの付いた Pod と Pod のスケジュールの禁止を試行する非アフィニティーの preferred (優先) ルールを使用する Pod を作成する 2 つの Pod の単純な設定を示しています。

注記

アフィニティーをスケジュールされた Pod に直接追加することはできません。

手順

  1. Pod 仕様の特定のラベルの付いた Pod を作成します。

    1. 以下の内容を含む YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: security-s1
        labels:
          security: S1
      spec:
        containers:
        - name: security-s1
          image: docker.io/ocpqe/hello-pod
    2. Pod を作成します。

      $ oc create -f <pod-spec>.yaml
  2. 他の Pod の作成時に、以下のパラメーターを設定します。

    1. 以下の内容を含む YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: security-s2-east
      #...
      spec
        affinity 1
          podAntiAffinity:
            preferredDuringSchedulingIgnoredDuringExecution: 2
            - weight: 100 3
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                  - key: security 4
                    values:
                    - S1
                    operator: In 5
                topologyKey: kubernetes.io/hostname 6
      #...
      1
      Pod の非アフィニティーを追加します。
      2
      requiredDuringSchedulingIgnoredDuringExecution パラメーターまたは preferredDuringSchedulingIgnoredDuringExecution パラメーターを設定します。
      3
      優先ルールの場合、ノードの重みを 1 ~ 100 で指定します。最も高い重みを持つノードが優先されます。
      4
      満たす必要のある key および values を指定します。新規 Pod を他の Pod と共にスケジュールされないようにする必要がある場合、最初の Pod のラベルと同じ key および values パラメーターを使用します。
      5
      Operator を指定します。演算子は InNotInExists、または DoesNotExist にすることができます。たとえば、演算子 In を使用してラベルをノードで必要になるようにします。
      6
      topologyKey を指定します。これは、システムがトポロジードメインを表すために使用する事前にデータが設定された Kubernetes ラベル です。
    2. Pod を作成します。

      $ oc create -f <pod-spec>.yaml

4.3.4. Pod のアフィニティールールと非アフィニティールールの例

以下の例は、Pod のアフィニティーおよび非アフィニティーについて示しています。

4.3.4.1. Pod のアフィニティー

以下の例は、一致するラベルとラベルセレクターを持つ Pod に関する Pod のアフィニティーを示しています。

  • Pod team4 にはラベル team:4 が付けられています。

    apiVersion: v1
    kind: Pod
    metadata:
      name: team4
      labels:
         team: "4"
    #...
    spec:
      containers:
      - name: ocp
        image: docker.io/ocpqe/hello-pod
    #...
  • Pod team4a には、podAffinity の下にラベルセレクター team:4 が付けられています。

    apiVersion: v1
    kind: Pod
    metadata:
      name: team4a
    #...
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: team
                operator: In
                values:
                - "4"
            topologyKey: kubernetes.io/hostname
      containers:
      - name: pod-affinity
        image: docker.io/ocpqe/hello-pod
    #...
  • team4a Pod は team4 Pod と同じノードにスケジュールされます。
4.3.4.2. Pod の非アフィニティー

以下の例は、一致するラベルとラベルセレクターを持つ Pod に関する Pod の非アフィニティーを示しています。

  • Pod pod-s1 にはラベル security:s1 が付けられています。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s1
      labels:
        security: s1
    #...
    spec:
      containers:
      - name: ocp
        image: docker.io/ocpqe/hello-pod
    #...
  • Pod pod-s2 には、podAntiAffinity の下にラベルセレクター security:s1 が付けられています。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s2
    #...
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: security
                operator: In
                values:
                - s1
            topologyKey: kubernetes.io/hostname
      containers:
      - name: pod-antiaffinity
        image: docker.io/ocpqe/hello-pod
    #...
  • Pod pod-s2pod-s1 と同じノードにスケジュールできません。
4.3.4.3. 一致するラベルのない Pod のアフィニティー

以下の例は、一致するラベルとラベルセレクターのない Pod に関する Pod のアフィニティーを示しています。

  • Pod pod-s1 にはラベル security:s1 が付けられています。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s1
      labels:
        security: s1
    #...
    spec:
      containers:
      - name: ocp
        image: docker.io/ocpqe/hello-pod
    #...
  • Pod pod-s2 にはラベルセレクター security:s2 があります。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s2
    #...
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: security
                operator: In
                values:
                - s2
            topologyKey: kubernetes.io/hostname
      containers:
      - name: pod-affinity
        image: docker.io/ocpqe/hello-pod
    #...
  • Pod pod-s2 は、security:s2 ラベルの付いた Pod を持つノードがない場合はスケジュールされません。そのラベルの付いた他の Pod がない場合、新規 Pod は保留状態のままになります。

    出力例

    NAME      READY     STATUS    RESTARTS   AGE       IP        NODE
    pod-s2    0/1       Pending   0          32s       <none>

4.3.5. Pod のアフィニティーと非アフィニティーを使用して、Operator がインストールされている場所を制御する

デフォルトでは、Operator をインストールすると、OpenShift Container Platform は Operator Pod をワーカーノードの 1 つにランダムにインストールします。ただし、特定のノードまたはノードのセットでその Pod をスケジュールする必要がある場合があります。

以下の例では、Operator Pod を特定のノードまたはノードのセットにスケジュールする状況を説明します。

  • Operator が amd64arm64 などの特定のプラットフォームを必要とする場合
  • オペレータが Linux や Windows などの特定のオペレーティングシステムを必要とする場合
  • 同じホストまたは同じラックに配置されたホストでスケジュールされた一緒に動作する Operator が必要な場合
  • ネットワークまたはハードウェアの問題によるダウンタイムを回避するために、Operator をインフラストラクチャー全体に分散させたい場合

Operator の サブスクリプション オブジェクトに Pod アフィニティーまたは非アフィニティーを追加することで、Operator Pod がインストールされる場所を制御できます。

次の例は、Pod の非アフィニティーを使用して、特定のラベルを持つ Pod を持つノードから Custom Metrics Autoscaler Operator がインストールされないようにする方法を示しています。

Operator Pod を 1 つ以上の特定のノードに配置する Pod アフィニティーの例

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: openshift-custom-metrics-autoscaler-operator
  namespace: openshift-keda
spec:
  name: my-package
  source: my-operators
  sourceNamespace: operator-registries
  config:
    affinity:
      podAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - test
          topologyKey: kubernetes.io/hostname
#...

1
app=test ラベルを持つ Pod を持つノードに Operator の Pod を配置する Pod アフィニティー。

Operator Pod が 1 つ以上の特定のノードからアクセスできないようにする Pod 非アフィニティーの例

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: openshift-custom-metrics-autoscaler-operator
  namespace: openshift-keda
spec:
  name: my-package
  source: my-operators
  sourceNamespace: operator-registries
  config:
    affinity:
      podAntiAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: cpu
              operator: In
              values:
              - high
          topologyKey: kubernetes.io/hostname
#...

1
Operator の Pod が cpu=high ラベルの Pod を持つノードでスケジュールされないようにする Pod 非アフィニティー。

手順

Operator Pod の配置を制御するには、次の手順を実行します。

  1. 通常どおり Operator をインストールします。
  2. 必要に応じて、ノードがアフィニティーに適切に応答するようにラベル付けされていることを確認してください。
  3. Operator Subscription オブジェクトを編集してアフィニティーを追加します。
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: openshift-custom-metrics-autoscaler-operator
  namespace: openshift-keda
spec:
  name: my-package
  source: my-operators
  sourceNamespace: operator-registries
  config:
    affinity:
      podAntiAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
          podAffinityTerm:
            labelSelector:
              matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - ip-10-0-185-229.ec2.internal
            topologyKey: topology.kubernetes.io/zone
#...
1
podAffinity または podAntiAffinity を追加します。

検証

  • Pod が特定のノードにデプロイされていることを確認するには、次のコマンドを実行します。

    $ oc get pods -o wide

    出力例

    NAME                                                  READY   STATUS    RESTARTS   AGE   IP            NODE                           NOMINATED NODE   READINESS GATES
    custom-metrics-autoscaler-operator-5dcc45d656-bhshg   1/1     Running   0          50s   10.131.0.20   ip-10-0-185-229.ec2.internal   <none>           <none>

4.4. ノードのアフィニティールールを使用したノード上での Pod 配置の制御

アフィニティーとは、スケジュールするノードを制御する Pod の特性です。

OpenShift Container Platformnode では、アフィニティーとはスケジューラーが Pod を配置する場所を決定するために使用する一連のルールのことです。このルールは、ノードのカスタムラベルと Pod で指定されたラベルセレクターを使用して定義されます。

4.4.1. ノードのアフィニティーについて

ノードのアフィニティーにより、Pod がその配置に使用できるノードのグループに対してアフィニティーを指定できます。ノード自体は配置に対して制御を行いません。

たとえば、Pod を特定の CPU を搭載したノードまたは特定のアベイラビリティーゾーンにあるノードでのみ実行されるよう設定することができます。

ノードのアフィニティールールには、required (必須) および preferred (優先) の 2 つのタイプがあります。

Pod をノードにスケジュールする前に、required (必須) ルールを 満たしている必要があります。preferred (優先) ルールは、ルールを満たす場合に、スケジューラーはルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。

注記

ランタイム時にノードのラベルに変更が生じ、その変更により Pod でのノードのアフィニティールールを満たさなくなる状態が生じるでも、Pod はノードで引き続き実行されます。

ノードのアフィニティーは Pod 仕様ファイルで設定します。required (必須) ルール、preferred (優先) ルールのいずれか、その両方を指定することができます。両方を指定する場合、ノードは最初に required (必須) ルールを満たす必要があり、その後に preferred (優先) ルールを満たそうとします。

以下の例は、Pod をキーが e2e-az-NorthSouth で、その値が e2e-az-North または e2e-az-South のいずれかであるラベルの付いたノードに Pod を配置することを求めるルールが設定された Pod 仕様です。

ノードのアフィニティーの required (必須) ルールが設定された Pod 設定ファイルのサンプル

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity: 1
      requiredDuringSchedulingIgnoredDuringExecution: 2
        nodeSelectorTerms:
        - matchExpressions:
          - key: e2e-az-NorthSouth 3
            operator: In 4
            values:
            - e2e-az-North 5
            - e2e-az-South 6
  containers:
  - name: with-node-affinity
    image: docker.io/ocpqe/hello-pod
#...

1
ノードのアフィニティーを設定するためのスタンザです。
2
required (必須) ルールを定義します。
3 5 6
ルールを適用するために一致している必要のあるキー/値のペア (ラベル) です。
4
演算子は、ノードのラベルと Pod 仕様の matchExpression パラメーターの値のセットの間の関係を表します。この値は、InNotInExists、または DoesNotExistLt、または Gt にすることができます。

以下の例は、キーが e2e-az-EastWest で、その値が e2e-az-East または e2e-az-West のラベルが付いたノードに Pod を配置すること優先する preferred (優先) ルールが設定されたノード仕様です。

ノードのアフィニティーの preferred (優先) ルールが設定された Pod 設定ファイルのサンプル

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity: 1
      preferredDuringSchedulingIgnoredDuringExecution: 2
      - weight: 1 3
        preference:
          matchExpressions:
          - key: e2e-az-EastWest 4
            operator: In 5
            values:
            - e2e-az-East 6
            - e2e-az-West 7
  containers:
  - name: with-node-affinity
    image: docker.io/ocpqe/hello-pod
#...

1
ノードのアフィニティーを設定するためのスタンザです。
2
preferred (優先) ルールを定義します。
3
preferred (優先) ルールの重みを指定します。最も高い重みを持つノードが優先されます。
4 6 7
ルールを適用するために一致している必要のあるキー/値のペア (ラベル) です。
5
演算子は、ノードのラベルと Pod 仕様の matchExpression パラメーターの値のセットの間の関係を表します。この値は、InNotInExists、または DoesNotExistLt、または Gt にすることができます。

ノードの非アフィニティー に関する明示的な概念はありませんが、NotIn または DoesNotExist 演算子を使用すると、動作が複製されます。

注記

同じ Pod 設定でノードのアフィニティーとノードのセレクターを使用している場合は、以下に注意してください。

  • nodeSelectornodeAffinity の両方を設定する場合、Pod が候補ノードでスケジュールされるにはどちらの条件も満たしている必要があります。
  • nodeAffinity タイプに関連付けられた複数の nodeSelectorTerms を指定する場合、nodeSelectorTerms のいずれかが満たされている場合に Pod をノードにスケジュールすることができます。
  • nodeSelectorTerms に関連付けられた複数の matchExpressions を指定する場合、すべての matchExpressions が満たされている場合にのみ Pod をノードにスケジュールすることができます。

4.4.2. ノードアフィニティーの required (必須) ルールの設定

Pod をノードにスケジュールする前に、required (必須) ルールを 満たしている必要があります

手順

以下の手順は、ノードとスケジューラーがノードに配置する必要のある Pod を作成する単純な設定を示しています。

  1. oc label node コマンドを使用してラベルをノードに追加します。

    $ oc label node node1 e2e-az-name=e2e-az1
    ヒント

    あるいは、以下の YAML を適用してラベルを追加できます。

    kind: Node
    apiVersion: v1
    metadata:
      name: <node_name>
      labels:
        e2e-az-name: e2e-az1
    #...
  2. Pod 仕様の特定のラベルの付いた Pod を作成します。

    1. 以下の内容を含む YAML ファイルを作成します。

      注記

      アフィニティーをスケジュールされた Pod に直接追加することはできません。

      出力例

      apiVersion: v1
      kind: Pod
      metadata:
        name: s1
      spec:
        affinity: 1
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution: 2
              nodeSelectorTerms:
              - matchExpressions:
                - key: e2e-az-name 3
                  values:
                  - e2e-az1
                  - e2e-az2
                  operator: In 4
      #...

      1
      Pod のアフィニティーを追加します。
      2
      requiredDuringSchedulingIgnoredDuringExecution パラメーターを設定します。
      3
      満たす必要のある key および values を指定します。新規 Pod を編集したノードにスケジュールする必要がある場合、ノードのラベルと同じ key および values パラメーターを使用します。
      4
      Operator を指定します。演算子は InNotInExists、または DoesNotExist にすることができます。たとえば、演算子 In を使用してラベルをノードで必要になるようにします。
    2. Pod を作成します。

      $ oc create -f <file-name>.yaml

4.4.3. ノードアフィニティーの preferred (優先) ルールの設定

preferred (優先) ルールは、ルールを満たす場合に、スケジューラーはルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。

手順

以下の手順は、ノードとスケジューラーがノードに配置しようとする Pod を作成する単純な設定を示しています。

  1. oc label node コマンドを使用してラベルをノードに追加します。

    $ oc label node node1 e2e-az-name=e2e-az3
  2. 特定のラベルの付いた Pod を作成します。

    1. 以下の内容を含む YAML ファイルを作成します。

      注記

      アフィニティーをスケジュールされた Pod に直接追加することはできません。

      apiVersion: v1
      kind: Pod
      metadata:
        name: s1
      spec:
        affinity: 1
          nodeAffinity:
            preferredDuringSchedulingIgnoredDuringExecution: 2
            - weight: 3
              preference:
                matchExpressions:
                - key: e2e-az-name 4
                  values:
                  - e2e-az3
                  operator: In 5
      #...
      1
      Pod のアフィニティーを追加します。
      2
      preferredDuringSchedulingIgnoredDuringExecution パラメーターを設定します。
      3
      ノードの重みを数字の 1-100 で指定します。最も高い重みを持つノードが優先されます。
      4
      満たす必要のある key および values を指定します。新規 Pod を編集したノードにスケジュールする必要がある場合、ノードのラベルと同じ key および values パラメーターを使用します。
      5
      Operator を指定します。演算子は InNotInExists、または DoesNotExist にすることができます。たとえば、演算子 In を使用してラベルをノードで必要になるようにします。
    2. Pod を作成します。

      $ oc create -f <file-name>.yaml

4.4.4. ノードのアフィニティールールの例

以下の例は、ノードのアフィニティーを示しています。

4.4.4.1. 一致するラベルを持つノードのアフィニティー

以下の例は、一致するラベルを持つノードと Pod のノードのアフィニティーを示しています。

  • Node1 ノードにはラベル zone:us があります。

    $ oc label node node1 zone=us
    ヒント

    あるいは、以下の YAML を適用してラベルを追加できます。

    kind: Node
    apiVersion: v1
    metadata:
      name: <node_name>
      labels:
        zone: us
    #...
  • pod-s1 pod にはノードアフィニティーの required (必須) ルールの下に zoneus のキー/値のペアがあります。

    $ cat pod-s1.yaml

    出力例

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s1
    spec:
      containers:
        - image: "docker.io/ocpqe/hello-pod"
          name: hello-pod
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: "zone"
                  operator: In
                  values:
                  - us
    #...

  • pod-s1 pod は Node1 でスケジュールできます。

    $ oc get pod -o wide

    出力例

    NAME     READY     STATUS       RESTARTS   AGE      IP      NODE
    pod-s1   1/1       Running      0          4m       IP1     node1

4.4.4.2. 一致するラベルのないノードのアフィニティー

以下の例は、一致するラベルを持たないノードと Pod のノードのアフィニティーを示しています。

  • Node1 ノードにはラベル zone:emea があります。

    $ oc label node node1 zone=emea
    ヒント

    あるいは、以下の YAML を適用してラベルを追加できます。

    kind: Node
    apiVersion: v1
    metadata:
      name: <node_name>
      labels:
        zone: emea
    #...
  • pod-s1 pod にはノードアフィニティーの required (必須) ルールの下に zoneus のキー/値のペアがあります。

    $ cat pod-s1.yaml

    出力例

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s1
    spec:
      containers:
        - image: "docker.io/ocpqe/hello-pod"
          name: hello-pod
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: "zone"
                  operator: In
                  values:
                  - us
    #...

  • pod-s1 pod は Node1 でスケジュールすることができません。

    $ oc describe pod pod-s1

    出力例

    ...
    
    Events:
     FirstSeen LastSeen Count From              SubObjectPath  Type                Reason
     --------- -------- ----- ----              -------------  --------            ------
     1m        33s      8     default-scheduler Warning        FailedScheduling    No nodes are available that match all of the following predicates:: MatchNodeSelector (1).

4.4.5. ノードアフィニティーを使用して Operator がインストールされる場所を制御する

デフォルトでは、Operator をインストールすると、OpenShift Container Platform は Operator Pod をワーカーノードの 1 つにランダムにインストールします。ただし、特定のノードまたはノードのセットでその Pod をスケジュールする必要がある場合があります。

以下の例では、Operator Pod を特定のノードまたはノードのセットにスケジュールする状況を説明します。

  • Operator が amd64arm64 などの特定のプラットフォームを必要とする場合
  • オペレータが Linux や Windows などの特定のオペレーティングシステムを必要とする場合
  • 同じホストまたは同じラックに配置されたホストでスケジュールされた一緒に動作する Operator が必要な場合
  • ネットワークまたはハードウェアの問題によるダウンタイムを回避するために、Operator をインフラストラクチャー全体に分散させたい場合

Operator の Subscription オブジェクトにノードアフィニティーの制約を追加することで、Operator Pod がインストールされる場所を制御できます。

次の例は、ノードアフィニティーを使用して、Custom Metrics Autoscaler Operator のインスタンスをクラスター内の特定のノードにインストールする方法を示しています。

Operator Pod を特定のノードに配置するノードアフィニティーの例

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: openshift-custom-metrics-autoscaler-operator
  namespace: openshift-keda
spec:
  name: my-package
  source: my-operators
  sourceNamespace: operator-registries
  config:
    affinity:
      nodeAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - ip-10-0-163-94.us-west-2.compute.internal
#...

1
Operator の Pod を ip-10-0-163-94.us-west-2.compute.internal という名前のノードでスケジュールする必要があるノードアフィニティー。

Operator Pod を特定のプラットフォームのノードに配置するノードアフィニティーの例

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: openshift-custom-metrics-autoscaler-operator
  namespace: openshift-keda
spec:
  name: my-package
  source: my-operators
  sourceNamespace: operator-registries
  config:
    affinity:
      nodeAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/arch
              operator: In
              values:
              - arm64
            - key: kubernetes.io/os
              operator: In
              values:
              - linux
#...

1
Operator の Pod を kubernetes.io/arch=arm64 および kubernetes.io/os=linux ラベルを持つノードでスケジュールする必要があるノードアフィニティー。

手順

Operator Pod の配置を制御するには、次の手順を実行します。

  1. 通常どおり Operator をインストールします。
  2. 必要に応じて、ノードがアフィニティーに適切に応答するようにラベル付けされていることを確認してください。
  3. Operator Subscription オブジェクトを編集してアフィニティーを追加します。

    apiVersion: operators.coreos.com/v1alpha1
    kind: Subscription
    metadata:
      name: openshift-custom-metrics-autoscaler-operator
      namespace: openshift-keda
    spec:
      name: my-package
      source: my-operators
      sourceNamespace: operator-registries
      config:
        affinity: 1
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
              - matchExpressions:
                - key: kubernetes.io/hostname
                  operator: In
                  values:
                  - ip-10-0-185-229.ec2.internal
    #...
    1
    nodeAffinity を追加します。

検証

  • Pod が特定のノードにデプロイされていることを確認するには、次のコマンドを実行します。

    $ oc get pods -o wide

    出力例

    NAME                                                  READY   STATUS    RESTARTS   AGE   IP            NODE                           NOMINATED NODE   READINESS GATES
    custom-metrics-autoscaler-operator-5dcc45d656-bhshg   1/1     Running   0          50s   10.131.0.20   ip-10-0-185-229.ec2.internal   <none>           <none>

4.4.6. 関連情報

4.5. Pod のオーバーコミットノードへの配置

オーバーコミット とは、コンテナーの計算リソース要求と制限の合計が、そのシステムで利用できるリソースを超えた状態のことです。オーバーコミットは、容量に対して保証されたパフォーマンスのトレードオフが許容可能である開発環境において、望ましいことがあります。

要求および制限により、管理者はノードでのリソースのオーバーコミットを許可し、管理できます。スケジューラーは、要求を使用してコンテナーをスケジュールし、最小限のサービス保証を提供します。制限は、ノード上で消費されるコンピュートリソースの量を制限します。

4.5.1. オーバーコミットについて

要求および制限により、管理者はノードでのリソースのオーバーコミットを許可し、管理できます。スケジューラーは、要求を使用してコンテナーをスケジュールし、最小限のサービス保証を提供します。制限は、ノード上で消費されるコンピュートリソースの量を制限します。

OpenShift Container Platform 管理者は、開発者がコンテナーで設定された要求と制限の比率を上書きするようマスターを設定することで、オーバーコミットのレベルを制御し、ノードのコンテナー密度を管理します。この設定を、制限とデフォルトを指定するプロジェクトごとの LimitRange と共に使用することで、オーバーコミットを必要なレベルに設定できるようコンテナーの制限と要求を調整することができます。

注記

コンテナーに制限が設定されていない場合には、これらの上書きは影響を与えません。デフォルトの制限で (個別プロジェクトごとに、またはプロジェクトテンプレートを使用して) LimitRange オブジェクトを作成し、上書きが適用されるようにします。

上書き後も、コンテナーの制限および要求は、プロジェクトのいずれかの LimitRange オブジェクトで引き続き検証される必要があります。たとえば、開発者が最小限度に近い制限を指定し、要求を最小限度よりも低い値に上書きすることで、Pod が禁止される可能性があります。この最適でないユーザーエクスペリエンスについては、今後の作業で対応する必要がありますが、現時点ではこの機能および LimitRange オブジェクトを注意して設定してください。

4.5.2. ノードのオーバーコミットについて

オーバーコミット環境では、最適なシステム動作を提供できるようにノードを適切に設定する必要があります。

ノードが起動すると、メモリー管理用のカーネルの調整可能なフラグが適切に設定されます。カーネルは、物理メモリーが不足しない限り、メモリーの割り当てに失敗するこはありません。

この動作を確認するため、OpenShift Container Platform は、vm.overcommit_memory パラメーターを 1 に設定し、デフォルトのオペレーティングシステムの設定を上書きすることで、常にメモリーをオーバーコミットするようにカーネルを設定します。

また、OpenShift Container Platform は vm.panic_on_oom パラメーターを 0 に設定することで、メモリーが不足したときでもカーネルがパニックにならないようにします。0 の設定は、Out of Memory (OOM) 状態のときに oom_killer を呼び出すようカーネルに指示します。これにより、優先順位に基づいてプロセスを強制終了します。

現在の設定は、ノードに以下のコマンドを実行して表示できます。

$ sysctl -a |grep commit

出力例

#...
vm.overcommit_memory = 0
#...

$ sysctl -a |grep panic

出力例

#...
vm.panic_on_oom = 0
#...

注記

上記のフラグはノード上にすでに設定されているはずであるため、追加のアクションは不要です。

各ノードに対して以下の設定を実行することもできます。

  • CPU CFS クォータを使用した CPU 制限の無効化または実行
  • システムプロセスのリソース予約
  • Quality of Service (QoS) 層でのメモリー予約

4.6. ノード taint を使用した Pod 配置の制御

taint および toleration により、ノードはノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。

4.6.1. taint および toleration について

taint により、ノードは Pod に一致する toleration がない場合に Pod のスケジュールを拒否することができます。

taint は Node 仕様 (NodeSpec) でノードに適用され、toleration は Pod 仕様 (PodSpec) で Pod に適用されます。taint をノードに適用する場合、スケジューラーは Pod が taint を容認しない限り、Pod をそのノードに配置することができません。

ノード仕様の taint の例

apiVersion: v1
kind: Node
metadata:
  name: my-node
#...
spec:
  taints:
  - effect: NoExecute
    key: key1
    value: value1
#...

Pod 仕様での toleration の例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
#...
spec:
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoExecute"
    tolerationSeconds: 3600
#...

taint および toleration は、key、value、および effect で構成されます。

表4.1 taint および toleration コンポーネント
パラメーター説明

key

key には、253 文字までの文字列を使用できます。キーは文字または数字で開始する必要があり、文字、数字、ハイフン、ドットおよびアンダースコアを含めることができます。

value

value には、63 文字までの文字列を使用できます。値は文字または数字で開始する必要があり、文字、数字、ハイフン、ドットおよびアンダースコアを含めることができます。

effect

effect は以下のいずれかにすることができます。

NoSchedule [1]

  • taint に一致しない新規 Pod はノードにスケジュールされません。
  • ノードの既存 Pod はそのままになります。

PreferNoSchedule

  • taint に一致しない新規 Pod はノードにスケジュールされる可能性がありますが、スケジューラーはスケジュールしないようにします。
  • ノードの既存 Pod はそのままになります。

NoExecute

  • taint に一致しない新規 Pod はノードにスケジュールできません。
  • 一致する toleration を持たないノードの既存 Pod は削除されます。

operator

Equal

key/value/effect パラメーターは一致する必要があります。これはデフォルトになります。

Exists

key/effect パラメーターは一致する必要があります。いずれかに一致する value パラメーターを空のままにする必要があります。

  1. NoSchedule taint をコントロールプレーンノードに追加すると、ノードには、デフォルトで追加される node-role.kubernetes.io/master=:NoSchedule taint が必要です。

    以下に例を示します。

    apiVersion: v1
    kind: Node
    metadata:
      annotations:
        machine.openshift.io/machine: openshift-machine-api/ci-ln-62s7gtb-f76d1-v8jxv-master-0
        machineconfiguration.openshift.io/currentConfig: rendered-master-cdc1ab7da414629332cc4c3926e6e59c
      name: my-node
    #...
    spec:
      taints:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
    #...

toleration は taint と一致します。

  • operator パラメーターが Equal に設定されている場合:

    • key パラメーターは同じになります。
    • value パラメーターは同じになります。
    • effect パラメーターは同じになります。
  • operator パラメーターが Exists に設定されている場合:

    • key パラメーターは同じになります。
    • effect パラメーターは同じになります。

以下の taint は OpenShift Container Platform に組み込まれています。

  • node.kubernetes.io/not-ready: ノードは準備状態にありません。これはノード条件 Ready=False に対応します。
  • node.kubernetes.io/unreachable: ノードはノードコントローラーから到達不能です。これはノード条件 Ready=Unknown に対応します。
  • node.kubernetes.io/memory-pressure: ノードにはメモリー不足の問題が発生しています。これはノード条件 MemoryPressure=True に対応します。
  • node.kubernetes.io/disk-pressure: ノードにはディスク不足の問題が発生しています。これはノード条件 DiskPressure=True に対応します。
  • node.kubernetes.io/network-unavailable: ノードのネットワークは使用できません。
  • node.kubernetes.io/unschedulable: ノードはスケジュールが行えません。
  • node.cloudprovider.kubernetes.io/uninitialized: ノードコントローラーが外部のクラウドプロバイダーを使用して起動すると、この taint はノード上に設定され、使用不可能とマークされます。cloud-controller-manager のコントローラーがこのノードを初期化した後に、kubelet がこの taint を削除します。
  • node.kubernetes.io/pid-pressure: ノードが pid 不足の状態です。これはノード条件 PIDPressure=True に対応します。

    重要

    OpenShift Container Platform では、デフォルトの pid.available evictionHard は設定されません。

4.6.1.1. Pod のエビクションを遅延させる toleration (秒数) の使用方法

Pod 仕様または MachineSettolerationSeconds パラメーターを指定して、Pod がエビクションされる前にノードにバインドされる期間を指定できます。effect が NoExecute の taint がノードに追加される場合、taint を容認する Pod に tolerationSeconds パラメーターがある場合、Pod は期限切れになるまでエビクトされません。

出力例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
#...
spec:
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoExecute"
    tolerationSeconds: 3600
#...

ここで、この Pod が実行中であるものの、一致する容 toleration がない場合、Pod は 3,600 秒間バインドされたままとなり、その後にエビクトされます。taint が期限前に削除される場合、Pod はエビクトされません。

4.6.1.2. 複数の taint の使用方法

複数の taint を同じノードに、複数の toleration を同じ Pod に配置することができます。OpenShift Container Platform は複数の taint と toleration を以下のように処理します。

  1. Pod に一致する toleration のある taint を処理します。
  2. 残りの一致しないテイン taint は Pod について以下の effect を持ちます。

    • effect が NoSchedule の一致しない taint が 1 つ以上ある場合、OpenShift Container Platform は Pod をノードにスケジュールできません。
    • effect が NoSchedule の一致しない taint がなく、effect が PreferNoSchedule の一致しない taint が 1 つ以上ある場合、OpenShift Container Platform は Pod のノードへのスケジュールを試行しません。
    • effect が NoExecute の taint が 1 つ以上ある場合、OpenShift Container Platform は Pod をノードからエビクトするか (ノードですでに実行中の場合)、または Pod のそのノードへのスケジュールが実行されません (ノードでまだ実行されていない場合)。

      • taint を容認しない Pod はすぐにエビクトされます。
      • Pod の仕様に tolerationSeconds を指定せずに taint を容認する Pod は永久にバインドされたままになります。
      • 指定された tolerationSeconds を持つテイン taint を容認する Pod は指定された期間バインドされます。

以下に例を示します。

  • 以下の taint をノードに追加します。

    $ oc adm taint nodes node1 key1=value1:NoSchedule
    $ oc adm taint nodes node1 key1=value1:NoExecute
    $ oc adm taint nodes node1 key2=value2:NoSchedule
  • Pod には以下の toleration があります。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    #...
    spec:
      tolerations:
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoSchedule"
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoExecute"
    #...

この場合、3 つ目の taint に一致する toleration がないため、Pod はノードにスケジュールできません。Pod はこの taint の追加時にノードですでに実行されている場合は実行が継続されます。3 つ目の taint は 3 つの taint の中で Pod で容認されない唯一の taint であるためです。

4.6.1.3. Pod のスケジューリングとノードの状態 (Taint Nodes By Condition) について

Taint Nodes By Condition (状態別のノードへの taint) 機能はデフォルトで有効にされており、これはメモリー不足やディスク不足などの状態を報告するノードを自動的に taint します。ノードが状態を報告すると、その状態が解消するまで taint が追加されます。taint に NoSchedule の effect がある場合、ノードが一致する toleration を持つまでそのノードに Pod をスケジュールすることはできません。

スケジューラーは、Pod をスケジュールする前に、ノードでこれらの taint の有無をチェックします。taint がある場合、Pod は別のノードにスケジュールされます。スケジューラーは実際のノードの状態ではなく taint をチェックするので、適切な Pod toleration を追加して、スケジューラーがこのようなノードの状態を無視するように設定します。

デーモンセットコントローラーは、以下の toleration をすべてのデーモンに自動的に追加し、下位互換性を確保します。

  • node.kubernetes.io/memory-pressure
  • node.kubernetes.io/disk-pressure
  • node.kubernetes.io/unschedulable (1.10 以降)
  • node.kubernetes.io/network-unavailable (ホストネットワークのみ)

デーモンセットには任意の toleration を追加することも可能です。

注記

コントロールプレーンは、QoS クラスを持つ Pod に node.kubernetes.io/memory-pressure toleration も追加します。これは、Kubernetes が Guaranteed または Burstable QoS クラスで Pod を管理するためです。新しい BestEffort Pod は、影響を受けるノードにスケジュールされません。

4.6.1.4. Pod の状態別エビクションについて (Taint-Based Eviction)

Taint-Based Eviction 機能はデフォルトで有効にされており、これは not-ready および unreachable などの特定の状態にあるノードから Pod をエビクトします。ノードがこうした状態のいずれかになると、OpenShift Container Platform は taint をノードに自動的に追加して、Pod のエビクトおよび別のノードでの再スケジュールを開始します。

Taint Based Eviction には NoExecute の effect があり、その taint を容認しない Pod はすぐにエビクトされ、これを容認する Pod はエビクトされません (Pod が tolerationSeconds パラメーターを使用しない場合に限ります)。

tolerationSeconds パラメーターを使用すると、ノード状態が設定されたノードに Pod がどの程度の期間バインドされるかを指定することができます。tolerationSeconds の期間後もこの状態が続くと、taint はノードに残り続け、一致する toleration を持つ Pod はエビクトされます。tolerationSeconds の期間前にこの状態が解消される場合、一致する toleration を持つ Pod は削除されません。

値なしで tolerationSeconds パラメーターを使用する場合、Pod は not ready(準備未完了) および unreachable(到達不能) のノードの状態が原因となりエビクトされることはありません。

注記

OpenShift Container Platform は、レートが制限された方法で Pod をエビクトし、マスターがノードからパーティション化される場合などのシナリオで発生する大規模な Pod エビクションを防ぎます。

デフォルトでは、特定のゾーン内のノードの 55% 以上が 異常である場合、ノードライフサイクルコントローラーはそのゾーンの状態を PartialDisruption に変更し、Pod の削除率が低下します。この状態の小さなクラスター (デフォルトでは 50 ノード以下) の場合、このゾーンのノードは taint されず、排除が停止されます。

詳細は、Kubernetes ドキュメントの Rate limits on eviction を参照してください。

OpenShift Container Platform は、node.kubernetes.io/not-ready および node.kubernetes.io/unreachable の toleration を、Pod 設定がいずれかの toleration を指定しない限り、自動的に tolerationSeconds=300 に追加します。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
#...
spec:
  tolerations:
  - key: node.kubernetes.io/not-ready
    operator: Exists
    effect: NoExecute
    tolerationSeconds: 300 1
  - key: node.kubernetes.io/unreachable
    operator: Exists
    effect: NoExecute
    tolerationSeconds: 300
#...
1
これらの toleration は、ノード状態の問題のいずれかが検出された後、デフォルトの Pod 動作のバインドを 5 分間維持できるようにします。

これらの toleration は必要に応じて設定できます。たとえば、アプリケーションに多数のローカル状態がある場合、ネットワークのパーティション化などに伴い、Pod をより長い時間ノードにバインドさせる必要があるかもしれません。 これにより、パーティションを回復させることができ、Pod のエビクションを回避できます。

デーモンセットによって起動する Pod は、tolerationSeconds が指定されない以下の taint の NoExecute toleration を使用して作成されます。

  • node.kubernetes.io/unreachable
  • node.kubernetes.io/not-ready

その結果、デーモンセット Pod は、これらのノードの状態が原因でエビクトされることはありません。

4.6.1.5. すべての taint の許容

ノードは、operator: "Exists" toleration を key および value パラメーターなしで追加することですべての taint を容認するように Pod を設定できます。この toleration のある Pod は taint を持つノードから削除されません。

すべての taint を容認するための Pod 仕様

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
#...
spec:
  tolerations:
  - operator: "Exists"
#...

4.6.2. taint および toleration の追加

toleration を Pod に、taint をノードに追加することで、ノードはノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。既存の Pod およびノードの場合、最初に toleration を Pod に追加してから taint をノードに追加して、toleration を追加する前に Pod がノードから削除されないようにする必要があります。

手順

  1. Pod 仕様を tolerations スタンザを含めるように編集して、toleration を Pod に追加します。

    Equal 演算子を含む Pod 設定ファイルのサンプル

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    #...
    spec:
      tolerations:
      - key: "key1" 1
        value: "value1"
        operator: "Equal"
        effect: "NoExecute"
        tolerationSeconds: 3600 2
    #...

    1
    taint および toleration コンポーネント の表で説明されている toleration パラメーターです。
    2
    tolerationSeconds パラメーターは、エビクトする前に Pod をどの程度の期間ノードにバインドさせるかを指定します。

    以下に例を示します。

    Exists 演算子を含む Pod 設定ファイルのサンプル

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    #...
    spec:
       tolerations:
        - key: "key1"
          operator: "Exists" 1
          effect: "NoExecute"
          tolerationSeconds: 3600
    #...

    1
    Exists Operator は value を取りません。

    この例では、taint を、キー key1、値 value1、および taint effect NoExecute を持つ node1 に taint を配置します。

  2. taint および toleration コンポーネント の表で説明されているパラメーターと共に以下のコマンドを使用して taint をノードに追加します。

    $ oc adm taint nodes <node_name> <key>=<value>:<effect>

    以下に例を示します。

    $ oc adm taint nodes node1 key1=value1:NoExecute

    このコマンドは、キー key1、値 value1、および effect NoExecute を持つ taint を node1 に配置します。

    注記

    NoSchedule taint をコントロールプレーンノードに追加すると、ノードには、デフォルトで追加される node-role.kubernetes.io/master=:NoSchedule taint が必要です。

    以下に例を示します。

    apiVersion: v1
    kind: Node
    metadata:
      annotations:
        machine.openshift.io/machine: openshift-machine-api/ci-ln-62s7gtb-f76d1-v8jxv-master-0
        machineconfiguration.openshift.io/currentConfig: rendered-master-cdc1ab7da414629332cc4c3926e6e59c
      name: my-node
    #...
    spec:
      taints:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
    #...

    Pod の toleration はノードの taint に一致します。いずれかの toleration のある Pod は node1 にスケジュールできます。

4.6.2.1. コンピュートマシンセットを使用した taint および toleration の追加

コンピュートマシンセットを使用して taint をノードに追加できます。MachineSet オブジェクトに関連付けられるすべてのノードが taint で更新されます。toleration は、ノードに直接追加された taint と同様に、コンピュートマシンセットによって追加される taint に応答します。

手順

  1. Pod 仕様を tolerations スタンザを含めるように編集して、toleration を Pod に追加します。

    Equal 演算子を含む Pod 設定ファイルのサンプル

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    #...
    spec:
      tolerations:
      - key: "key1" 1
        value: "value1"
        operator: "Equal"
        effect: "NoExecute"
        tolerationSeconds: 3600 2
    #...

    1
    taint および toleration コンポーネント の表で説明されている toleration パラメーターです。
    2
    tolerationSeconds パラメーターは、エビクトする前に Pod をどの程度の期間ノードにバインドさせるかを指定します。

    以下に例を示します。

    Exists 演算子を含む Pod 設定ファイルのサンプル

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    #...
    spec:
      tolerations:
      - key: "key1"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 3600
    #...

  2. taint を MachineSet オブジェクトに追加します。

    1. taint を付けるノードの MachineSet YAML を編集するか、新規 MachineSet オブジェクトを作成できます。

      $ oc edit machineset <machineset>
    2. taint を spec.template.spec セクションに追加します。

      コンピュートマシンセット仕様の taint の例

      apiVersion: machine.openshift.io/v1beta1
      kind: MachineSet
      metadata:
        name: my-machineset
      #...
      spec:
      #...
        template:
      #...
          spec:
            taints:
            - effect: NoExecute
              key: key1
              value: value1
      #...

      この例では、キー key1、値 value1、および taint effect NoExecute を持つ taint をノードに配置します。

    3. コンピュートマシンセットを 0 にスケールダウンします。

      $ oc scale --replicas=0 machineset <machineset> -n openshift-machine-api
      ヒント

      または、以下の YAML を適用してコンピュートマシンセットをスケーリングすることもできます。

      apiVersion: machine.openshift.io/v1beta1
      kind: MachineSet
      metadata:
        name: <machineset>
        namespace: openshift-machine-api
      spec:
        replicas: 0

      マシンが削除されるまで待機します。

    4. コンピュートマシンセットを随時スケールアップします。

      $ oc scale --replicas=2 machineset <machineset> -n openshift-machine-api

      または、以下を実行します。

      $ oc edit machineset <machineset> -n openshift-machine-api

      マシンが起動するまで待ちます。taint は MachineSet オブジェクトに関連付けられたノードに追加されます。

4.6.2.2. taint および toleration 使用してユーザーをノードにバインドする

ノードのセットを特定のユーザーセットによる排他的な使用のために割り当てる必要がある場合、toleration をそれらの Pod に追加します。次に、対応する taint をそれらのノードに追加します。toleration が設定された Pod は、taint が付けられたノードまたはクラスター内の他のノードを使用できます。

Pod が taint が付けられたノードのみにスケジュールされるようにするには、ラベルを同じノードセットに追加し、ノードのアフィニティーを Pod に追加し、Pod がそのラベルの付いたノードのみにスケジュールできるようにします。

手順

ノードをユーザーの使用可能な唯一のノードとして設定するには、以下を実行します。

  1. 対応する taint をそれらのノードに追加します。

    以下に例を示します。

    $ oc adm taint nodes node1 dedicated=groupName:NoSchedule
    ヒント

    または、以下の YAML を適用して taint を追加できます。

    kind: Node
    apiVersion: v1
    metadata:
      name: my-node
    #...
    spec:
      taints:
        - key: dedicated
          value: groupName
          effect: NoSchedule
    #...
  2. カスタム受付コントローラーを作成して toleration を Pod に追加します。
4.6.2.3. ノードセレクターおよび toleration を使用したプロジェクトの作成

ノードセレクターおよび toleration (アノテーションとして設定されたもの) を使用するプロジェクトを作成して、Pod の特定のノードへの配置を制御できます。プロジェクトで作成された後続のリソースは、toleration に一致する taint を持つノードでスケジュールされます。

前提条件

  • コンピュートマシンセットを使用するか、ノードを直接編集して、ノード選択のラベルが 1 つ以上のノードに追加されている。
  • コンピュートマシンセットを使用するか、ノードを直接編集することによって、taint が 1 つ以上のノードに追加されました。

手順

  1. metadata.annotations セクションにノードセレクターおよび toleration を指定して、Project リソース定義を作成します。

    project.yaml ファイルの例

    kind: Project
    apiVersion: project.openshift.io/v1
    metadata:
      name: <project_name> 1
      annotations:
        openshift.io/node-selector: '<label>' 2
        scheduler.alpha.kubernetes.io/defaultTolerations: >-
          [{"operator": "Exists", "effect": "NoSchedule", "key":
          "<key_name>"} 3
          ]

    1
    プロジェクト名。
    2
    デフォルトのノードセレクターラベル。
    3
    taint および toleration コンポーネント の表で説明されている toleration パラメーターです。この例では、NoSchedule の effect を使用します。これにより、ノード上の既存の Pod はそのまま残り、Exists Operator は値を取得しません。
  2. oc apply コマンドを使用してプロジェクトを作成します。

    $ oc apply -f project.yaml

<project_name> namespace で作成された後続のリソースは指定されたノードにスケジュールされます。

4.6.2.4. taint および toleration を使用して特殊ハードウェアを持つノードを制御する

ノードの小規模なサブセットが特殊ハードウェアを持つクラスターでは、taint および toleration を使用して、特殊ハードウェアを必要としない Pod をそれらのノードから切り離し、特殊ハードウェアを必要とする Pod をそのままにすることができます。また、特殊ハードウェアを必要とする Pod に対して特定のノードを使用することを要求することもできます。

これは、特殊ハードウェアを必要とする Pod に toleration を追加し、特殊ハードウェアを持つノードに taint を付けることで実行できます。

手順

特殊ハードウェアを持つノードが特定の Pod 用に予約されるようにするには、以下を実行します。

  1. toleration を特別なハードウェアを必要とする Pod に追加します。

    以下に例を示します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    #...
    spec:
      tolerations:
        - key: "disktype"
          value: "ssd"
          operator: "Equal"
          effect: "NoSchedule"
          tolerationSeconds: 3600
    #...
  2. 以下のコマンドのいずれかを使用して、特殊ハードウェアを持つノードに taint を設定します。

    $ oc adm taint nodes <node-name> disktype=ssd:NoSchedule

    または、以下を実行します。

    $ oc adm taint nodes <node-name> disktype=ssd:PreferNoSchedule
    ヒント

    または、以下の YAML を適用して taint を追加できます。

    kind: Node
    apiVersion: v1
    metadata:
      name: my_node
    #...
    spec:
      taints:
        - key: disktype
          value: ssd
          effect: PreferNoSchedule
    #...

4.6.3. taint および toleration の削除

必要に応じてノードから taint を、Pod から toleration をそれぞれ削除できます。最初に toleration を Pod に追加してから taint をノードに追加して、toleration を追加する前に Pod がノードから削除されないようにする必要があります。

手順

taint および toleration を削除するには、以下を実行します。

  1. ノードから taint を削除するには、以下を実行します。

    $ oc adm taint nodes <node-name> <key>-

    以下に例を示します。

    $ oc adm taint nodes ip-10-0-132-248.ec2.internal key1-

    出力例

    node/ip-10-0-132-248.ec2.internal untainted

  2. Pod から toleration を削除するには、toleration を削除するための Pod 仕様を編集します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    #...
    spec:
      tolerations:
      - key: "key2"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 3600
    #...

4.7. ノードセレクターの使用による特定ノードへの Pod の配置

ノードセレクター は、ノードのカスタムラベルと Pod で指定されるセレクターを使用して定義されるキー/値のペアのマップを指定します。

Pod がノードで実行する要件を満たすには、Pod にはノードのラベルと同じキー/値のペアがなければなりません。

4.7.1. ノードセレクターについて

Pod でノードセレクターを使用し、ノードでラベルを使用して、Pod がスケジュールされる場所を制御できます。ノードセレクターにより、OpenShift Container Platform は一致するラベルが含まれるノード上に Pod をスケジュールします。

ノードセレクターを使用して特定の Pod を特定のノードに配置し、クラスタースコープのノードセレクターを使用して特定ノードの新規 Pod をクラスター内の任意の場所に配置し、プロジェクトノードを使用して新規 Pod を特定ノードのプロジェクトに配置できます。

たとえば、クラスター管理者は、作成するすべての Pod にノードセレクターを追加して、アプリケーション開発者が地理的に最も近い場所にあるノードにのみ Pod をデプロイできるインフラストラクチャーを作成できます。この例では、クラスターは 2 つのリージョンに分散する 5 つのデータセンターで構成されます。米国では、ノードに us-eastus-central、または us-west のラベルを付けます。アジア太平洋リージョン (APAC) では、ノードに apac-east または apac-west のラベルを付けます。開発者は、Pod がこれらのノードにスケジュールされるように、作成する Pod にノードセレクターを追加できます。

Pod オブジェクトにノードセレクターが含まれる場合でも、一致するラベルを持つノードがない場合、Pod はスケジュールされません。

重要

同じ Pod 設定でノードセレクターとノードのアフィニティーを使用している場合は、以下のルールが Pod のノードへの配置を制御します。

  • nodeSelectornodeAffinity の両方を設定する場合、Pod が候補ノードでスケジュールされるにはどちらの条件も満たしている必要があります。
  • nodeAffinity タイプに関連付けられた複数の nodeSelectorTerms を指定する場合、nodeSelectorTerms のいずれかが満たされている場合に Pod をノードにスケジュールすることができます。
  • nodeSelectorTerms に関連付けられた複数の matchExpressions を指定する場合、すべての matchExpressions が満たされている場合にのみ Pod をノードにスケジュールすることができます。
特定の Pod およびノードのノードセレクター

ノードセレクターおよびラベルを使用して、特定の Pod がスケジュールされるノードを制御できます。

ノードセレクターおよびラベルを使用するには、まずノードにラベルを付けて Pod がスケジュール解除されないようにしてから、ノードセレクターを Pod に追加します。

注記

ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。デプロイメント設定などの Pod を制御するオブジェクトにラベルを付ける必要があります。

たとえば、以下の Node オブジェクトには region: east ラベルがあります。

ラベルを含む Node オブジェクトのサンプル

kind: Node
apiVersion: v1
metadata:
  name: ip-10-0-131-14.ec2.internal
  selfLink: /api/v1/nodes/ip-10-0-131-14.ec2.internal
  uid: 7bc2580a-8b8e-11e9-8e01-021ab4174c74
  resourceVersion: '478704'
  creationTimestamp: '2019-06-10T14:46:08Z'
  labels:
    kubernetes.io/os: linux
    topology.kubernetes.io/zone: us-east-1a
    node.openshift.io/os_version: '4.5'
    node-role.kubernetes.io/worker: ''
    topology.kubernetes.io/region: us-east-1
    node.openshift.io/os_id: rhcos
    node.kubernetes.io/instance-type: m4.large
    kubernetes.io/hostname: ip-10-0-131-14
    kubernetes.io/arch: amd64
    region: east 1
    type: user-node
#...

1
Pod ノードセレクターに一致するラベル。

Pod には type: user-node,region: east ノードセレクターがあります。

ノードセレクターが含まれる Pod オブジェクトのサンプル

apiVersion: v1
kind: Pod
metadata:
  name: s1
#...
spec:
  nodeSelector: 1
    region: east
    type: user-node
#...

1
ノードトラベルに一致するノードセレクター。ノードには、各ノードセレクターのラベルが必要です。

サンプル Pod 仕様を使用して Pod を作成する場合、これはサンプルノードでスケジュールできます。

クラスタースコープのデフォルトノードセレクター

デフォルトのクラスタースコープのノードセレクターを使用する場合、クラスターで Pod を作成すると、OpenShift Container Platform はデフォルトのノードセレクターを Pod に追加し、一致するラベルのあるノードで Pod をスケジュールします。

たとえば、以下の Scheduler オブジェクトにはデフォルトのクラスタースコープの region=east および type=user-node ノードセレクターがあります。

スケジューラー Operator カスタムリソースの例

apiVersion: config.openshift.io/v1
kind: Scheduler
metadata:
  name: cluster
#...
spec:
  defaultNodeSelector: type=user-node,region=east
#...

クラスター内のノードには type=user-node,region=east ラベルがあります。

Node オブジェクトの例

apiVersion: v1
kind: Node
metadata:
  name: ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4
#...
  labels:
    region: east
    type: user-node
#...

ノードセレクターを持つ Pod オブジェクトの例

apiVersion: v1
kind: Pod
metadata:
  name: s1
#...
spec:
  nodeSelector:
    region: east
#...

サンプルクラスターでサンプル Pod 仕様を使用して Pod を作成する場合、Pod はクラスタースコープのノードセレクターで作成され、ラベルが付けられたノードにスケジュールされます。

ラベルが付けられたノード上の Pod を含む Pod リストの例

NAME     READY   STATUS    RESTARTS   AGE   IP           NODE                                       NOMINATED NODE   READINESS GATES
pod-s1   1/1     Running   0          20s   10.131.2.6   ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4   <none>           <none>

注記

Pod を作成するプロジェクトにプロジェクトノードセレクターがある場合、そのセレクターはクラスタースコープのセレクターよりも優先されます。Pod にプロジェクトノードセレクターがない場合、Pod は作成されたり、スケジュールされたりしません。

プロジェクトノードセレクター

プロジェクトノードセレクターを使用する場合、このプロジェクトで Pod を作成すると、OpenShift Container Platform はノードセレクターを Pod に追加し、Pod を一致するラベルを持つノードでスケジュールします。クラスタースコープのデフォルトノードセレクターがない場合、プロジェクトノードセレクターが優先されます。

たとえば、以下のプロジェクトには region=east ノードセレクターがあります。

Namespace オブジェクトの例

apiVersion: v1
kind: Namespace
metadata:
  name: east-region
  annotations:
    openshift.io/node-selector: "region=east"
#...

以下のノードには type=user-node,region=east ラベルがあります。

Node オブジェクトの例

apiVersion: v1
kind: Node
metadata:
  name: ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4
#...
  labels:
    region: east
    type: user-node
#...

Pod をこのサンプルプロジェクトでサンプル Pod 仕様を使用して作成する場合、Pod はプロジェクトノードセレクターで作成され、ラベルが付けられたノードにスケジュールされます。

Pod オブジェクトの例

apiVersion: v1
kind: Pod
metadata:
  namespace: east-region
#...
spec:
  nodeSelector:
    region: east
    type: user-node
#...

ラベルが付けられたノード上の Pod を含む Pod リストの例

NAME     READY   STATUS    RESTARTS   AGE   IP           NODE                                       NOMINATED NODE   READINESS GATES
pod-s1   1/1     Running   0          20s   10.131.2.6   ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4   <none>           <none>

Pod に異なるノードセレクターが含まれる場合、プロジェクトの Pod は作成またはスケジュールされません。たとえば、以下の Pod をサンプルプロジェクトにデプロイする場合、これは作成されません。

無効なノードセレクターを持つ Pod オブジェクトの例

apiVersion: v1
kind: Pod
metadata:
  name: west-region
#...
spec:
  nodeSelector:
    region: west
#...

4.7.2. ノードセレクターの使用による Pod 配置の制御

Pod でノードセレクターを使用し、ノードでラベルを使用して、Pod がスケジュールされる場所を制御できます。ノードセレクターにより、OpenShift Container Platform は一致するラベルが含まれるノード上に Pod をスケジュールします。

ラベルをノード、コンピュートマシンセット、またはマシン設定に追加します。コンピュートマシンセットにラベルを追加すると、ノードまたはマシンが停止した場合に、新規ノードにそのラベルが追加されます。ノードまたはマシン設定に追加されるラベルは、ノードまたはマシンが停止すると維持されません。

ノードセレクターを既存 Pod に追加するには、ノードセレクターを ReplicaSet オブジェクト、DaemonSet オブジェクト、StatefulSet オブジェクト、Deployment オブジェクト、または DeploymentConfig オブジェクトなどの Pod の制御オブジェクトに追加します。制御オブジェクト下の既存 Pod は、一致するラベルを持つノードで再作成されます。新規 Pod を作成する場合、ノードセレクターを Pod 仕様に直接追加できます。Pod に制御オブジェクトがない場合は、Pod を削除し、Pod 仕様を編集して、Pod を再作成する必要があります。

注記

ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。

前提条件

ノードセレクターを既存 Pod に追加するには、Pod の制御オブジェクトを判別します。たとえば、router-default-66d5cf9464-m2g75 Pod は router-default-66d5cf9464 レプリカセットによって制御されます。

$ oc describe pod router-default-66d5cf9464-7pwkc

出力例

kind: Pod
apiVersion: v1
metadata:
# ...
Name:               router-default-66d5cf9464-7pwkc
Namespace:          openshift-ingress
# ...
Controlled By:      ReplicaSet/router-default-66d5cf9464
# ...

Web コンソールでは、Pod YAML の ownerReferences に制御オブジェクトをリスト表示します。

apiVersion: v1
kind: Pod
metadata:
  name: router-default-66d5cf9464-7pwkc
# ...
  ownerReferences:
    - apiVersion: apps/v1
      kind: ReplicaSet
      name: router-default-66d5cf9464
      uid: d81dd094-da26-11e9-a48a-128e7edf0312
      controller: true
      blockOwnerDeletion: true
# ...

手順

  1. コンピュートマシンセットを使用するか、ノードを直接編集してラベルをノードに追加します。

    • MachineSet オブジェクトを使用して、ノードの作成時にコンピュートマシンセットによって管理されるノードにラベルを追加します。

      1. 以下のコマンドを実行してラベルを MachineSet オブジェクトに追加します。

        $ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]'  -n openshift-machine-api

        以下に例を示します。

        $ oc patch MachineSet abc612-msrtw-worker-us-east-1c  --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]'  -n openshift-machine-api
        ヒント

        あるいは、以下の YAML を適用してコンピュートマシンセットにラベルを追加することもできます。

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
        metadata:
          name: xf2bd-infra-us-east-2a
          namespace: openshift-machine-api
        spec:
          template:
            spec:
              metadata:
                labels:
                  region: "east"
                  type: "user-node"
        # ...
      2. oc edit コマンドを使用して、ラベルが MachineSet オブジェクトに追加されていることを確認します。

        以下に例を示します。

        $ oc edit MachineSet abc612-msrtw-worker-us-east-1c -n openshift-machine-api

        MachineSet オブジェクトの例

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
        
        # ...
        
        spec:
        # ...
          template:
            metadata:
        # ...
            spec:
              metadata:
                labels:
                  region: east
                  type: user-node
        # ...

    • ラベルをノードに直接追加します。

      1. ノードの Node オブジェクトを編集します。

        $ oc label nodes <name> <key>=<value>

        たとえば、ノードにラベルを付けるには、以下を実行します。

        $ oc label nodes ip-10-0-142-25.ec2.internal type=user-node region=east
        ヒント

        あるいは、以下の YAML を適用してノードにラベルを追加することもできます。

        kind: Node
        apiVersion: v1
        metadata:
          name: hello-node-6fbccf8d9
          labels:
            type: "user-node"
            region: "east"
        # ...
      2. ラベルがノードに追加されていることを確認します。

        $ oc get nodes -l type=user-node,region=east

        出力例

        NAME                          STATUS   ROLES    AGE   VERSION
        ip-10-0-142-25.ec2.internal   Ready    worker   17m   v1.27.3

  2. 一致するノードセレクターを Pod に追加します。

    • ノードセレクターを既存 Pod および新規 Pod に追加するには、ノードセレクターを Pod の制御オブジェクトに追加します。

      ラベルを含む ReplicaSet オブジェクトのサンプル

      kind: ReplicaSet
      apiVersion: apps/v1
      metadata:
        name: hello-node-6fbccf8d9
      # ...
      spec:
      # ...
        template:
          metadata:
            creationTimestamp: null
            labels:
              ingresscontroller.operator.openshift.io/deployment-ingresscontroller: default
              pod-template-hash: 66d5cf9464
          spec:
            nodeSelector:
              kubernetes.io/os: linux
              node-role.kubernetes.io/worker: ''
              type: user-node 1
      # ...

      1
      ノードセレクターを追加します。
    • ノードセレクターを特定の新規 Pod に追加するには、セレクターを Pod オブジェクトに直接追加します。

      ノードセレクターを持つ Pod オブジェクトの例

      apiVersion: v1
      kind: Pod
      metadata:
        name: hello-node-6fbccf8d9
      # ...
      spec:
        nodeSelector:
          region: east
          type: user-node
      # ...

      注記

      ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。

4.7.3. クラスタースコープのデフォルトノードセレクターの作成

クラスター内の作成されたすべての Pod を特定のノードに制限するために、デフォルトのクラスタースコープのノードセレクターをノード上のラベルと共に Pod で使用することができます。

クラスタースコープのノードセレクターを使用する場合、クラスターで Pod を作成すると、OpenShift Container Platform はデフォルトのノードセレクターを Pod に追加し、一致するラベルのあるノードで Pod をスケジュールします。

スケジューラー Operator カスタムリソース (CR) を編集して、クラスタースコープのノードセレクターを設定します。ラベルをノード、コンピュートマシンセット、またはマシン設定に追加します。コンピュートマシンセットにラベルを追加すると、ノードまたはマシンが停止した場合に、新規ノードにそのラベルが追加されます。ノードまたはマシン設定に追加されるラベルは、ノードまたはマシンが停止すると維持されません。

注記

Pod にキーと値のペアを追加できます。ただし、デフォルトキーの異なる値を追加することはできません。

手順

デフォルトのクラスタースコープのセレクターを追加するには、以下を実行します。

  1. スケジューラー Operator CR を編集して、デフォルトのクラスタースコープのノードクラスターを追加します。

    $ oc edit scheduler cluster

    ノードセレクターを含むスケジューラー Operator CR のサンプル

    apiVersion: config.openshift.io/v1
    kind: Scheduler
    metadata:
      name: cluster
    ...
    spec:
      defaultNodeSelector: type=user-node,region=east 1
      mastersSchedulable: false

    1
    適切な <key>:<value> ペアが設定されたノードセレクターを追加します。

    この変更を加えた後に、openshift-kube-apiserver プロジェクトの Pod の再デプロイを待機します。これには数分の時間がかかる場合があります。デフォルトのクラスター全体のノードセレクターは、Pod の再起動まで有効になりません。

  2. コンピュートマシンセットを使用するか、ノードを直接編集してラベルをノードに追加します。

    • コンピュートマシンセットを使用して、ノードの作成時にコンピュートマシンセットによって管理されるノードにラベルを追加します。

      1. 以下のコマンドを実行してラベルを MachineSet オブジェクトに追加します。

        $ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]'  -n openshift-machine-api 1
        1
        それぞれのラベルに <key>/<value> ペアを追加します。

        以下に例を示します。

        $ oc patch MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]'  -n openshift-machine-api
        ヒント

        あるいは、以下の YAML を適用してコンピュートマシンセットにラベルを追加することもできます。

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
        metadata:
          name: <machineset>
          namespace: openshift-machine-api
        spec:
          template:
            spec:
              metadata:
                labels:
                  region: "east"
                  type: "user-node"
      2. oc edit コマンドを使用して、ラベルが MachineSet オブジェクトに追加されていることを確認します。

        以下に例を示します。

        $ oc edit MachineSet abc612-msrtw-worker-us-east-1c -n openshift-machine-api

        MachineSet オブジェクトの例

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
          ...
        spec:
          ...
          template:
            metadata:
          ...
            spec:
              metadata:
                labels:
                  region: east
                  type: user-node
          ...

      3. 0 にスケールダウンし、ノードをスケールアップして、そのコンピュートマシンセットに関連付けられたノードを再デプロイします。

        以下に例を示します。

        $ oc scale --replicas=0 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
        $ oc scale --replicas=1 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
      4. ノードの準備ができ、利用可能な状態になったら、oc get コマンドを使用してラベルがノードに追加されていることを確認します。

        $ oc get nodes -l <key>=<value>

        以下に例を示します。

        $ oc get nodes -l type=user-node

        出力例

        NAME                                       STATUS   ROLES    AGE   VERSION
        ci-ln-l8nry52-f76d1-hl7m7-worker-c-vmqzp   Ready    worker   61s   v1.27.3

    • ラベルをノードに直接追加します。

      1. ノードの Node オブジェクトを編集します。

        $ oc label nodes <name> <key>=<value>

        たとえば、ノードにラベルを付けるには、以下を実行します。

        $ oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 type=user-node region=east
        ヒント

        あるいは、以下の YAML を適用してノードにラベルを追加することもできます。

        kind: Node
        apiVersion: v1
        metadata:
          name: <node_name>
          labels:
            type: "user-node"
            region: "east"
      2. oc get コマンドを使用して、ラベルがノードに追加されていることを確認します。

        $ oc get nodes -l <key>=<value>,<key>=<value>

        以下に例を示します。

        $ oc get nodes -l type=user-node,region=east

        出力例

        NAME                                       STATUS   ROLES    AGE   VERSION
        ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49   Ready    worker   17m   v1.27.3

4.7.4. プロジェクトスコープのノードセレクターの作成

プロジェクトで作成されたすべての Pod をラベルが付けられたノードに制限するために、プロジェクトのノードセレクターをノード上のラベルと共に使用できます。

このプロジェクトで Pod を作成する場合、OpenShift Container Platform はノードセレクターをプロジェクトの Pod に追加し、プロジェクトの一致するラベルを持つノードで Pod をスケジュールします。クラスタースコープのデフォルトノードセレクターがない場合、プロジェクトノードセレクターが優先されます。

You add node selectors to a project by editing the Namespace object to add the openshift.io/node-selector parameter.ラベルをノード、コンピュートマシンセット、またはマシン設定に追加します。コンピュートマシンセットにラベルを追加すると、ノードまたはマシンが停止した場合に、新規ノードにそのラベルが追加されます。ノードまたはマシン設定に追加されるラベルは、ノードまたはマシンが停止すると維持されません。

Pod オブジェクトにノードセレクターが含まれる場合でも、一致するノードセレクターを持つプロジェクトがない場合、Pod はスケジュールされません。その仕様から Pod を作成すると、以下のメッセージと同様のエラーが表示されます。

エラーメッセージの例

Error from server (Forbidden): error when creating "pod.yaml": pods "pod-4" is forbidden: pod node label selector conflicts with its project node label selector

注記

Pod にキーと値のペアを追加できます。ただし、プロジェクトキーに異なる値を追加することはできません。

手順

デフォルトのプロジェクトノードセレクターを追加するには、以下を実行します。

  1. namespace を作成するか、既存の namespace を編集して openshift.io/node-selector パラメーターを追加します。

    $ oc edit namespace <name>

    出力例

    apiVersion: v1
    kind: Namespace
    metadata:
      annotations:
        openshift.io/node-selector: "type=user-node,region=east" 1
        openshift.io/description: ""
        openshift.io/display-name: ""
        openshift.io/requester: kube:admin
        openshift.io/sa.scc.mcs: s0:c30,c5
        openshift.io/sa.scc.supplemental-groups: 1000880000/10000
        openshift.io/sa.scc.uid-range: 1000880000/10000
      creationTimestamp: "2021-05-10T12:35:04Z"
      labels:
        kubernetes.io/metadata.name: demo
      name: demo
      resourceVersion: "145537"
      uid: 3f8786e3-1fcb-42e3-a0e3-e2ac54d15001
    spec:
      finalizers:
      - kubernetes

    1
    適切な <key>:<value> ペアを持つ openshift.io/node-selector を追加します。
  2. コンピュートマシンセットを使用するか、ノードを直接編集してラベルをノードに追加します。

    • MachineSet オブジェクトを使用して、ノードの作成時にコンピュートマシンセットによって管理されるノードにラベルを追加します。

      1. 以下のコマンドを実行してラベルを MachineSet オブジェクトに追加します。

        $ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]'  -n openshift-machine-api

        以下に例を示します。

        $ oc patch MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]'  -n openshift-machine-api
        ヒント

        あるいは、以下の YAML を適用してコンピュートマシンセットにラベルを追加することもできます。

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
        metadata:
          name: <machineset>
          namespace: openshift-machine-api
        spec:
          template:
            spec:
              metadata:
                labels:
                  region: "east"
                  type: "user-node"
      2. oc edit コマンドを使用して、ラベルが MachineSet オブジェクトに追加されていることを確認します。

        以下に例を示します。

        $ oc edit MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api

        出力例

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
        metadata:
        ...
        spec:
        ...
          template:
            metadata:
        ...
            spec:
              metadata:
                labels:
                  region: east
                  type: user-node

      3. そのコンピュートマシンセットに関連付けられているノードを再デプロイします。

        以下に例を示します。

        $ oc scale --replicas=0 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
        $ oc scale --replicas=1 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
      4. ノードの準備ができ、利用可能な状態になったら、oc get コマンドを使用してラベルがノードに追加されていることを確認します。

        $ oc get nodes -l <key>=<value>

        以下に例を示します。

        $ oc get nodes -l type=user-node,region=east

        出力例

        NAME                                       STATUS   ROLES    AGE   VERSION
        ci-ln-l8nry52-f76d1-hl7m7-worker-c-vmqzp   Ready    worker   61s   v1.27.3

    • ラベルをノードに直接追加します。

      1. Node オブジェクトを編集してラベルを追加します。

        $ oc label <resource> <name> <key>=<value>

        たとえば、ノードにラベルを付けるには、以下を実行します。

        $ oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-c-tgq49 type=user-node region=east
        ヒント

        あるいは、以下の YAML を適用してノードにラベルを追加することもできます。

        kind: Node
        apiVersion: v1
        metadata:
          name: <node_name>
          labels:
            type: "user-node"
            region: "east"
      2. oc get コマンドを使用して、ラベルが Node オブジェクトに追加されていることを確認します。

        $ oc get nodes -l <key>=<value>

        以下に例を示します。

        $ oc get nodes -l type=user-node,region=east

        出力例

        NAME                                       STATUS   ROLES    AGE   VERSION
        ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49   Ready    worker   17m   v1.27.3

4.8. Pod トポロジー分散制約を使用した Pod 配置の制御

Pod トポロジーの分散制約を使用すると、ノード、ゾーン、リージョン、またはその他のユーザー定義のトポロジードメイン全体にわたる Pod の配置を詳細に制御できます。障害ドメイン全体に Pod を分散すると、高可用性とより効率的なリソース利用を実現できます。

4.8.1. 使用例

  • 管理者として、ワークロードを 2 個から 15 個の Pod 間で自動的にスケーリングしたいと考えています。Pod が 2 つしかない場合は、単一障害点を回避するために、Pod が同じノードに配置されないようにする必要があります。
  • 管理者として、レイテンシーとネットワークコストを削減するために、Pod を複数のインフラストラクチャーゾーンに均等に分散し、問題が発生した場合にクラスターが自己修復できることを確認したいと考えています。

4.8.2. 重要な留意事項

  • OpenShift Container Platform クラスター内の Pod は、デプロイメント、ステートフルセット、デーモンセットなどの ワークロードコントローラー によって管理されます。これらのコントローラーは、クラスター内のノード間で Pod がどのように分散およびスケーリングされるかなど、Pod のグループの望ましい状態を定義します。混乱を避けるために、グループ内のすべての Pod に同じ Pod トポロジーの分散制約を設定する必要があります。デプロイメントなどのワークロードコントローラーを使用する場合、通常は Pod テンプレートがこれを処理します。
  • 異なる Pod トポロジーの分散制約を混在させると、OpenShift Container Platform の動作が混同され、トラブルシューティングが困難になる可能性があります。トポロジードメイン内のすべてのノードに一貫したラベルが付けられていることを確認することで、これを回避できます。OpenShift Container Platform は、kubernetes.io/hostname などのよく知られたラベルを自動的に入力します。これにより、ノードに手動でラベルを付ける必要がなくなります。これらのラベルは重要なトポロジー情報を提供し、クラスター全体で一貫したノードラベル付けを保証します。
  • 制約により、分散される際に同じ namespace 内の Pod のみが一致し、グループ化されます。
  • 複数の Pod トポロジー分散制約を指定できますが、それらが互いに競合しないようにする必要があります。Pod を配置するには、すべての Pod トポロジー分散制約を満たしている必要があります。

4.8.3. skew と maxSkew

スキューとは、ゾーンやノードなどの異なるトポロジードメイン間で指定されたラベルセレクターに一致する Pod の数の差を指します。

スキューは、各ドメイン内の Pod の数と、スケジュールされている Pod の数が最も少ないドメイン内の Pod 数との絶対差をとることで、各ドメインごとに計算されます。maxSkew 値を設定すると、スケジューラーはバランスの取れた Pod 分散を維持するようになります。

4.8.3.1. スキューの計算例

3 つのゾーン (A、B、C) があり、これらのゾーンに Pod を均等に分散したいと考えています。ゾーン A に Pod が 5 個、ゾーン B に Pod が 3 個、ゾーン C に Pod が 2 個ある場合、偏りを見つけるには、各ゾーンに現在ある Pod の数から、スケジュールされている Pod の数が最も少ないドメインの Pod の数を減算します。つまり、ゾーン A のスキューは 3、ゾーン B のスキューは 1、ゾーン C のスキューは 0 です。

4.8.3.2. maxSkew パラメーター

maxSkew パラメーターは、任意の 2 つのトポロジードメイン間の Pod 数の最大許容差、つまりスキューを定義します。maxSkew1 に設定されている場合、トポロジードメイン内の Pod の数は、他のドメインとの差が 1 を超えてはなりません。スキューが maxSkew を超える場合、スケジューラーは制約に従ってスキューを減らす方法で新しい Pod を配置しようとします。

前のスキュー計算例を使用すると、スキュー値はデフォルトの maxSkew1 を超えます。スケジューラーは、スキューを減らして、負荷がバランスよく分散されるように、ゾーン B とゾーン C に新しい Pod を配置し、トポロジードメインがスキュー 1 を超えないようにします。

4.8.4. Pod トポロジー分散制約の設定例

グループ化する Pod を指定し、それらの Pod が分散されるトポロジードメインと、許可できるスキューを指定します。

以下の例は、Pod トポロジー設定分散制約の設定を示しています。

指定されたラベルに一致する Pod をゾーンに基づいて分散する例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    region: us-east
spec:
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  topologySpreadConstraints:
  - maxSkew: 1 1
    topologyKey: topology.kubernetes.io/zone 2
    whenUnsatisfiable: DoNotSchedule 3
    labelSelector: 4
      matchLabels:
        region: us-east 5
    matchLabelKeys:
      - my-pod-label 6
  containers:
  - image: "docker.io/ocpqe/hello-pod"
    name: hello-pod
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop: [ALL]

1
任意の 2 つのトポロジードメイン間の Pod 数の最大差。デフォルトは 1 で、0 の値を指定することはできません。
2
ノードラベルのキー。このキーと同じ値を持つノードは同じトポロジーにあると見なされます。
3
分散制約を満たさない場合に Pod を処理する方法です。デフォルトは DoNotSchedule であり、これはスケジューラーに Pod をスケジュールしないように指示します。ScheduleAnyway に設定して Pod を依然としてスケジュールできますが、スケジューラーはクラスターがさらに不均衡な状態になるのを防ぐためにスキューの適用を優先します。
4
制約を満たすために、分散される際に、このラベルセレクターに一致する Pod はグループとしてカウントされ、認識されます。ラベルセレクターを指定してください。指定しないと、Pod が一致しません。
5
今後適切にカウントされるようにするには、この Pod 仕様がこのラベルセレクターに一致するようにラベルを設定していることも確認してください。
6
拡散を計算する Pod を選択するための Pod ラベルキーのリスト。

単一 Pod トポロジーの分散制約を示す例

kind: Pod
apiVersion: v1
metadata:
  name: my-pod
  labels:
    region: us-east
spec:
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        region: us-east
  containers:
  - image: "docker.io/ocpqe/hello-pod"
    name: hello-pod

前の例では、Pod トポロジーの分散制約が 1 つある Pod 仕様を定義しています。これは region: us-east というラベルが付いた Pod で一致し、ゾーン間で分散され、スキューの 1 を指定し、これらの要件を満たさない場合に Pod をスケジュールしません。

複数の Pod トポロジー分散制約を示す例

kind: Pod
apiVersion: v1
metadata:
  name: my-pod-2
  labels:
    region: us-east
spec:
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: node
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        region: us-east
  - maxSkew: 1
    topologyKey: rack
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        region: us-east
  containers:
  - image: "docker.io/ocpqe/hello-pod"
    name: hello-pod

上記の例では、Pod トポロジー分散制約が 2 つある Pod 仕様を定義します。どちらも region: us-east というラベルの付いた Pod に一致し、スキューを 1 に指定し、これらの要件を満たしていない場合は Pod はスケジュールされません。

最初の制約は、ユーザー定義ラベルの node に基づいて Pod を分散し、2 つ目の制約はユーザー定義ラベルの rack に基づいて Pod を分散します。Pod がスケジュールされるには、両方の制約を満たす必要があります。

4.8.5. 関連情報

4.9. Descheduler を使用した Pod のエビクト

スケジューラー は、新しい Pod をホストするのに最適なノードを決定するために使用されますが、デスケジューラーは、実行中の Pod を削除して、Pod をより適切なノードに再スケジュールできるようにするために使用できます。

4.9.1. Descheduler について

Descheduler を使用して Pod を特定のストラテジーに基づいてエビクトし、Pod がより適切なノードに再スケジュールされるようにできます。

以下のような状況では、実行中の Pod のスケジュールを解除することに利点があります。

  • ノードの使用率が低くなっているか、使用率が高くなっている。
  • taint またはラベルなどの、Pod およびノードアフィニティーの各種要件が変更され、当初のスケジュールの意思決定が特定のノードに適さなくなっている。
  • ノードの障害により、Pod を移動する必要がある。
  • 新規ノードがクラスターに追加されている。
  • Pod が再起動された回数が多すぎる。
重要

Descheduler はエビクトされた Pod の置き換えをスケジュールしません。スケジューラーは、エビクトされた Pod に対してこのタスクを自動的に実行します。

Descheduler がノードから Pod をエビクトすることを決定する際には、以下の一般的なメカニズムを使用します。

  • openshift-* および kube-system namespace の Pod はエビクトされることがありません。
  • priorityClassNamesystem-cluster-critical または system-node-critical に設定されている Critical Pod はエビクトされることがありません。
  • レプリケーションコントローラー、レプリカセット、デプロイメント、またはジョブの一部ではない静的な Pod、ミラーリングされた Pod、またはスタンドアロンの Pod は、再作成されないためにエビクトされません。
  • デーモンセットに関連付けられた Pod はエビクトされることがありません。
  • ローカルストレージを持つ Pod はエビクトされることがありません。
  • Best effort Pod は、Burstable および Guaranteed Pod の前にエビクトされます。
  • descheduler.alpha.kubernetes.io/evict アノテーションを持つすべてのタイプの Pod はエビクトの対象になります。このアノテーションはエビクションを防ぐチェックを上書きするために使用され、ユーザーはエビクトする Pod を選択できます。ユーザーは、Pod を再作成する方法と、Pod が再作成されるかどうかを認識している必要があります。
  • Pod の Disruption Budget (PDB) が適用される Pod は、スケジュール解除が PDB に違反する場合にはエビクトされません。Pod は、エビクションサブリソースを使用して PDB を処理することでエビクトされます。

4.9.2. Descheduler プロファイル

以下の Descheduler ストラテジーを利用できます。

AffinityAndTaints

このプロファイルは、Pod 間の非アフィニティー、ノードアフィニティー、およびノードの taint に違反する Pod をエビクトします。

これにより、以下のストラテジーが有効になります。

  • RemovePodsViolatingInterPodAntiAffinity: Pod 間の非アフィニティーに違反する Pod を削除します。
  • RemovePodsViolatingNodeAffinity: ノードのアフィニティーに違反する Pod を削除します。
  • RemovePodsViolatingNodeTaints: ノード上の NoSchedule taint に違反する Pod を削除します。

    ノードのアフィニティータイプが requiredDuringSchedulingIgnoredDuringExecution の Pod は削除されます。

TopologyAndDuplicates

このプロファイルは、ノード間で同様の Pod または同じトポロジードメインの Pod を均等に分散できるように Pod をエビクトします。

これにより、以下のストラテジーが有効になります。

  • RemovePodsViolatingTopologySpreadConstraint: 均等に分散されていないとポロジードメインを見つけ、DoNotSchedule 制約を違反している場合により大きなものから Pod のエビクトを試行します。
  • RemoveDuplicates: 1 つの Pod のみが同じノードで実行されているレプリカセット、レプリケーションコントローラー、デプロイメントまたはジョブに関連付けられます。追加の Pod がある場合、それらの重複 Pod はクラスターに Pod を効果的に分散できるようにエビクトされます。
LifecycleAndUtilization

このプロファイルは長時間実行される Pod をエビクトし、ノード間のリソース使用状況のバランスを取ります。

これにより、以下のストラテジーが有効になります。

  • RemovePodsHavingTooManyRestarts: コンテナーが何度も再起動された Pod を削除します。

    すべてのコンテナー (Init コンテナーを含む) での再起動の合計が 100 を超える Pod。

  • LowNodeUtilization: 使用率の低いノードを検出し、可能な場合は過剰に使用されているノードから Pod をエビクトし、エビクトされた Pod の再作成がそれらの使用率の低いノードでスケジュールされるようにします。

    ノードは、使用率がすべてのしきい値 (CPU、メモリー、Pod の数) について 20% 未満の場合に使用率が低いと見なされます。

    ノードは、使用率がすべてのしきい値 (CPU、メモリー、Pod の数) について 50% を超える場合に過剰に使用されていると見なされます。

  • PodLifeTime: 古くなり過ぎた Pod をエビクトします。

    デフォルトでは、24 時間以上経過した Pod は削除されます。Pod のライフタイム値をカスタマイズできます。

SoftTopologyAndDuplicates

このプロファイルは TopologyAndDuplicates と同じですが、whenUnsatisfiable: ScheduleAnyway などのソフトトポロジー制約のある Pod も削除の対象と見なされる点が異なります。

注記

SoftTopologyAndDuplicatesTopologyAndDuplicates の両方を有効にしないでください。両方を有効にすると、競合が生じます。

EvictPodsWithLocalStorage
このプロファイルにより、ローカルストレージを備えた Pod が削除の対象になります。
EvictPodsWithPVC
このプロファイルを使用すると、永続的なボリュームクレームを持つ Pod をエビクションの対象にすることができます。Kubernetes NFS Subdir External Provisioner を使用している場合は、プロビジョナーがインストールされているnamespaceに除外されたnamespaceを追加する必要があります。

4.9.3. Descheduler のインストール

Descheduler はデフォルトで利用できません。Descheduler を有効にするには、Kube Descheduler Operator を OperatorHub からインストールし、1 つ以上の Descheduler プロファイルを有効にする必要があります。

デフォルトで、Descheduler は予測モードで実行されます。つまり、これは Pod エビクションのみをシミュレートします。Pod エビクションを実行するには、Descheduler のモードを automatic に変更する必要があります。

重要

クラスターでホストされたコントロールプレーンを有効にしている場合は、カスタム優先度のしきい値を設定して、ホストされたコントロールプレーンの namespace の Pod が削除される可能性を下げます。ホストされたコントロールプレーンの優先度クラスの中で優先度値が最も低い (100000000) ため、優先度しきい値クラス名を hypershift-control-plane に設定します。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。
  • OpenShift Container Platform Web コンソールにアクセスできる。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. Kube Descheduler Operator に必要な namespace を作成します。

    1. AdministrationNamespaces に移動し、Create Namespace をクリックします。
    2. Name フィールドに openshift-kube-descheduler-operator を入力し、Labels フィールドに openshift.io/cluster-monitoring=true を入力して Descheduler メトリックを有効にし、Create をクリックします。
  3. Kube Descheduler Operator をインストールします。

    1. OperatorsOperatorHub に移動します。
    2. Kube Descheduler Operator をフィルターボックスに入力します。
    3. Kube Descheduler Operator を選択し、Install をクリックします。
    4. Install Operator ページで、A specific namespace on the cluster を選択します。ドロップダウンメニューから openshift-kube-descheduler-operator を選択します。
    5. Update Channel および Approval Strategy の値を必要な値に調整します。
    6. Install をクリックします。
  4. Descheduler インスタンスを作成します。

    1. OperatorsInstalled Operators ページから、Kube Descheduler Operator をクリックします。
    2. Kube Descheduler タブを選択し、Create KubeDescheduler をクリックします。
    3. 必要に応じて設定を編集します。

      1. エビクションをシミュレーションせずに Pod をエビクトするには、Mode フィールドを Automatic に変更します。
      2. Profiles セクションを展開し、1 つ以上のプロファイルを選択して有効にします。AffinityAndTaints プロファイルはデフォルトで有効になっています。Add Profile をクリックして、追加のプロファイルを選択します。

        注記

        TopologyAndDuplicatesSoftTopologyAndDuplicates の両方を有効にしないでください。両方を有効にすると、競合が生じます。

      3. オプション: Profile Customizations セクションを拡張して、Descheduler の任意の設定を行います。

        • LifecycleAndUtilization プロファイルのカスタム Pod ライフタイム値を設定します。podLifetime フィールドを使用して、数値と有効な単位 (sm、または h) を設定します。デフォルトの Pod の有効期間は 24 時間 (24 h) です。
        • カスタム優先度しきい値を設定して、Pod の優先度が指定された優先度レベルよりも低い場合にのみ、Pod を削除対象と見なします。thresholdPriority フィールドを使用して数値の優先度しきい値を設定するか、thresholdPriorityClassName フィールドを使用して特定の優先度クラス名を指定します。

          注記

          デスケジューラーに thresholdPrioritythresholdPriorityClassName の両方を指定しないでください。

        • デスケジューラー操作から除外または含める特定の namespace を設定します。namespaces フィールドを展開し、namespace を 除外 リストまたは 包含 リストに追加します。除外する namespace のリストまたは追加する namespace のリストのみを設定できます。保護されている namespace (openshift-*kube-systemhypershift) はデフォルトで除外されることに注意してください。
        • 実験的: LowNodeUtilization ストラテジーの使用率および過度化のしきい値を設定します。devLowNodeUtilizationThresholds フィールドを使用して、以下のいずれかの値を設定します。

          • Low: 10% が十分に活用されておらず、30% が過剰に活用されている
          • Medium: 20% が十分に活用されておらず、50% が過剰に活用されている
          • High: 40% が十分に活用されておらず、70% が過剰に活用されている
          注記

          この設定は実験段階にあり、実稼働環境では使用しないでください。

      4. オプション: Descheduling Interval Seconds フィールドを使用して、Descheduler の実行間の秒数を変更します。デフォルトは 3600 秒です。
    4. Create をクリックします。

また、後で OpenShift CLI (oc) を使用して、Descheduler のプロファイルおよび設定を設定することもできます。Web コンソールから Descheduler インスタンスを作成する際にプロファイルを調整しない場合、AffinityAndTaints プロファイルはデフォルトで有効にされます。

4.9.4. Descheduler プロファイルの設定

Descheduler が Pod のエビクトに使用するプロファイルを設定できます。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。

手順

  1. KubeDescheduler オブジェクトを編集します。

    $ oc edit kubedeschedulers.operator.openshift.io cluster -n openshift-kube-descheduler-operator
  2. spec.profiles セクションに 1 つ以上のプロファイルを指定します。

    apiVersion: operator.openshift.io/v1
    kind: KubeDescheduler
    metadata:
      name: cluster
      namespace: openshift-kube-descheduler-operator
    spec:
      deschedulingIntervalSeconds: 3600
      logLevel: Normal
      managementState: Managed
      operatorLogLevel: Normal
      mode: Predictive                                     1
      profileCustomizations:
        namespaces:                                        2
          excluded:
          - my-namespace
        podLifetime: 48h                                   3
        thresholdPriorityClassName: my-priority-class-name 4
      profiles:                                            5
      - AffinityAndTaints
      - TopologyAndDuplicates                              6
      - LifecycleAndUtilization
      - EvictPodsWithLocalStorage
      - EvictPodsWithPVC
    1
    オプション: デフォルトでは、Descheduler は Pod をエビクトしません。Pod をエビクトするには、modeAutomatic に設定します。
    2
    オプション: Descheduler 操作に含めるか、除外するように、ユーザーが作成した namespace の一覧を設定します。excluded namespace のリストを設定するには exclude を使用するか、含める namespace のリストを設定するには included を使用します。保護されている namespace (openshift-*kube-systemhypershift) はデフォルトで除外されることに注意してください。
    3
    オプション: LifecycleAndUtilization プロファイルのカスタム Pod ライフタイム値を有効にします。有効な単位は sm、または h です。デフォルトの Pod の有効期間は 24 時間です。
    4
    オプション: 優先順位のしきい値を指定して、優先順位のしきい値を指定して、それらの優先順位が指定されたレベルよりも低い場合にのみ Pod をエビクションの対象とみなします。thresholdPriority フィールドを使用して数値の優先度しきい値 (たとえば、10000) を設定するか、thresholdPriorityClassName フィールドを使用して特定の優先度クラス名 (たとえば、my-priority-class-name) を指定します。優先順位クラス名を指定する場合、これはすでに存在している必要があり、Descheduler はエラーを出力します。thresholdPrioritythresholdPriorityClassName の両方を設定しないでください。
    5
    1 つ以上のプロファイルを追加して有効にします。使用可能なプロファイル: AffinityAndTaintsTopologyAndDuplicatesLifecycleAndUtilizationSoftTopologyAndDuplicatesEvictPodsWithLocalStorage、および EvictPodsWithPVC
    6
    TopologyAndDuplicatesSoftTopologyAndDuplicates の両方を有効にしないでください。両方を有効にすると、競合が生じます。

    複数のプロファイルを有効にすることができますが、プロファイルを指定する順番は重要ではありません。

  3. 変更を適用するためにファイルを保存します。

4.9.5. Descheduler の間隔の設定

Descheduler の実行間隔を設定できます。デフォルトは 3600 秒 (1 時間) です。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。

手順

  1. KubeDescheduler オブジェクトを編集します。

    $ oc edit kubedeschedulers.operator.openshift.io cluster -n openshift-kube-descheduler-operator
  2. deschedulingIntervalSeconds フィールドを必要な値に更新します。

    apiVersion: operator.openshift.io/v1
    kind: KubeDescheduler
    metadata:
      name: cluster
      namespace: openshift-kube-descheduler-operator
    spec:
      deschedulingIntervalSeconds: 3600 1
    ...
    1
    Descheduler の実行間隔を秒単位で設定します。このフィールドの値 0 は Descheduler を一度実行し、終了します。
  3. 変更を適用するためにファイルを保存します。

4.9.6. Descheduler のアンインストール

Descheduler インスタンスを削除し、Kube Descheduler Operator をアンインストールして Descheduler をクラスターから削除できます。この手順では、KubeDescheduler CRD および openshift-kube-descheduler-operator namespace もクリーンアップします。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。
  • OpenShift Container Platform Web コンソールにアクセスできる。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. Descheduler インスタンスを削除します。

    1. OperatorsInstalled Operators ページから、Kube Descheduler Operator をクリックします。
    2. Kube Descheduler タブを選択します。
    3. clusterエントリーの横にあるオプションメニュー kebab をクリックし、Delete KubeDeschedulerを選択します。
    4. 確認ダイアログで Delete をクリックします。
  3. Kube Descheduler Operator をアンインストールします。

    1. OperatorsInstalled Operators に移動します。
    2. Kube Descheduler Operatorエントリーの横にあるオプションメニュー kebab をクリックし、Uninstall Operatorを選択します。
    3. 確認ダイアログで、Uninstall をクリックします。
  4. openshift-kube-descheduler-operator namespace を削除します。

    1. AdministrationNamespaces に移動します。
    2. openshift-kube-descheduler-operator をフィルターボックスに入力します。
    3. openshift-kube-descheduler-operatorエントリーの横にあるオプションメニュー kebab をクリックし、Delete Namespace.を選択します。
    4. 確認ダイアログで openshift-kube-descheduler-operator を入力し、Delete をクリックします。
  5. KubeDescheduler CRD を削除します。

    1. AdministrationCustom Resource Definitions に移動します。
    2. KubeDescheduler をフィルターボックスに入力します。
    3. KubeDeschedulerエントリーの横にあるオプションメニュー kebab をクリックし、Delete CustomResourceDefinition を選択します。
    4. 確認ダイアログで Delete をクリックします。

4.10. セカンダリースケジューラー

4.10.1. セカンダリースケジューラーの概要

Secondary Scheduler Operator をインストールして、デフォルトのスケジューラーと共にカスタムのセカンダリースケジューラーを実行して Pod をスケジュールすることができます。

4.10.1.1. セカンダリースケジューラー Operator について

Red Hat OpenShift のセカンダリースケジューラー Operator は、OpenShift Container Platform でカスタムセカンダリースケジューラーをデプロイする方法を提供します。セカンダリースケジューラーは、デフォルトのスケジューラーと共に実行され、Pod をスケジュールします。Pod 設定は、使用するスケジューラーを指定できます。

カスタムスケジューラーには /bin/kube-scheduler バイナリーが必要であり、Kubernetes スケジューリングフレームワーク をベースとする必要があります。

重要

Secondary Scheduler Operator を使用してカスタムセカンダリースケジューラーを OpenShift Container Platform にデプロイできますが、Red Hat はカスタムセカンダリースケジューラーの機能を直接サポートしません。

セカンダリースケジューラー Operator は、セカンダリースケジューラーで必要なデフォルトのロールおよびロールバインディングを作成します。セカンダリースケジューラーの KubeSchedulerConfiguration リソースを設定することにより、有効または無効にするスケジューリングプラグインを指定できます。

4.10.2. Red Hat OpenShift リリースノートのセカンダリースケジューラー Operator

Red Hat OpenShift のセカンダリースケジューラー Operator を使用すると、カスタムセカンダリースケジューラーを OpenShift Container Platform クラスターにデプロイできます。

このリリースノートでは、Red Hat OpenShift のセカンダリースケジューラー Operator の開発を追跡します。

詳細は、Secondary Scheduler Operator について を参照してください。

4.10.2.1. Red Hat OpenShift 1.3.0 の Secondary Scheduler Operator のリリースノート

発行日: 2024 年 11 月 20 日

Red Hat OpenShift 1.3.0 の Secondary Scheduler Operator には、次のアドバイザリーが利用可能です。

4.10.2.1.1. バグ修正
  • Secondary Scheduler Operator のこのリリースでは、いくつかの Common Vulnerabilities and Exposures (CVE) に対処しています。
4.10.2.1.2. 既知の問題
  • 現時点で、Secondary Scheduler Operator を使用して設定マップ、CRD、RBAC ポリシーなどの追加のリソースをデプロイできません。カスタムセカンダリースケジューラーに必要なロールとロールバインディング以外のリソースは、外部から適用する必要があります。(WRKLDS-645)
4.10.2.2. Red Hat OpenShift 1.2.1 の Secondary Scheduler Operator のリリースノート

発行日: 2024 年 3 月 6 日

Red Hat OpenShift 1.2.1 の Secondary Scheduler Operator については、次のアドバイザリーが利用可能です。

4.10.2.2.1. 新機能および機能拡張
大規模なクラスターをサポートするために、リソース制限が削除される

このリリースでは、リソース制限が削除され、多くのノードと Pod を含む大規模なクラスターに対して、メモリー不足エラーによって失敗することなく Secondary Scheduler Operator を使用できるようになりました。

4.10.2.2.2. バグ修正
  • Secondary Scheduler Operator のこのリリースでは、いくつかの Common Vulnerabilities and Exposures (CVE) に対処しています。
4.10.2.2.3. 既知の問題
  • 現時点で、Secondary Scheduler Operator を使用して設定マップ、CRD、RBAC ポリシーなどの追加のリソースをデプロイできません。カスタムセカンダリースケジューラーに必要なロールとロールバインディング以外のリソースは、外部から適用する必要があります。(WRKLDS-645)
4.10.2.3. Red Hat OpenShift 1.2.0 の Secondary Scheduler Operator のリリースノート

発行日: 2023 年 11 月 1 日

以下のアドバイザリーは、Red Hat OpenShift 1.2.0 の Secondary Scheduler Operator で利用できます。

4.10.2.3.1. バグ修正
  • Secondary Scheduler Operator のこのリリースでは、いくつかの Common Vulnerabilities and Exposures (CVE) に対処しています。
4.10.2.3.2. 既知の問題
  • 現時点で、Secondary Scheduler Operator を使用して設定マップ、CRD、RBAC ポリシーなどの追加のリソースをデプロイできません。カスタムセカンダリースケジューラーに必要なロールとロールバインディング以外のリソースは、外部から適用する必要があります。(WRKLDS-645)

4.10.3. セカンダリースケジューラーを使用した Pod のスケジューリング

OpenShift Container Platform でカスタムセカンダリースケジューラーを実行するには、セカンダリースケジューラー Operator をインストールし、セカンダリースケジューラーをデプロイし、セカンダリースケジューラーを Pod 定義に設定します。

4.10.3.1. セカンダリースケジューラー Operator のインストール

Web コンソールを使用して、Red Hat OpenShift の Secondary Scheduler Operator をインストールできます。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。
  • OpenShift Container Platform Web コンソールにアクセスできる。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. Red Hat OpenShift のセカンダリースケジューラー Operator に必要な namespace を作成します。

    1. AdministrationNamespaces に移動し、Create Namespace をクリックします。
    2. Name フィールドに openshift-secondary-scheduler-operator を入力し、Create をクリックします。
  3. Red Hat OpenShift 用のセカンダリースケジューラー Operator をインストールします。

    1. OperatorsOperatorHub に移動します。
    2. フィルターボックスに Secondary Scheduler Operator for Red Hat OpenShift と入力します。
    3. Red Hat OpenShift 用の Secondary Scheduler Operator を選択し、Install をクリックします。
    4. Install Operator ページで以下を行います。

      1. Update チャネルstable に設定され、Red Hat OpenShift 用の Secondary Scheduler Operator の最新の安定したリリースをインストールします。
      2. クラスターで特定の namespace を選択し、ドロップダウンメニューから openshift-secondary-scheduler-operator を選択します。
      3. Update approval strategy を選択します。

        • Automatic ストラテジーにより、Operator Lifecycle Manager (OLM) は新規バージョンが利用可能になると Operator を自動的に更新できます。
        • Manual ストラテジーには、Operator の更新を承認するための適切な認証情報を持つユーザーが必要です。
      4. Install をクリックします。

検証

  1. OperatorsInstalled Operators に移動します。
  2. Red Hat OpenShift の Secondary Scheduler OperatorStatusSucceeded の状態でリスト表示されていることを確認します。
4.10.3.2. セカンダリースケジューラーのデプロイ

Secondary Scheduler Operator のインストール後に、セカンダリースケジューラーをデプロイできます。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。
  • OpenShift Container Platform Web コンソールにアクセスできる。
  • Red Hat OpenShift のセカンダリースケジューラー Operator がインストールされている。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. セカンダリースケジューラーの設定を保持する設定マップを作成します。

    1. WorkloadsConfigMaps に移動します。
    2. Create ConfigMap をクリックします。
    3. YAML エディターで、必要な KubeSchedulerConfiguration 設定が含まれる設定マップ定義を入力します。以下に例を示します。

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: "secondary-scheduler-config"                  1
        namespace: "openshift-secondary-scheduler-operator" 2
      data:
        "config.yaml": |
          apiVersion: kubescheduler.config.k8s.io/v1
          kind: KubeSchedulerConfiguration                  3
          leaderElection:
            leaderElect: false
          profiles:
            - schedulerName: secondary-scheduler            4
              plugins:                                      5
                score:
                  disabled:
                    - name: NodeResourcesBalancedAllocation
                    - name: NodeResourcesLeastAllocated
      1
      設定マップの名前。これは、SecondaryScheduler CR の作成時に Scheduler Config フィールドで使用されます。
      2
      設定マップは openshift-secondary-scheduler-operator namespace に作成される必要があります。
      3
      セカンダリースケジューラーの KubeSchedulerConfiguration リソース。詳細は、Kubernetes API ドキュメントの KubeSchedulerConfiguration を参照してください。
      4
      セカンダリースケジューラーの名前。spec.schedulerName フィールドをこの値に設定する Pod はこのセカンダリースケジューラーでスケジュールされます。
      5
      セカンダリースケジューラーに対して有効または無効にするプラグイン。デフォルトのスケジューリングプラグインのリストは、Kubernetes ドキュメントの スケジューリングプラグ インを参照してください。
    4. Create をクリックします。
  3. SecondaryScheduler CR を作成します。

    1. OperatorsInstalled Operators に移動します。
    2. Red Hat OpenShift の Secondary Scheduler Operator を選択します。
    3. Secondary Scheduler タブを選択し、Create SecondaryScheduler をクリックします。
    4. Name フィールドはデフォルトで cluster に設定されます。この名前は変更しないでください。
    5. Scheduler Config フィールドは secondary-scheduler-config にデフォルト設定されます。この値は、この手順で先に作成した設定マップの名前と一致していることを確認してください。
    6. Scheduler Image フィールドにカスタムスケジューラーのイメージ名を入力します。

      重要

      Red Hat では、カスタムのセカンダリースケジューラーの機能を直接サポートしません。

    7. Create をクリックします。
4.10.3.3. セカンダリースケジューラーを使用した Pod のスケジューリング

セカンダリースケジューラーを使用して Pod をスケジュールするには、Pod 定義の schedulerName フィールドを設定します。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。
  • OpenShift Container Platform Web コンソールにアクセスできる。
  • Red Hat OpenShift のセカンダリースケジューラー Operator がインストールされている。
  • セカンダリースケジューラーが設定されています。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. WorkloadsPods に移動します。
  3. Create Pod をクリックします。
  4. YAML エディターで、必要な Pod 設定を入力し、schedulerName フィールドを追加します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      namespace: default
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2
          ports:
            - containerPort: 80
      schedulerName: secondary-scheduler 1
    1
    schedulerName フィールドは、セカンダリースケジューラーの設定時に設定マップで定義される名前と一致する必要があります。
  5. Create をクリックします。

検証

  1. OpenShift CLI にログインします。
  2. 以下のコマンドを使用して Pod を記述します。

    $ oc describe pod nginx -n default

    出力例

    Name:         nginx
    Namespace:    default
    Priority:     0
    Node:         ci-ln-t0w4r1k-72292-xkqs4-worker-b-xqkxp/10.0.128.3
    ...
    Events:
      Type    Reason          Age   From                 Message
      ----    ------          ----  ----                 -------
      Normal  Scheduled       12s   secondary-scheduler  Successfully assigned default/nginx to ci-ln-t0w4r1k-72292-xkqs4-worker-b-xqkxp
    ...

  3. イベントテーブルで、Successfully assigned <namespace>/<pod_name> to <node_name> のようなメッセージが表示されたイベントを見つけます。
  4. "From" 列で、デフォルトのスケジューラーではなく、イベントがセカンダリースケジューラーから生成されたことを確認します。

    注記

    openshift-secondary-scheduler-namespacesecondary-scheduler-* Pod ログをチェックして、Pod がセカンダリースケジューラーによってスケジュールされていることを確認することもできます。

4.10.4. セカンダリースケジューラー Operator のアンインストール

Operator をアンインストールして関連リソースを削除することにより、Red Hat OpenShift のセカンダリースケジューラー Operator を OpenShift Container Platform から削除できます。

4.10.4.1. セカンダリースケジューラー Operator のアンインストール

Web コンソールを使用して、Red Hat OpenShift のセカンダリースケジューラー Operator をアンインストールできます。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。
  • OpenShift Container Platform Web コンソールにアクセスできる。
  • Red Hat OpenShift のセカンダリースケジューラー Operator がインストールされている。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. Red Hat OpenShift Operator のセカンダリースケジューラー Operator をアンインストールします。

    1. OperatorsInstalled Operators に移動します。
    2. セカンダリースケジューラーの Operator エントリーの隣にあるオプションメニュー kebab をクリックし、Operator のアンインストール をクリックします。
    3. 確認ダイアログで、Uninstall をクリックします。
4.10.4.2. Secondary Scheduler Operator リソースの削除

オプションで、Red Hat OpenShift の Secondary Scheduler Operator をアンインストールした後、関連するリソースをクラスターから削除できます。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。
  • OpenShift Container Platform Web コンソールにアクセスできる。

手順

  1. OpenShift Container Platform Web コンソールにログインします。
  2. Secondary Scheduler Operator によってインストールされた CRD を削除します。

    1. AdministrationCustomResourceDefinitions に移動します。
    2. Name フィールドに SecondaryScheduler を入力して CRD をフィルターします。
    3. SecondaryScheduler CRD の横にある Options メニュー kebab をクリックし、Delete Custom Resource Definition を選択します。
  3. openshift-secondary-scheduler-operator namespace を削除します。

    1. AdministrationNamespaces に移動します。
    2. openshift-secondary-scheduler-operator の横にあるオプションメニュー kebab をクリックし、namespace の削除 を選択します。
    3. 確認ダイアログで、フィールドに openshift-secondary-scheduler-operator を入力し、Delete をクリックします。

第5章 ジョブと DaemonSet の使用

5.1. デーモンセットによるノード上でのバックグラウンドタスクの自動的な実行

管理者は、デーモンセットを作成して OpenShift Container Platform クラスター内の特定の、またはすべてのノードで Pod のレプリカを実行するために使用できます。

デーモンセットは、すべて (または一部) のノードで Pod のコピーが確実に実行されるようにします。ノードがクラスターに追加されると、Pod がクラスターに追加されます。ノードがクラスターから削除されると、Pod はガベージコレクションによって削除されます。デーモンセットを削除すると、デーモンセットによって作成された Pod がクリーンアップされます。

デーモンセットを使用して共有ストレージを作成し、クラスター内のすべてのノードでロギング Pod を実行するか、すべてのノードでモニターエージェントをデプロイできます。

セキュリティー上の理由から、クラスター管理者とプロジェクト管理者がデーモンセットを作成できます。

デーモンセットの詳細は、Kubernetes ドキュメント を参照してください。

重要

デーモンセットのスケジューリングにはプロジェクトのデフォルトノードセレクターとの互換性がありません。これを無効にしない場合、デーモンセットはデフォルトのノードセレクターとのマージによって制限されます。これにより、マージされたノードセレクターで選択解除されたノードで Pod が頻繁に再作成されるようになり、クラスターに不要な負荷が加わります。

5.1.1. デフォルトスケジューラーによるスケジュール

デーモンセットは、適格なすべてのノードで Pod のコピーが確実に実行されるようにします。通常は、Pod が実行されるノードは Kubernetes のスケジューラーが選択します。ただし、デーモンセット Pod はデーモンセットコントローラーによって作成され、スケジュールされます。その結果、以下のような問題が生じています。

  • Pod の動作に一貫性がない。スケジューリングを待機している通常の Pod は、作成されると Pending 状態になりますが、デーモンセット Pod は作成されても Pending 状態になりません。これによりユーザーに混乱が生じます。
  • Pod のプリエンプションがデフォルトのスケジューラーで処理される。プリエンプションが有効にされると、デーモンセットコントローラーは Pod の優先順位とプリエンプションを考慮することなくスケジューリングの決定を行います。

ScheduleDaemonSetPods 機能は、OpenShift Container Platform でデフォルトで有効にされます。これにより、spec.nodeName の条件 (term) ではなく NodeAffinity の条件 (term) をデーモンセット Pod に追加することで、デーモンセットコントローラーではなくデフォルトのスケジューラーを使用してデーモンセットをスケジュールすることができます。その後、デフォルトのスケジューラーは、Pod をターゲットホストにバインドさせるために使用されます。デーモンセット Pod のノードアフィニティーがすでに存在する場合、これは置き換えられます。デーモンセットコントローラーは、デーモンセット Pod を作成または変更する場合にのみこれらの操作を実行し、デーモンセットの spec.template は一切変更されません。

kind: Pod
apiVersion: v1
metadata:
  name: hello-node-6fbccf8d9-9tmzr
#...
spec:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchFields:
        - key: metadata.name
          operator: In
          values:
          - target-host-name
#...

さらに、node.kubernetes.io/unschedulable:NoSchedule の toleration がデーモンセット Pod に自動的に追加されます。デフォルトのスケジューラーは、デーモンセット Pod をスケジュールする際に、スケジュールできないノードを無視します。

5.1.2. デーモンセットの作成

デーモンセットの作成時に、nodeSelector フィールドは、デーモンセットがレプリカをデプロイする必要のあるノードを指定するために使用されます。

前提条件

  • デーモンセットの使用を開始する前に、namespace のアノテーション openshift.io/node-selector を空の文字列に設定することで、namespace のプロジェクトスコープのデフォルトのノードセレクターを無効にします。

    $ oc patch namespace myproject -p \
        '{"metadata": {"annotations": {"openshift.io/node-selector": ""}}}'
    ヒント

    または、以下の YAML を適用して、プロジェクト全体で namespace のデフォルトのノードセレクターを無効にすることもできます。

    apiVersion: v1
    kind: Namespace
    metadata:
      name: <namespace>
      annotations:
        openshift.io/node-selector: ''
    #...
  • 新規プロジェクトを作成している場合は、デフォルトのノードセレクターを上書きします。

    $ oc adm new-project <name> --node-selector=""

手順

デーモンセットを作成するには、以下を実行します。

  1. デーモンセット yaml ファイルを定義します。

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: hello-daemonset
    spec:
      selector:
          matchLabels:
            name: hello-daemonset 1
      template:
        metadata:
          labels:
            name: hello-daemonset 2
        spec:
          nodeSelector: 3
            role: worker
          containers:
          - image: openshift/hello-openshift
            imagePullPolicy: Always
            name: registry
            ports:
            - containerPort: 80
              protocol: TCP
            resources: {}
            terminationMessagePath: /dev/termination-log
          serviceAccount: default
          terminationGracePeriodSeconds: 10
    #...
    1
    デーモンセットに属する Pod を判別するラベルセレクターです。
    2
    Pod テンプレートのラベルセレクターです。上記のラベルセレクターに一致している必要があります。
    3
    Pod レプリカをデプロイする必要があるノードを判別するノードセレクターです。一致するラベルがこのノードに存在する必要があります。
  2. デーモンセットオブジェクトを作成します。

    $ oc create -f daemonset.yaml
  3. Pod が作成されていることを確認し、各 Pod に Pod レプリカがあることを確認するには、以下を実行します。

    1. daemonset Pod を検索します。

      $ oc get pods

      出力例

      hello-daemonset-cx6md   1/1       Running   0          2m
      hello-daemonset-e3md9   1/1       Running   0          2m

    2. Pod がノードに配置されていることを確認するために Pod を表示します。

      $ oc describe pod/hello-daemonset-cx6md|grep Node

      出力例

      Node:        openshift-node01.hostname.com/10.14.20.134

      $ oc describe pod/hello-daemonset-e3md9|grep Node

      出力例

      Node:        openshift-node02.hostname.com/10.14.20.137

重要
  • デーモンセット Pod テンプレートを更新しても、既存の Pod レプリカには影響はありません。
  • デーモンセットを削除してから、異なるテンプレートと同じラベルセレクターを使用して新規のデーモンセットを作成する場合に、既存の Pod レプリカについてラベルが一致していると認識するため、既存の Pod レプリカは更新されず、Pod テンプレートで一致しない場合でも新しいレプリカが作成されます。
  • ノードのラベルを変更する場合には、デーモンセットは新しいラベルと一致するノードに Pod を追加し、新しいラベルと一致しないノードから Pod を削除します。

デーモンセットを更新するには、古いレプリカまたはノードを削除して新規の Pod レプリカの作成を強制的に実行します。

5.2. ジョブの使用による Pod でのタスクの実行

job は、OpenShift Container Platform クラスターのタスクを実行します。

ジョブは、タスクの全体的な進捗状況を追跡し、進行中、完了、および失敗した各 Pod の情報を使用してその状態を更新します。ジョブを削除するとそのジョブによって作成された Pod のレプリカがクリーンアップされます。ジョブは Kubernetes API の一部で、他のオブジェクトタイプ同様に oc コマンドで管理できます。

ジョブ仕様のサンプル

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  parallelism: 1    1
  completions: 1    2
  activeDeadlineSeconds: 1800 3
  backoffLimit: 6   4
  template:         5
    metadata:
      name: pi
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: OnFailure    6
#...

1
ジョブの Pod レプリカは並行して実行される必要があります。
2
ジョブの完了をマークするには、Pod の正常な完了が必要です。
3
ジョブを実行できる最長期間。
4
ジョブの再試行回数。
5
コントローラーが作成する Pod のテンプレート。
6
Pod の再起動ポリシー。

関連情報

5.2.1. ジョブと cron ジョブについて

ジョブは、タスクの全体的な進捗状況を追跡し、進行中、完了、および失敗した各 Pod の情報を使用してその状態を更新します。ジョブを削除するとそのジョブによって作成された Pod がクリーンアップされます。ジョブは Kubernetes API の一部で、他のオブジェクトタイプ同様に oc コマンドで管理できます。

OpenShift Container Platform で一度だけ実行するオブジェクトを作成できるリソースタイプは 2 種類あります。

ジョブ

定期的なジョブは、タスクを作成しジョブが完了したことを確認する、一度だけ実行するオブジェクトです。

ジョブとして実行するには、主に以下のタスクタイプを使用できます。

  • 非並列ジョブ:

    • Pod が失敗しない限り、単一の Pod のみを起動するジョブ。
    • このジョブは、Pod が正常に終了するとすぐに完了します。
  • 固定の完了数が指定された並列ジョブ

    • 複数の Pod を起動するジョブ。
    • ジョブはタスク全体を表し、1 から completions 値までの範囲内のそれぞれの値に対して 1 つの正常な Pod がある場合に完了します。
  • ワークキューを含む並列ジョブ:

    • 指定された Pod に複数の並列ワーカープロセスを持つジョブ。
    • OpenShift Container Platform は Pod を調整し、それぞれの機能を判別するか、外部キューサービスを使用します。
    • 各 Pod はそれぞれ、すべてのピア Pod が完了しているかどうかや、ジョブ全体が実行済みであることを判別することができます。
    • ジョブからの Pod が正常な状態で終了すると、新規 Pod は作成されません。
    • 1 つ以上の Pod が正常な状態で終了し、すべての Pod が終了している場合、ジョブが正常に完了します。
    • Pod が正常な状態で終了した場合、それ以外の Pod がこのタスクについて機能したり、または出力を書き込むことはありません。Pod はすべて終了プロセスにあるはずです。

      各種のジョブを使用する方法の詳細は、Kubernetes ドキュメントの Job Patterns を参照してください。

Cron ジョブ

ジョブは、cron ジョブを使用して複数回実行するようにスケジュールすることが可能です。

cron ジョブ は、ユーザーがジョブの実行方法を指定することを可能にすることで、定期的なジョブを積み重ねます。Cron ジョブは Kubernetes API の一部であり、他のオブジェクトタイプと同様に oc コマンドで管理できます。

Cron ジョブは、バックアップの実行やメールの送信など周期的な繰り返しのタスクを作成する際に役立ちます。また、低アクティビティー期間にジョブをスケジュールする場合など、特定の時間に個別のタスクをスケジュールすることも可能です。cron ジョブは、cronjob コントローラーを実行するコントロールプレーンノードに設定されたタイムゾーンに基づいて Job オブジェクトを作成します。

警告

cron ジョブはスケジュールの実行時間ごとに約 1 回ずつ Job オブジェクトを作成しますが、ジョブの作成に失敗したり、2 つのジョブが作成される場合があります。そのためジョブはべき等である必要があり、履歴制限を設定する必要があります。

5.2.1.1. ジョブの作成方法

どちらのリソースタイプにも、以下の主要な要素から構成されるジョブ設定が必要です。

  • OpenShift Container Platform が作成する Pod を記述している Pod テンプレート。
  • parallelism パラメーター。ジョブの実行に使用する、同時に実行される Pod の数を指定します。

    • 非並列ジョブの場合は、未設定のままにします。未設定の場合は、デフォルトの 1 に設定されます。
  • completions パラメーター。ジョブを完了するために必要な、正常に完了した Pod の数を指定します。

    • 非並列ジョブの場合は、未設定のままにします。未設定の場合は、デフォルトの 1 に設定されます。
    • 固定の完了数を持つ並列ジョブの場合は、値を指定します。
    • ワークキューのある並列ジョブでは、未設定のままにします。未設定の場合、デフォルトは parallelism 値に設定されます。
5.2.1.2. ジョブの最長期間を設定する方法

ジョブの定義時に、activeDeadlineSeconds フィールドを設定して最長期間を定義できます。これは秒単位で指定され、デフォルトでは設定されません。設定されていない場合は、実施される最長期間はありません。

最長期間は、最初の Pod がスケジュールされた時点から計算され、ジョブが有効である期間を定義します。これは実行の全体の時間を追跡します。指定されたタイムアウトに達すると、OpenShift Container Platform がジョブを終了します。

5.2.1.3. 失敗した Pod のためのジョブのバックオフポリシーを設定する方法

ジョブは、設定の論理的なエラーなどの理由により再試行の設定回数を超えた後に失敗とみなされる場合があります。ジョブに関連付けられた失敗した Pod は 6 分を上限として指数関数的バックオフ遅延値 (10s20s40s …) に基づいて再作成されます。この制限は、コントローラーのチェック間で失敗した Pod が新たに生じない場合に再設定されます。

ジョブの再試行回数を設定するには spec.backoffLimit パラメーターを使用します。

5.2.1.4. アーティファクトを削除するように cron ジョブを設定する方法

Cron ジョブはジョブや Pod などのアーティファクトリーソースをそのままにすることがあります。ユーザーは履歴制限を設定して古いジョブとそれらの Pod が適切に消去されるようにすることが重要です。これに対応する 2 つのフィールドが cron ジョブ仕様にあります。

  • .spec.successfulJobsHistoryLimit。保持する成功した終了済みジョブの数 (デフォルトは 3 に設定)。
  • .spec.failedJobsHistoryLimit。保持する失敗した終了済みジョブの数 (デフォルトは 1 に設定)。
ヒント
  • 必要なくなった cron ジョブを削除します。

    $ oc delete cronjob/<cron_job_name>

    これを実行することで、不要なアーティファクトの生成を防げます。

  • spec.suspend を true に設定することで、その後の実行を中断することができます。その後のすべての実行は、false に再設定するまで中断されます。
5.2.1.5. 既知の制限

ジョブ仕様の再起動ポリシーは Pod にのみ適用され、ジョブコントローラー には適用されません。ただし、ジョブコントローラーはジョブを完了まで再試行するようハードコーディングされます。

そのため restartPolicy: Never または --restart=Never により、restartPolicy: OnFailure または --restart=OnFailure と同じ動作が実行されます。つまり、ジョブが失敗すると、成功するまで (または手動で破棄されるまで) 自動で再起動します。このポリシーは再起動するサブシステムのみを設定します。

Never ポリシーでは、ジョブコントローラー が再起動を実行します。それぞれの再試行時に、ジョブコントローラーはジョブステータスの失敗数を増分し、新規 Pod を作成します。これは、それぞれの試行が失敗するたびに Pod の数が増えることを意味します。

OnFailure ポリシーでは、kubelet が再起動を実行します。それぞれの試行によりジョブステータスでの失敗数が増分する訳ではありません。さらに、kubelet は同じノードで Pod の起動に失敗したジョブを再試行します。

5.2.2. ジョブの作成

ジョブオブジェクトを作成して OpenShift Container Platform にジョブを作成します。

手順

ジョブを作成するには、以下を実行します。

  1. 以下のような YAML ファイルを作成します。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: pi
    spec:
      parallelism: 1    1
      completions: 1    2
      activeDeadlineSeconds: 1800 3
      backoffLimit: 6   4
      template:         5
        metadata:
          name: pi
        spec:
          containers:
          - name: pi
            image: perl
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
          restartPolicy: OnFailure    6
    #...
    1
    オプション: ジョブを並行して実行する Pod レプリカの数を指定します。デフォルトは 1 です。
    • 非並列ジョブの場合は、未設定のままにします。未設定の場合は、デフォルトの 1 に設定されます。
    2
    オプション: ジョブの完了をマークするために必要な Pod の正常な完了の数を指定します。
    • 非並列ジョブの場合は、未設定のままにします。未設定の場合は、デフォルトの 1 に設定されます。
    • 固定の完了数を持つ並列ジョブの場合、完了の数を指定します。
    • ワークキューのある並列ジョブでは、未設定のままにします。未設定の場合、デフォルトは parallelism 値に設定されます。
    3
    オプション: ジョブを実行できる最大期間を指定します。
    4
    オプション: ジョブの再試行回数を指定します。このフィールドは、デフォルトでは 6 に設定されています。
    5
    コントローラーが作成する Pod のテンプレートを指定します。
    6
    Pod の再起動ポリシーを指定します。
    • Never.ジョブを再起動しません。
    • OnFailure.ジョブが失敗した場合にのみ再起動します。
    • Alwaysジョブを常に再起動します。

      OpenShift Container Platform が失敗したコンテナーに再起動ポリシーを使用する方法の詳細は、Kubernetes ドキュメントの State の例 を参照してください。

  2. ジョブを作成します。

    $ oc create -f <file-name>.yaml
注記

oc create job を使用して単一コマンドからジョブを作成し、起動することもできます。以下のコマンドは直前の例に指定されている同じジョブを作成し、これを起動します。

$ oc create job pi --image=perl -- perl -Mbignum=bpi -wle 'print bpi(2000)'

5.2.3. cron ジョブの作成

ジョブオブジェクトを作成して OpenShift Container Platform に cron ジョブを作成します。

手順

cron ジョブを作成するには、以下を実行します。

  1. 以下のような YAML ファイルを作成します。

    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: pi
    spec:
      schedule: "*/1 * * * *"          1
      timeZone: Etc/UTC                2
      concurrencyPolicy: "Replace"     3
      startingDeadlineSeconds: 200     4
      suspend: true                    5
      successfulJobsHistoryLimit: 3    6
      failedJobsHistoryLimit: 1        7
      jobTemplate:                     8
        spec:
          template:
            metadata:
              labels:                  9
                parent: "cronjobpi"
            spec:
              containers:
              - name: pi
                image: perl
                command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
              restartPolicy: OnFailure 10
    #...
    1
    cron 形式 で指定されたジョブのスケジュール。この例では、ジョブは毎分実行されます。
    2
    スケジュールのオプションのタイムゾーン。有効なオプションは、tz データベースのタイムゾーンのリスト を参照してください。指定しない場合、Kubernetes コントローラーマネージャーは、ローカルタイムゾーンを基準にしてスケジュールを解釈します。
    3
    オプションの同時実行ポリシー。cron ジョブ内での同時実行ジョブを処理する方法を指定します。以下の同時実行ポリシーの 1 つのみを指定できます。これが指定されない場合、同時実行を許可するようにデフォルト設定されます。
    • Allow: cron ジョブを同時に実行できます。
    • Forbid: 同時実行を禁止し、直前の実行が終了していない場合は次の実行を省略します。
    • Replace: 同時に実行されているジョブを取り消し、これを新規ジョブに置き換えます。
    4
    ジョブを開始するためのオプションの期限 (秒単位)(何らかの理由によりスケジュールされた時間が経過する場合)。ジョブの実行が行われない場合、ジョブの失敗としてカウントされます。これが指定されない場合は期間が設定されません。
    5
    cron ジョブの停止を許可するオプションのフラグ。これが true に設定されている場合、後続のすべての実行が停止されます。
    6
    保持する成功した終了済みジョブの数 (デフォルトは 3 に設定)。
    7
    保持する失敗した終了済みジョブの数 (デフォルトは 1 に設定)。
    8
    ジョブテンプレート。これはジョブの例と同様です。
    9
    この cron ジョブで生成されるジョブのラベルを設定します。
    10
    Pod の再起動ポリシー。ジョブコントローラーには適用されません。
  2. cron ジョブを作成します。

    $ oc create -f <file-name>.yaml
注記

oc create cronjob を使用して単一コマンドから cron ジョブを作成し、起動することもできます。以下のコマンドは直前の例で指定されている同じ cron ジョブを作成し、これを起動します。

$ oc create cronjob pi --image=perl --schedule='*/1 * * * *' -- perl -Mbignum=bpi -wle 'print bpi(2000)'

oc create cronjob で、--schedule オプションは cron 形式 のスケジュールを受け入れます。

第6章 ノードの使用

6.1. OpenShift Container Platform クラスター内のノードの閲覧とリスト表示

クラスターのすべてのノードをリスト表示し、ステータスや経過時間、メモリー使用量などの情報およびノードの詳細を取得できます。

ノード管理の操作を実行すると、CLI は実際のノードホストの表現であるノードオブジェクトと対話します。マスターはノードオブジェクトの情報を使用してヘルスチェックでノードを検証します。

6.1.1. クラスター内のすべてのノードのリスト表示について

クラスター内のノードに関する詳細な情報を取得できます。

  • 以下のコマンドは、すべてのノードをリスト表示します。

    $ oc get nodes

    以下の例は、正常なノードを持つクラスターです。

    $ oc get nodes

    出力例

    NAME                   STATUS    ROLES     AGE       VERSION
    master.example.com     Ready     master    7h        v1.27.3
    node1.example.com      Ready     worker    7h        v1.27.3
    node2.example.com      Ready     worker    7h        v1.27.3

    以下の例は、正常でないノードが 1 つ含まれるクラスターです。

    $ oc get nodes

    出力例

    NAME                   STATUS                      ROLES     AGE       VERSION
    master.example.com     Ready                       master    7h        v1.27.3
    node1.example.com      NotReady,SchedulingDisabled worker    7h        v1.27.3
    node2.example.com      Ready                       worker    7h        v1.27.3

    NotReady ステータスをトリガーする条件は、このセクションの後半で説明します。

  • -o wide オプションは、ノードに関する追加情報を提供します。

    $ oc get nodes -o wide

    出力例

    NAME                STATUS   ROLES    AGE    VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                                                       KERNEL-VERSION                 CONTAINER-RUNTIME
    master.example.com  Ready    master   171m   v1.27.3   10.0.129.108   <none>        Red Hat Enterprise Linux CoreOS 48.83.202103210901-0 (Ootpa)   4.18.0-240.15.1.el8_3.x86_64   cri-o://1.27.3-30.rhaos4.10.gitf2f339d.el8-dev
    node1.example.com   Ready    worker   72m    v1.27.3   10.0.129.222   <none>        Red Hat Enterprise Linux CoreOS 48.83.202103210901-0 (Ootpa)   4.18.0-240.15.1.el8_3.x86_64   cri-o://1.27.3-30.rhaos4.10.gitf2f339d.el8-dev
    node2.example.com   Ready    worker   164m   v1.27.3   10.0.142.150   <none>        Red Hat Enterprise Linux CoreOS 48.83.202103210901-0 (Ootpa)   4.18.0-240.15.1.el8_3.x86_64   cri-o://1.27.3-30.rhaos4.10.gitf2f339d.el8-dev

  • 以下のコマンドは、単一のノードに関する情報をリスト表示します。

    $ oc get node <node>

    以下に例を示します。

    $ oc get node node1.example.com

    出力例

    NAME                   STATUS    ROLES     AGE       VERSION
    node1.example.com      Ready     worker    7h        v1.27.3

  • 以下のコマンドを実行すると、現在の状態の理由を含む、特定ノードの詳細情報を取得できます。

    $ oc describe node <node>

    以下に例を示します。

    $ oc describe node node1.example.com

    出力例

    Name:               node1.example.com 1
    Roles:              worker 2
    Labels:             kubernetes.io/os=linux
                        kubernetes.io/hostname=ip-10-0-131-14
                        kubernetes.io/arch=amd64 3
                        node-role.kubernetes.io/worker=
                        node.kubernetes.io/instance-type=m4.large
                        node.openshift.io/os_id=rhcos
                        node.openshift.io/os_version=4.5
                        region=east
                        topology.kubernetes.io/region=us-east-1
                        topology.kubernetes.io/zone=us-east-1a
    Annotations:        cluster.k8s.io/machine: openshift-machine-api/ahardin-worker-us-east-2a-q5dzc  4
                        machineconfiguration.openshift.io/currentConfig: worker-309c228e8b3a92e2235edd544c62fea8
                        machineconfiguration.openshift.io/desiredConfig: worker-309c228e8b3a92e2235edd544c62fea8
                        machineconfiguration.openshift.io/state: Done
                        volumes.kubernetes.io/controller-managed-attach-detach: true
    CreationTimestamp:  Wed, 13 Feb 2019 11:05:57 -0500
    Taints:             <none>  5
    Unschedulable:      false
    Conditions:                 6
      Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
      ----             ------  -----------------                 ------------------                ------                       -------
      OutOfDisk        False   Wed, 13 Feb 2019 15:09:42 -0500   Wed, 13 Feb 2019 11:05:57 -0500   KubeletHasSufficientDisk     kubelet has sufficient disk space available
      MemoryPressure   False   Wed, 13 Feb 2019 15:09:42 -0500   Wed, 13 Feb 2019 11:05:57 -0500   KubeletHasSufficientMemory   kubelet has sufficient memory available
      DiskPressure     False   Wed, 13 Feb 2019 15:09:42 -0500   Wed, 13 Feb 2019 11:05:57 -0500   KubeletHasNoDiskPressure     kubelet has no disk pressure
      PIDPressure      False   Wed, 13 Feb 2019 15:09:42 -0500   Wed, 13 Feb 2019 11:05:57 -0500   KubeletHasSufficientPID      kubelet has sufficient PID available
      Ready            True    Wed, 13 Feb 2019 15:09:42 -0500   Wed, 13 Feb 2019 11:07:09 -0500   KubeletReady                 kubelet is posting ready status
    Addresses:   7
      InternalIP:   10.0.140.16
      InternalDNS:  ip-10-0-140-16.us-east-2.compute.internal
      Hostname:     ip-10-0-140-16.us-east-2.compute.internal
    Capacity:    8
     attachable-volumes-aws-ebs:  39
     cpu:                         2
     hugepages-1Gi:               0
     hugepages-2Mi:               0
     memory:                      8172516Ki
     pods:                        250
    Allocatable:
     attachable-volumes-aws-ebs:  39
     cpu:                         1500m
     hugepages-1Gi:               0
     hugepages-2Mi:               0
     memory:                      7558116Ki
     pods:                        250
    System Info:    9
     Machine ID:                              63787c9534c24fde9a0cde35c13f1f66
     System UUID:                             EC22BF97-A006-4A58-6AF8-0A38DEEA122A
     Boot ID:                                 f24ad37d-2594-46b4-8830-7f7555918325
     Kernel Version:                          3.10.0-957.5.1.el7.x86_64
     OS Image:                                Red Hat Enterprise Linux CoreOS 410.8.20190520.0 (Ootpa)
     Operating System:                        linux
     Architecture:                            amd64
     Container Runtime Version:               cri-o://1.27.3-0.6.dev.rhaos4.3.git9ad059b.el8-rc2
     Kubelet Version:                         v1.27.3
     Kube-Proxy Version:                      v1.27.3
    PodCIDR:                                  10.128.4.0/24
    ProviderID:                               aws:///us-east-2a/i-04e87b31dc6b3e171
    Non-terminated Pods:                      (12 in total)  10
      Namespace                               Name                                   CPU Requests  CPU Limits  Memory Requests  Memory Limits
      ---------                               ----                                   ------------  ----------  ---------------  -------------
      openshift-cluster-node-tuning-operator  tuned-hdl5q                            0 (0%)        0 (0%)      0 (0%)           0 (0%)
      openshift-dns                           dns-default-l69zr                      0 (0%)        0 (0%)      0 (0%)           0 (0%)
      openshift-image-registry                node-ca-9hmcg                          0 (0%)        0 (0%)      0 (0%)           0 (0%)
      openshift-ingress                       router-default-76455c45c-c5ptv         0 (0%)        0 (0%)      0 (0%)           0 (0%)
      openshift-machine-config-operator       machine-config-daemon-cvqw9            20m (1%)      0 (0%)      50Mi (0%)        0 (0%)
      openshift-marketplace                   community-operators-f67fh              0 (0%)        0 (0%)      0 (0%)           0 (0%)
      openshift-monitoring                    alertmanager-main-0                    50m (3%)      50m (3%)    210Mi (2%)       10Mi (0%)
      openshift-monitoring                    node-exporter-l7q8d                    10m (0%)      20m (1%)    20Mi (0%)        40Mi (0%)
      openshift-monitoring                    prometheus-adapter-75d769c874-hvb85    0 (0%)        0 (0%)      0 (0%)           0 (0%)
      openshift-multus                        multus-kw8w5                           0 (0%)        0 (0%)      0 (0%)           0 (0%)
      openshift-sdn                           ovs-t4dsn                              100m (6%)     0 (0%)      300Mi (4%)       0 (0%)
      openshift-sdn                           sdn-g79hg                              100m (6%)     0 (0%)      200Mi (2%)       0 (0%)
    Allocated resources:
      (Total limits may be over 100 percent, i.e., overcommitted.)
      Resource                    Requests     Limits
      --------                    --------     ------
      cpu                         380m (25%)   270m (18%)
      memory                      880Mi (11%)  250Mi (3%)
      attachable-volumes-aws-ebs  0            0
    Events:     11
      Type     Reason                   Age                From                      Message
      ----     ------                   ----               ----                      -------
      Normal   NodeHasSufficientPID     6d (x5 over 6d)    kubelet, m01.example.com  Node m01.example.com status is now: NodeHasSufficientPID
      Normal   NodeAllocatableEnforced  6d                 kubelet, m01.example.com  Updated Node Allocatable limit across pods
      Normal   NodeHasSufficientMemory  6d (x6 over 6d)    kubelet, m01.example.com  Node m01.example.com status is now: NodeHasSufficientMemory
      Normal   NodeHasNoDiskPressure    6d (x6 over 6d)    kubelet, m01.example.com  Node m01.example.com status is now: NodeHasNoDiskPressure
      Normal   NodeHasSufficientDisk    6d (x6 over 6d)    kubelet, m01.example.com  Node m01.example.com status is now: NodeHasSufficientDisk
      Normal   NodeHasSufficientPID     6d                 kubelet, m01.example.com  Node m01.example.com status is now: NodeHasSufficientPID
      Normal   Starting                 6d                 kubelet, m01.example.com  Starting kubelet.
    #...

    1
    ノードの名前。
    2
    ノードのロール (master または worker のいずれか)。
    3
    ノードに適用されたラベル。
    4
    ノードに適用されるアノテーション。
    5
    ノードに適用された taint。
    6
    ノードの状態およびステータス。conditions スタンザには、ReadyPIDPressureMemoryPressureDiskPressure、および OutOfDisk ステータスがリスト表示されます。これらの状態については、このセクションの後半で説明します。
    7
    ノードの IP アドレスとホスト名。
    8
    Pod のリソースと割り当て可能なリソース。
    9
    ノードホストに関する情報。
    10
    ノードの Pod。
    11
    ノードが報告したイベント。
注記

新しく作成されたマスターノードや更新されたマスターノードに、コントロールプレーンラベルは自動的に追加されません。ノードにコントロールプレーンラベルを使用する必要がある場合は、ラベルを手動で設定できます。詳細は、関連資料 セクションの ノードのラベルの更新方法 を参照してください。

ノードの情報の中でも、とりわけ以下のノードの状態がこのセクションで説明されるコマンドの出力に表示されます。

表6.1 ノードの状態
条件説明

Ready

true の場合、ノードは正常であり、Pod を受け入れることのできる準備状態にあります。false の場合、ノードは正常ではなく、Pod を受け入れません。unknown の場合、ノードコントローラーは node-monitor-grace-period (デフォルトは 40 秒) の間にハートビートをノードから受信しませんでした。

DiskPressure

true の場合、ディスク容量は低くなります。

MemoryPressure

true の場合、ノードのメモリーは低くなります。

PIDPressure

true の場合、ノードのプロセスが多すぎます。

OutOfDisk

true の場合、ノードには新しい Pod を追加するためのノード上の空きスペースが十分にありません。

NetworkUnavailable

true の場合、ノードのネットワークは正しく設定されていません。

NotReady

true の場合、コンテナーのランタイムやネットワークなど基本のコンポーネントのいずれかに問題が発生しているか、それらがまだ設定されていません。

SchedulingDisabled

ノードに配置するように Pod をスケジュールすることができません。

6.1.2. クラスターでのノード上の Pod のリスト表示

特定のノード上のすべての Pod をリスト表示できます。

手順

  • 1 つ以上のノードにすべてまたは選択した Pod をリスト表示するには、以下を実行します。

    $ oc describe node <node1> <node2>

    以下に例を示します。

    $ oc describe node ip-10-0-128-218.ec2.internal
  • 選択したノードのすべてまたは選択した Pod をリスト表示するには、以下を実行します。

    $ oc describe node --selector=<node_selector>
    $ oc describe node --selector=kubernetes.io/os

    または、以下を実行します。

    $ oc describe node -l=<pod_selector>
    $ oc describe node -l node-role.kubernetes.io/worker
  • 終了した Pod を含む、特定のノード上のすべての Pod をリスト表示するには、以下を実行します。

    $ oc get pod --all-namespaces --field-selector=spec.nodeName=<nodename>

6.1.3. ノードのメモリーと CPU 使用統計の表示

コンテナーのランタイム環境を提供する、ノードに関する使用状況の統計を表示できます。これらの使用状況の統計には CPU、メモリー、およびストレージの消費量が含まれます。

前提条件

  • 使用状況の統計を表示するには、cluster-reader 権限が必要です。
  • 使用状況の統計を表示するには、メトリクスをインストールしている必要があります。

手順

  • 使用状況の統計を表示するには、以下を実行します。

    $ oc adm top nodes

    出力例

    NAME                                   CPU(cores)   CPU%      MEMORY(bytes)   MEMORY%
    ip-10-0-12-143.ec2.compute.internal    1503m        100%      4533Mi          61%
    ip-10-0-132-16.ec2.compute.internal    76m          5%        1391Mi          18%
    ip-10-0-140-137.ec2.compute.internal   398m         26%       2473Mi          33%
    ip-10-0-142-44.ec2.compute.internal    656m         43%       6119Mi          82%
    ip-10-0-146-165.ec2.compute.internal   188m         12%       3367Mi          45%
    ip-10-0-19-62.ec2.compute.internal     896m         59%       5754Mi          77%
    ip-10-0-44-193.ec2.compute.internal    632m         42%       5349Mi          72%

  • ラベルの付いたノードの使用状況の統計を表示するには、以下を実行します。

    $ oc adm top node --selector=''

    フィルターに使用するセレクター (ラベルクエリー) を選択する必要があります。===、および != をサポートします。

6.2. ノードの使用

管理者は、複数のタスクを実行して、クラスターを効率化できます。

6.2.1. ノード上の Pod を退避させる方法

Pod を退避させると、所定のノードからすべての Pod または選択した Pod を移行できます。

退避させることができるのは、レプリケーションコントローラーが管理している Pod のみです。レプリケーションコントローラーは、他のノードに新しい Pod を作成し、指定されたノードから既存の Pod を削除します。

ベア Pod、つまりレプリケーションコントローラーが管理していない Pod はデフォルトで影響を受けません。Pod セレクターを指定すると Pod のサブセットを退避できます。Pod セレクターはラベルに基づくので、指定したラベルを持つすべての Pod を退避できます。

手順

  1. Pod の退避を実行する前に、ノードをスケジュール対象外としてマークします。

    1. ノードにスケジュール対象外 (unschedulable) のマークを付けます。

      $ oc adm cordon <node1>

      出力例

      node/<node1> cordoned

    2. ノードのステータスが Ready,SchedulingDisabled であることを確認します。

      $ oc get node <node1>

      出力例

      NAME        STATUS                     ROLES     AGE       VERSION
      <node1>     Ready,SchedulingDisabled   worker    1d        v1.27.3

  2. 以下の方法のいずれかを使用して Pod を退避します。

    • 1 つ以上のノードで、すべてまたは選択した Pod を退避します。

      $ oc adm drain <node1> <node2> [--pod-selector=<pod_selector>]
    • --force オプションを使用してベア Pod の削除を強制的に実行します。true に設定されると、Pod がレプリケーションコントローラー、レプリカセット、ジョブ、デーモンセット、またはステートフルセットで管理されていない場合でも削除が続行されます。

      $ oc adm drain <node1> <node2> --force=true
    • --grace-period を使用して、各 Pod を正常に終了するための期間 (秒単位) を設定します。負の値の場合には、Pod に指定されるデフォルト値が使用されます。

      $ oc adm drain <node1> <node2> --grace-period=-1
    • true に設定された --ignore-daemonsets フラグを使用してデーモンセットが管理する Pod を無視します。

      $ oc adm drain <node1> <node2> --ignore-daemonsets=true
    • --timeout を使用して、中止する前の待機期間を設定します。値 0 は無限の時間を設定します。

      $ oc adm drain <node1> <node2> --timeout=5s
    • --delete-emptydir-data フラグを true に設定して、emptyDir ボリュームを使用する Pod がある場合にも Pod を削除します。ローカルデータはノードがドレイン (解放) される場合に削除されます。

      $ oc adm drain <node1> <node2> --delete-emptydir-data=true
    • true に設定された --dry-run オプションを使用して、実際に退避を実行せずに移行するオブジェクトをリスト表示します。

      $ oc adm drain <node1> <node2>  --dry-run=true

      特定のノード名 (例: <node1> <node2>) を指定する代わりに、--selector=<node_selector> オプションを使用し、選択したノードで Pod を退避することができます。

  3. 完了したら、ノードにスケジュール対象のマークを付けます。

    $ oc adm uncordon <node1>

6.2.2. ノードでラベルを更新する方法について

ノード上の任意のラベルを更新できます。

ノードラベルは、ノードがマシンによってバックアップされている場合でも、ノードが削除されると永続しません。

注記

MachineSet への変更は、コンピュートマシンセットが所有する既存のマシンには適用されません。たとえば、編集されたか、既存の MachineSet に追加されたラベルは、マシンセットに関連付けられた既存マシンおよびノードには伝播しません。

  • 以下のコマンドは、ノードのラベルを追加または更新します。

    $ oc label node <node> <key_1>=<value_1> ... <key_n>=<value_n>

    以下に例を示します。

    $ oc label nodes webconsole-7f7f6 unhealthy=true
    ヒント

    以下の YAML を適用してラベルを適用することもできます。

    kind: Node
    apiVersion: v1
    metadata:
      name: webconsole-7f7f6
      labels:
        unhealthy: 'true'
    #...
  • 以下のコマンドは、namespace 内のすべての Pod を更新します。

    $ oc label pods --all <key_1>=<value_1>

    以下に例を示します。

    $ oc label pods --all status=unhealthy

6.2.3. ノードをスケジュール対象外 (Unschedulable) またはスケジュール対象 (Schedulable) としてマークする方法

デフォルトで、Ready ステータスの正常なノードはスケジュール対象としてマークされます。つまり、新規 Pod をこのノードに配置できます。手動でノードをスケジュール対象外としてマークすると、新規 Pod のノードでのスケジュールがブロックされます。ノード上の既存 Pod には影響がありません。

  • 以下のコマンドは、ノードをスケジュール対象外としてマークします。

    出力例

    $ oc adm cordon <node>

    以下に例を示します。

    $ oc adm cordon node1.example.com

    出力例

    node/node1.example.com cordoned
    
    NAME                 LABELS                                        STATUS
    node1.example.com    kubernetes.io/hostname=node1.example.com      Ready,SchedulingDisabled

  • 以下のコマンドは、現時点でスケジュール対象外のノードをスケジュール対象としてマークします。

    $ oc adm uncordon <node1>

    または、特定のノード名 (たとえば <node>) を指定する代わりに、--selector=<node_selector> オプションを使用して選択したノードをスケジュール対象またはスケジュール対象外としてマークすることができます。

6.2.4. アプリケーション Pod をドレインせずにノードを再起動した場合の単一ノード OpenShift クラスターでのエラーの処理

単一ノードの OpenShift クラスターおよび OpenShift Container Platform クラスター一般では、最初にノードをドレインせずにノードの再起動が発生してしまう可能性があります。これは、デバイスを要求するアプリケーション Pod が UnexpectedAdmissionError エラーで失敗した場合に発生する可能性があります。DeploymentReplicaSet、または DaemonSet エラーが報告されるのは、これらのデバイスを必要とするアプリケーション Pod が、それらのデバイスにサービスを提供する Pod より前に開始されるためです。Pod の再起動の順序を制御できません。

この動作は想定範囲内ですが、正常にデプロイできなかった場合でも、Pod がクラスター上に残る可能性があります。Pod は、引き続き UnexpectedAdmissionError を報告します。この問題は、アプリケーション Pod が通常 DeploymentReplicaSet、または DaemonSet に含まれるため、軽減されます。Pod がこのエラー状態にある場合は、別のインスタンスが実行されているはずなので、ほとんど問題はありません。DeploymentReplicaSet、または DaemonSetの一部であることにより、後続の Pod の正常な作成と実行が保証され、アプリケーションは確実かつ正常にデプロイメントされます。

このような Pod が正常に終了するように、アップストリームで作業が進行されます。この作業が解決されるまで、単一ノードの OpenShift クラスターで失敗した Pod を削除するには、以下のコマンドを実行します。

$ oc delete pods --field-selector status.phase=Failed -n <POD_NAMESPACE>
注記

単一ノードの OpenShift クラスターでは、ノードをドレインするオプションは利用できません。

6.2.5. ノードの削除

6.2.5.1. クラスターからのノードの削除

OpenShift Container Platform クラスターからノードを削除するには、適切な MachineSet オブジェクトをスケールダウンします。

重要

クラスターがクラウドプロバイダーと統合されている場合、ノードを削除するには対応するマシンを削除する必要があります。このタスクに oc delete node コマンドは使用しないでください。

CLI を使用してノードを削除する場合、ノードオブジェクトは Kubernetes で削除されますが、ノード自体にある Pod は削除されません。レプリケーションコントローラーで管理されていないベア Pod は、OpenShift Container Platform からアクセスできなくなります。レプリケーションコントローラーで管理されるベア Pod は、他の利用可能なノードに再スケジュールされます。ローカルのマニフェスト Pod は削除する必要があります。

注記

ベアメタルでクラスターを実行している場合、MachineSet オブジェクトを編集してノードを削除することはできません。コンピュートマシンセットは、クラスターがクラウドプロバイダーに統合されている場合にのみ利用できます。代わりに、ノードを手作業で削除する前に、ノードをスケジュール解除し、ドレイン (解放) する必要があります。

手順

  1. 次のコマンドを実行して、クラスター内のコンピュートマシンセットを表示します。

    $ oc get machinesets -n openshift-machine-api

    コンピュートマシンセットは、<cluster-id>-worker-<aws-region-az> の形式で一覧表示されます。

  2. 次のいずれかの方法で、コンピュートマシンセットをスケールダウンします。

    • 次のコマンドを実行して、スケールダウンするレプリカの数を指定します。

      $ oc scale --replicas=2 machineset <machine-set-name> -n openshift-machine-api
    • 次のコマンドを実行して、コンピュートマシンセットのカスタムリソースを編集します。

      $ oc edit machineset <machine-set-name> -n openshift-machine-api

      出力例

      apiVersion: machine.openshift.io/v1beta1
      kind: MachineSet
      metadata:
        # ...
        name: <machine-set-name>
        namespace: openshift-machine-api
        # ...
      spec:
        replicas: 2 1
        # ...

      1
      スケールダウンするレプリカの数を指定します。
6.2.5.2. ベアメタルクラスターからのノードの削除

CLI を使用してノードを削除する場合、ノードオブジェクトは Kubernetes で削除されますが、ノード自体にある Pod は削除されません。レプリケーションコントローラーで管理されないベア Pod は、OpenShift Container Platform からはアクセスできなくなります。レプリケーションコントローラーで管理されるベア Pod は、他の利用可能なノードに再スケジュールされます。ローカルのマニフェスト Pod は削除する必要があります。

手順

以下の手順を実行して、ベアメタルで実行されている OpenShift Container Platform クラスターからノードを削除します。

  1. ノードにスケジュール対象外 (unschedulable) のマークを付けます。

    $ oc adm cordon <node_name>
  2. ノード上のすべての Pod をドレイン (解放) します。

    $ oc adm drain <node_name> --force=true

    このステップは、ノードがオフラインまたは応答しない場合に失敗する可能性があります。ノードが応答しない場合でも、共有ストレージに書き込むワークロードを実行している可能性があります。データの破損を防ぐには、続行する前に物理ハードウェアの電源を切ります。

  3. クラスターからノードを削除します。

    $ oc delete node <node_name>

    ノードオブジェクトはクラスターから削除されていますが、これは再起動後や kubelet サービスが再起動される場合にクラスターに再び参加することができます。ノードとそのすべてのデータを永続的に削除するには、ノードの使用を停止 する必要があります。

  4. 物理ハードウェアを電源を切っている場合は、ノードがクラスターに再度加わるように、そのハードウェアを再びオンに切り替えます。

6.3. ノードの管理

OpenShift Container Platform は、KubeletConfig カスタムリソース (CR) を使用してノードの設定を管理します。KubeletConfig オブジェクトのインスタンスを作成すると、マネージドのマシン設定がノードの設定を上書きするために作成されます。

注記

リモートマシンにログインして設定を変更する方法はサポートされていません。

6.3.1. ノードの変更

クラスターまたはマシンプールの設定を変更するには、カスタムリソース定義 (CRD) または kubeletConfig オブジェクトを作成する必要があります。OpenShift Container Platform は、Machine Config Controller を使用して、変更をクラスターに適用するために CRD を使用して導入された変更を監視します。

注記

kubeletConfig オブジェクトのフィールドは、アップストリームの Kubernetes から kubelet に直接渡されるため、これらのフィールドの検証は kubelet 自体によって直接処理されます。これらのフィールドの有効な値は、関連する Kubernetes のドキュメントを参照してください。kubeletConfig オブジェクトの値が無効な場合、クラスターノードが使用できなくなる可能性があります。

手順

  1. 設定する必要のあるノードタイプの静的な CRD、Machine Config Pool に関連付けられたラベルを取得します。以下のいずれかの手順を実行します。

    1. 必要なマシン設定プールの現在のラベルをチェックします。

      以下に例を示します。

      $  oc get machineconfigpool  --show-labels

      出力例

      NAME      CONFIG                                             UPDATED   UPDATING   DEGRADED   LABELS
      master    rendered-master-e05b81f5ca4db1d249a1bf32f9ec24fd   True      False      False      operator.machineconfiguration.openshift.io/required-for-upgrade=
      worker    rendered-worker-f50e78e1bc06d8e82327763145bfcf62   True      False      False

    2. 必要なマシン設定プールにカスタムラベルを追加します。

      以下に例を示します。

      $ oc label machineconfigpool worker custom-kubelet=enabled
  2. 設定の変更用に kubeletconfig カスタムリソース (CR) を作成します。

    以下に例を示します。

    custom-config CR の設定例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: custom-config 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          custom-kubelet: enabled 2
      kubeletConfig: 3
        podsPerCore: 10
        maxPods: 250
        systemReserved:
          cpu: 2000m
          memory: 1Gi
    #...

    1
    CR に名前を割り当てます。
    2
    設定変更を適用するラベルを指定します。これは、マシン設定プールに追加するラベルになります。
    3
    変更する必要のある新しい値を指定します。
  3. CR オブジェクトを作成します。

    $ oc create -f <file-name>

    以下に例を示します。

    $ oc create -f master-kube-config.yaml

ほとんどの Kubelet 設定オプション はユーザーが設定できます。以下のオプションは上書きが許可されていません。

  • CgroupDriver
  • ClusterDNS
  • ClusterDomain
  • StaticPodPath
注記

単一ノードに 50 を超えるイメージが含まれている場合、Pod のスケジューリングがノード間で不均衡になる可能性があります。これは、ノード上のイメージのリストがデフォルトで 50 に短縮されているためです。KubeletConfig オブジェクトを編集し、nodeStatusMaxImages の値を -1 に設定して、イメージの制限を無効にすることができます。

6.3.2. スケジュール対象としてのコントロールプレーンノードの設定

コントロールプレーンノードをスケジュール可能に設定できます。つまり、新しい Pod をマスターノードに配置できます。デフォルトでは、コントロールプレーンノードはスケジュール対象ではありません。

マスターをスケジュール対象 (Schedulable) に設定できますが、ワーカーノードを保持する必要があります。

注記

ワーカーノードのない OpenShift Container Platform をベアメタルクラスターにデプロイできます。この場合、コントロールプレーンノードはデフォルトでスケジュール対象としてマークされます。

mastersSchedulable フィールドを設定することで、コントロールプレーンノードをスケジュール対象として許可または禁止できます。

重要

コントロールプレーンノードをデフォルトのスケジュール不可からスケジュール可に設定するには、追加のサブスクリプションが必要です。これは、コントロールプレーンノードがワーカーノードになるためです。

手順

  1. schedulers.config.openshift.io リソースを編集します。

    $ oc edit schedulers.config.openshift.io cluster
  2. mastersSchedulable フィールドを設定します。

    apiVersion: config.openshift.io/v1
    kind: Scheduler
    metadata:
      creationTimestamp: "2019-09-10T03:04:05Z"
      generation: 1
      name: cluster
      resourceVersion: "433"
      selfLink: /apis/config.openshift.io/v1/schedulers/cluster
      uid: a636d30a-d377-11e9-88d4-0a60097bee62
    spec:
      mastersSchedulable: false 1
    status: {}
    #...
    1
    コントロールプレーンノードがスケジュール対象 (Schedulable) になることを許可する場合は true に設定し、コントロールプレーンノードがスケジュール対象になることを拒否する場合は、false に設定します。
  3. 変更を適用するためにファイルを保存します。

6.3.3. SELinux ブール値の設定

OpenShift Container Platform を使用すると、Red Hat Enterprise Linux CoreOS(RHCOS) ノードで SELinux ブール値を有効または無効にできます。次の手順では、Machine Config Operator(MCO) を使用してノード上の SELinux ブール値を変更する方法を説明します。この手順では、ブール値の例として container_manage_cgroup を使用します。この値は、必要なブール値に変更できます。

前提条件

  • OpenShift CLI (oc) がインストールされている。

手順

  1. 次の例に示すように、MachineConfig オブジェクトを使用して新しい YAML ファイルを作成します。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker
      name: 99-worker-setsebool
    spec:
      config:
        ignition:
          version: 3.2.0
        systemd:
          units:
          - contents: |
              [Unit]
              Description=Set SELinux booleans
              Before=kubelet.service
    
              [Service]
              Type=oneshot
              ExecStart=/sbin/setsebool container_manage_cgroup=on
              RemainAfterExit=true
    
              [Install]
              WantedBy=multi-user.target graphical.target
            enabled: true
            name: setsebool.service
    #...
  2. 次のコマンドを実行して、新しい MachineConfig オブジェクトを作成します。

    $ oc create -f 99-worker-setsebool.yaml
注記

MachineConfig オブジェクトに変更を適用すると、変更が適用された後、影響を受けるすべてのノードが正常に再起動します。

6.3.4. カーネル引数のノードへの追加

特殊なケースとして、クラスターのノードセットにカーネル引数を追加する必要がある場合があります。これは十分に注意して実行する必要があり、設定する引数による影響を十分に理解している必要があります。

警告

カーネル引数を正しく使用しないと、システムが起動不可能になる可能性があります。

設定可能なカーネル引数の例には、以下が含まれます。

  • nosmt: カーネルの対称マルチスレッド (SMT) を無効にします。マルチスレッドは、各 CPU の複数の論理スレッドを許可します。潜在的なクロススレッド攻撃に関連するリスクを減らすために、マルチテナント環境での nosmt の使用を検討できます。SMT を無効にすることは、基本的にパフォーマンスよりもセキュリティーを重視する選択をしていることになります。
  • systemd.unified_cgroup_hierarchy: Linux コントロールグループバージョン 2 (cgroup v2) を有効にします。cgroup v2 は、カーネル コントロールグループ の次のバージョンであり、複数の改善点を備えています。
  • enforcing=0: SELinux (Security Enhanced Linux) を Permissive モードで実行するように設定します。Permissive モードでは、システムは、SELinux が読み込んだセキュリティーポリシーを実行しているかのように動作します。これには、オブジェクトのラベル付けや、アクセスを拒否したエントリーをログに出力するなどの動作が含まれますが、いずれの操作も拒否される訳ではありません。Permissive モードは、実稼働システムでの使用はサポートされませんが、デバッグには役に立ちます。

    警告

    実稼働環境の RHCOS での SELinux の無効化はサポートされていません。ノード上で SELinux が無効になったら、再プロビジョニングしてから実稼働クラスターに再び追加する必要があります。

カーネル引数の一覧と説明は、Kernel.org カーネルパラメーター を参照してください。

次の手順では、以下を特定する MachineConfig オブジェクトを作成します。

  • カーネル引数を追加する一連のマシン。この場合、ワーカーロールを持つマシン。
  • 既存のカーネル引数の最後に追加されるカーネル引数。
  • マシン設定のリストで変更が適用される場所を示すラベル。

前提条件

  • 作業用の OpenShift Container Platform クラスターに対する管理者権限が必要です。

手順

  1. OpenShift Container Platform クラスターの既存の MachineConfig をリスト表示し、マシン設定にラベルを付ける方法を判別します。

    $ oc get MachineConfig

    出力例

    NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
    00-master                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    00-worker                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-ssh                                                                                 3.2.0             40m
    99-worker-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-worker-ssh                                                                                 3.2.0             40m
    rendered-master-23e785de7587df95a4b517e0647e5ab7   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    rendered-worker-5d596d9293ca3ea80c896a1191735bb1   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m

  2. カーネル引数を識別する MachineConfig オブジェクトファイルを作成します (例: 05-worker-kernelarg-selinuxpermissive.yaml)。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker1
      name: 05-worker-kernelarg-selinuxpermissive2
    spec:
      kernelArguments:
        - enforcing=03
    1
    新しいカーネル引数をワーカーノードのみに適用します。
    2
    マシン設定 (05) 内の適切な場所を特定するための名前が指定されます (SELinux permissive モードを設定するためにカーネル引数を追加します)。
    3
    正確なカーネル引数を enforcing=0 として特定します。
  3. 新規のマシン設定を作成します。

    $ oc create -f 05-worker-kernelarg-selinuxpermissive.yaml
  4. マシン設定で新規の追加内容を確認します。

    $ oc get MachineConfig

    出力例

    NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
    00-master                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    00-worker                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    05-worker-kernelarg-selinuxpermissive                                                         3.2.0             105s
    99-master-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-ssh                                                                                 3.2.0             40m
    99-worker-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-worker-ssh                                                                                 3.2.0             40m
    rendered-master-23e785de7587df95a4b517e0647e5ab7   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    rendered-worker-5d596d9293ca3ea80c896a1191735bb1   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m

  5. ノードを確認します。

    $ oc get nodes

    出力例

    NAME                           STATUS                     ROLES    AGE   VERSION
    ip-10-0-136-161.ec2.internal   Ready                      worker   28m   v1.27.3
    ip-10-0-136-243.ec2.internal   Ready                      master   34m   v1.27.3
    ip-10-0-141-105.ec2.internal   Ready,SchedulingDisabled   worker   28m   v1.27.3
    ip-10-0-142-249.ec2.internal   Ready                      master   34m   v1.27.3
    ip-10-0-153-11.ec2.internal    Ready                      worker   28m   v1.27.3
    ip-10-0-153-150.ec2.internal   Ready                      master   34m   v1.27.3

    変更が適用されているため、各ワーカーノードのスケジューリングが無効にされていることを確認できます。

  6. ワーカーノードのいずれかに移動し、カーネルコマンドライン引数 (ホストの /proc/cmdline 内) をリスト表示して、カーネル引数が機能することを確認します。

    $ oc debug node/ip-10-0-141-105.ec2.internal

    出力例

    Starting pod/ip-10-0-141-105ec2internal-debug ...
    To use host binaries, run `chroot /host`
    
    sh-4.2# cat /host/proc/cmdline
    BOOT_IMAGE=/ostree/rhcos-... console=tty0 console=ttyS0,115200n8
    rootflags=defaults,prjquota rw root=UUID=fd0... ostree=/ostree/boot.0/rhcos/16...
    coreos.oem.id=qemu coreos.oem.id=ec2 ignition.platform.id=ec2 enforcing=0
    
    sh-4.2# exit

    enforcing=0 引数が他のカーネル引数に追加されていることを確認できるはずです。

6.3.5. ノードでのスワップメモリー使用の有効化

重要

ノードでスワップメモリーの使用を有効にできるのは、テクノロジープレビュー機能のみです。テクノロジープレビュー機能は、Red Hat 製品のサービスレベルアグリーメント (SLA) の対象外であり、機能的に完全ではないことがあります。Red Hat は、実稼働環境でこれらを使用することを推奨していません。テクノロジープレビューの機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。

Red Hat のテクノロジープレビュー機能のサポート範囲に関する詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。

ノードごとに OpenShift Container Platform ワークロードの swap メモリー使用量を有効にすることができます。

警告

スワップメモリーを有効にすると、ワークロードのパフォーマンスとリソース不足の処理に悪影響を与える可能性があります。コントロールプレーンノードでスワップメモリーを有効化しないでください。

スワップメモリーを有効にするには、kubeletconfig カスタムリソース (CR) を作成して、swapbehavior パラメーターを設定します。制限付きまたは無制限のスワップメモリーを設定できます。

  • 制限付き: LimitedSwap 値を使用して、使用できるスワップメモリーワークロード量を制限します。OpenShift Container Platform によって管理されていないノード上のワークロードは、引き続きスワップメモリーを使用できます。LimitedSwap の動作は、ノードが Linux コントロールグループ バージョン 1(cgroups v1 ) またはバージョン 2(cgroup v 2 )で実行されているかどうかによって異なります。

    • cgroup v1: OpenShift Container Platform ワークロードは、設定されている場合、Pod のメモリー制限まで、メモリーとスワップの任意の組み合わせを使用できます。
    • cgroup v2: OpenShift Container Platform ワークロードはスワップメモリーを使用できません。
  • Unlimited: UnlimitedSwap値を使用して、ワークロードがシステム制限まで、要求したスワップメモリーを使用できるようにします。

この設定がないと、スワップメモリーが存在する場合は kubelet が開始されないため、ノードでスワップメモリーを有効にする前に、OpenShift Container Platform でスワップメモリーを有効にする必要があります。ノードにスワップメモリーが存在しない場合、OpenShift Container Platform でスワップメモリーを有効にしても効果はありません。

前提条件

  • バージョン 4.10 以降を使用する OpenShift Container Platform クラスターが実行中である。
  • 管理者権限を持つユーザーとしてクラスターにログインしている。
  • クラスターで TechPreviewNoUpgrade 機能セットを有効にしている (ノード → クラスターの操作 → フィーチャーゲートを使用した機能の有効化 を参照)。

    注記

    TechPreviewNoUpgrade 機能セットを有効にすると元に戻すことができなくなり、マイナーバージョンの更新ができなくなります。これらの機能セットは、実稼働クラスターでは推奨されません。

  • ノードで cgroup v2 が有効になっている場合は、swapaccount = 1 カーネル引数を設定して、ノードでスワップアカウンティングを有効にする必要があります。

手順

  1. スワップメモリーを許可するマシン設定プールにカスタムラベルを適用します。

    $ oc label machineconfigpool worker kubelet-swap=enabled
  2. カスタムリソース (CR) を作成し、スワップ設定を有効にして設定します。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: swap-config
    spec:
      machineConfigPoolSelector:
        matchLabels:
          kubelet-swap: enabled
      kubeletConfig:
        failSwapOn: false 1
        memorySwap:
          swapBehavior: LimitedSwap 2
    #...
    1
    false に設定すると、関連付けられたノードでスワップメモリーを使用できるようになります。スワップメモリーの使用を無効にするには、true に設定します。
    2
    スワップメモリーの動作を指定します。指定しない場合、デフォルトは LimitedSwap です。
  3. マシンでスワップメモリーを有効にします。

6.3.6. RHOSP ホストから別の RHOSP ホストへのコントロールプレーンノードの手動移行

クラスターでコントロールプレーンマシンセットが有効になっていない場合は、コントロールプレーンノードをある Red Hat OpenStack Platform (RHOSP) ノードから別のノードに移動するスクリプトを実行できます。

注記

コントロールプレーンマシンセットは、ユーザーがプロビジョニングしたインフラストラクチャー上で実行するクラスターでは有効になりません。

コントロールプレーンマシンセットの詳細は、「コントロールプレーンマシンセットを使用したコントロールプレーンマシンの管理」を参照してください。

前提条件

  • 環境変数 OS_CLOUD は、clouds.yaml ファイルの管理者の認証情報を持つ クラウド エントリーを参照します。
  • 環境変数 KUBECONFIG は、管理用 OpenShift Container Platform 認証情報を含む設定を参照します。

手順

  • コマンドラインから、次のスクリプトを実行します。
#!/usr/bin/env bash

set -Eeuo pipefail

if [ $# -lt 1 ]; then
	echo "Usage: '$0 node_name'"
	exit 64
fi

# Check for admin OpenStack credentials
openstack server list --all-projects >/dev/null || { >&2 echo "The script needs OpenStack admin credentials. Exiting"; exit 77; }

# Check for admin OpenShift credentials
oc adm top node >/dev/null || { >&2 echo "The script needs OpenShift admin credentials. Exiting"; exit 77; }

set -x

declare -r node_name="$1"
declare server_id
server_id="$(openstack server list --all-projects -f value -c ID -c Name | grep "$node_name" | cut -d' ' -f1)"
readonly server_id

# Drain the node
oc adm cordon "$node_name"
oc adm drain "$node_name" --delete-emptydir-data --ignore-daemonsets --force

# Power off the server
oc debug "node/${node_name}" -- chroot /host shutdown -h 1

# Verify the server is shut off
until openstack server show "$server_id" -f value -c status | grep -q 'SHUTOFF'; do sleep 5; done

# Migrate the node
openstack server migrate --wait "$server_id"

# Resize the VM
openstack server resize confirm "$server_id"

# Wait for the resize confirm to finish
until openstack server show "$server_id" -f value -c status | grep -q 'SHUTOFF'; do sleep 5; done

# Restart the VM
openstack server start "$server_id"

# Wait for the node to show up as Ready:
until oc get node "$node_name" | grep -q "^${node_name}[[:space:]]\+Ready"; do sleep 5; done

# Uncordon the node
oc adm uncordon "$node_name"

# Wait for cluster operators to stabilize
until oc get co -o go-template='statuses: {{ range .items }}{{ range .status.conditions }}{{ if eq .type "Degraded" }}{{ if ne .status "False" }}DEGRADED{{ end }}{{ else if eq .type "Progressing"}}{{ if ne .status "False" }}PROGRESSING{{ end }}{{ else if eq .type "Available"}}{{ if ne .status "True" }}NOTAVAILABLE{{ end }}{{ end }}{{ end }}{{ end }}' | grep -qv '\(DEGRADED\|PROGRESSING\|NOTAVAILABLE\)'; do sleep 5; done

スクリプトが完了すると、コントロールプレーンマシンは新しい RHOSP ノードに移行されます。

関連情報

6.4. ノードあたりの Pod の最大数の管理

OpenShift Container Platform では、ノードのプロセッサーコアの数に基づいて、ノードで実行可能な Pod の数、ハード制限、またはその両方を設定できます。両方のオプションを使用した場合、より低い値の方がノード上の Pod の数を制限します。

両方のオプションが使用されている場合、2 つの値の低い方の値により、ノード上の Pod 数が制限されます。これらの値を超えると、以下の状態が生じる可能性があります。

  • CPU 使用率の増大。
  • Pod のスケジューリングの速度が遅くなる。
  • (ノードのメモリー量によって) メモリー不足のシナリオが生じる可能性。
  • IP アドレスのプールを消費する。
  • リソースのオーバーコミット、およびこれによるアプリケーションのパフォーマンスの低下。
重要

Kubernetes では、単一コンテナーを保持する Pod は実際には 2 つのコンテナーを使用します。2 つ目のコンテナーは実際のコンテナーの起動前にネットワークを設定するために使用されます。そのため、10 の Pod を使用するシステムでは、実際には 20 のコンテナーが実行されていることになります。

注記

クラウドプロバイダーからのディスク IOPS スロットリングは CRI-O および kubelet に影響を与える可能性があります。ノード上に多数の I/O 集約型 Pod が実行されている場合、それらはオーバーロードする可能性があります。ノード上のディスク I/O を監視し、ワークロード用に十分なスループットを持つボリュームを使用することが推奨されます。

podsPerCore パラメーターは、ノードのプロセッサーコアの数に基づいて、ノードが実行できる Pod の数を設定します。たとえば、4 プロセッサーコアを搭載したノードで podsPerCore10 に設定される場合、このノードで許可される Pod の最大数は 40 になります。

kubeletConfig:
  podsPerCore: 10

podsPerCore0 に設定すると、この制限が無効になります。デフォルトは 0 です。podsPerCore パラメーターの値は、maxPods パラメーターの値を超えることはできません。

maxPods パラメーターは、ノードのプロパティーに関係なく、ノードが実行できる Pod の数を固定値に設定します。

 kubeletConfig:
    maxPods: 250

6.4.1. ノードあたりの Pod の最大数の設定

podsPerCore および maxPods の 2 つのパラメーターはノードに対してスケジュールできる Pod の最大数を制御します。両方のオプションを使用した場合、より低い値の方がノード上の Pod の数を制限します。

たとえば、podsPerCore が 4 つのプロセッサーコアを持つノード上で、10 に設定されていると、ノード上で許容される Pod の最大数は 40 になります。

前提条件

  1. 次のコマンドを入力して、設定するノードタイプの静的な MachineConfigPool CRD に関連付けられたラベルを取得します。

    $ oc edit machineconfigpool <name>

    以下に例を示します。

    $ oc edit machineconfigpool worker

    出力例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      creationTimestamp: "2022-11-16T15:34:25Z"
      generation: 4
      labels:
        pools.operator.machineconfiguration.openshift.io/worker: "" 1
      name: worker
    #...

    1
    Labels の下にラベルが表示されます。
    ヒント

    ラベルが存在しない場合は、次のようなキー/値のペアを追加します。

    $ oc label machineconfigpool worker custom-kubelet=small-pods

手順

  1. 設定変更のためのカスタムリソース (CR) を作成します。

    max-pods CR の設定例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: set-max-pods 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 2
      kubeletConfig:
        podsPerCore: 10 3
        maxPods: 250 4
    #...

    1
    CR に名前を割り当てます。
    2
    マシン設定プールからラベルを指定します。
    3
    ノードがプロセッサーコアの数に基づいて実行できる Pod の数を指定します。
    4
    ノードのプロパティーにかかわらず、ノードが実行できる Pod 数を固定値に指定します。
    注記

    podsPerCore0 に設定すると、この制限が無効になります。

    上記の例では、podsPerCore のデフォルト値は 10 であり、maxPods のデフォルト値は 250 です。つまり、ノードのコア数が 25 以上でない限り、デフォルトにより podsPerCore が制限要素になります。

  2. 以下のコマンドを実行して CR を作成します。

    $ oc create -f <file_name>.yaml

検証

  1. 変更が適用されるかどうかを確認するために、MachineConfigPool CRD を一覧表示します。変更が Machine Config Controller によって取得されると、UPDATING 列で True と報告されます。

    $ oc get machineconfigpools

    出力例

    NAME     CONFIG                        UPDATED   UPDATING   DEGRADED
    master   master-9cc2c72f205e103bb534   False     False      False
    worker   worker-8cecd1236b33ee3f8a5e   False     True       False

    変更が完了すると、UPDATED 列で True と報告されます。

    $ oc get machineconfigpools

    出力例

    NAME     CONFIG                        UPDATED   UPDATING   DEGRADED
    master   master-9cc2c72f205e103bb534   False     True       False
    worker   worker-8cecd1236b33ee3f8a5e   True      False      False

6.5. Node Tuning Operator の使用

Node Tuning Operator を説明し、この Operator を使用し、Tuned デーモンのオーケストレーションを実行してノードレベルのチューニングを管理する方法を説明します。

目的

Node Tuning Operator は、TuneD デーモンを調整することでノードレベルのチューニングを管理し、パフォーマンスプロファイルコントローラーを使用して低レイテンシーのパフォーマンスを実現するのに役立ちます。ほとんどの高パフォーマンスアプリケーションでは、一定レベルのカーネルのチューニングが必要です。Node Tuning Operator は、ノードレベルの sysctl の統一された管理インターフェイスをユーザーに提供し、ユーザーが指定するカスタムチューニングを追加できるよう柔軟性を提供します。

Operator は、コンテナー化された OpenShift Container Platform の TuneD デーモンを Kubernetes デーモンセットとして管理します。これにより、カスタムチューニング仕様が、デーモンが認識する形式でクラスターで実行されるすべてのコンテナー化された TuneD デーモンに渡されます。デーモンは、ノードごとに 1 つずつ、クラスターのすべてのノードで実行されます。

コンテナー化された TuneD デーモンによって適用されるノードレベルの設定は、プロファイルの変更をトリガーするイベントで、または終了シグナルの受信および処理によってコンテナー化された TuneD デーモンが正常に終了する際にロールバックされます。

Node Tuning Operator は、パフォーマンスプロファイルコントローラーを使用して自動チューニングを実装し、OpenShift Container Platform アプリケーションの低レイテンシーパフォーマンスを実現します。

クラスター管理者は、以下のようなノードレベルの設定を定義するパフォーマンスプロファイルを設定します。

  • カーネルを kernel-rt に更新します。
  • ハウスキーピング用の CPU を選択します。
  • 実行中のワークロード用の CPU を選択します。
注記

現在、CPU 負荷分散の無効化は cgroup v2 ではサポートされていません。その結果、cgroup v2 が有効になっている場合は、パフォーマンスプロファイルから望ましい動作が得られない可能性があります。パフォーマンスプロファイルを使用している場合は、cgroup v2 を有効にすることは推奨されません。

Node Tuning Operator は、バージョン 4.1 以降における標準的な OpenShift Container Platform インストールの一部となっています。

注記

OpenShift Container Platform の以前のバージョンでは、Performance Addon Operator を使用して自動チューニングを実装し、OpenShift アプリケーションの低レイテンシーパフォーマンスを実現していました。OpenShift Container Platform 4.11 以降では、この機能は Node Tuning Operator の一部です。

6.5.1. Node Tuning Operator 仕様サンプルへのアクセス

このプロセスを使用して Node Tuning Operator 仕様サンプルにアクセスします。

手順

  • 次のコマンドを実行して、Node Tuning Operator 仕様の例にアクセスします。

    oc get tuned.tuned.openshift.io/default -o yaml -n openshift-cluster-node-tuning-operator

デフォルトの CR は、OpenShift Container Platform プラットフォームの標準的なノードレベルのチューニングを提供することを目的としており、Operator 管理の状態を設定するためにのみ変更できます。デフォルト CR へのその他のカスタム変更は、Operator によって上書きされます。カスタムチューニングの場合は、独自のチューニングされた CR を作成します。新規に作成された CR は、ノード/Pod ラベルおよびプロファイルの優先順位に基づいて OpenShift Container Platform ノードに適用されるデフォルトの CR およびカスタムチューニングと組み合わされます。

警告

特定の状況で Pod ラベルのサポートは必要なチューニングを自動的に配信する便利な方法ですが、この方法は推奨されず、とくに大規模なクラスターにおいて注意が必要です。デフォルトの調整された CR は Pod ラベル一致のない状態で提供されます。カスタムプロファイルが Pod ラベル一致のある状態で作成される場合、この機能はその時点で有効になります。Pod ラベル機能は、Node Tuning Operator の将来のバージョンで非推奨になる予定です。

6.5.2. カスタムチューニング仕様

Operator のカスタムリソース (CR) には 2 つの重要なセクションがあります。1 つ目のセクションの profile: は TuneD プロファイルおよびそれらの名前のリストです。2 つ目の recommend: は、プロファイル選択ロジックを定義します。

複数のカスタムチューニング仕様は、Operator の namespace に複数の CR として共存できます。新規 CR の存在または古い CR の削除は Operator によって検出されます。既存のカスタムチューニング仕様はすべてマージされ、コンテナー化された TuneD デーモンの適切なオブジェクトは更新されます。

管理状態

Operator 管理の状態は、デフォルトの Tuned CR を調整して設定されます。デフォルトで、Operator は Managed 状態であり、spec.managementState フィールドはデフォルトの Tuned CR に表示されません。Operator Management 状態の有効な値は以下のとおりです。

  • Managed: Operator は設定リソースが更新されるとそのオペランドを更新します。
  • Unmanaged: Operator は設定リソースへの変更を無視します。
  • Removed: Operator は Operator がプロビジョニングしたオペランドおよびリソースを削除します。

プロファイルデータ

profile: セクションは、TuneD プロファイルおよびそれらの名前をリスト表示します。

profile:
- name: tuned_profile_1
  data: |
    # TuneD profile specification
    [main]
    summary=Description of tuned_profile_1 profile

    [sysctl]
    net.ipv4.ip_forward=1
    # ... other sysctl's or other TuneD daemon plugins supported by the containerized TuneD

# ...

- name: tuned_profile_n
  data: |
    # TuneD profile specification
    [main]
    summary=Description of tuned_profile_n profile

    # tuned_profile_n profile settings

推奨プロファイル

profile: 選択ロジックは、CR の recommend: セクションによって定義されます。recommend: セクションは、選択基準に基づくプロファイルの推奨項目のリストです。

recommend:
<recommend-item-1>
# ...
<recommend-item-n>

リストの個別項目:

- machineConfigLabels: 1
    <mcLabels> 2
  match: 3
    <match> 4
  priority: <priority> 5
  profile: <tuned_profile_name> 6
  operand: 7
    debug: <bool> 8
    tunedConfig:
      reapply_sysctl: <bool> 9
1
オプション:
2
キー/値の MachineConfig ラベルのディクショナリー。キーは一意である必要があります。
3
省略する場合は、優先度の高いプロファイルが最初に一致するか、machineConfigLabels が設定されていない限り、プロファイルの一致が想定されます。
4
オプションのリスト。
5
プロファイルの順序付けの優先度。数値が小さいほど優先度が高くなります (0 が最も高い優先度になります)。
6
一致に適用する TuneD プロファイル。例: tuned_profile_1
7
オプションのオペランド設定。
8
TuneD デーモンのデバッグオンまたはオフを有効にします。オプションは、オンの場合は true、オフの場合は false です。デフォルトは false です。
9
TuneD デーモンの reapply_sysctl 機能をオンまたはオフにします。オプションは on で true、オフの場合は false です。

<match> は、以下のように再帰的に定義されるオプションの一覧です。

- label: <label_name> 1
  value: <label_value> 2
  type: <label_type> 3
    <match> 4
1
ノードまたは Pod のラベル名。
2
オプションのノードまたは Pod のラベルの値。省略されている場合も、<label_name> があるだけで一致条件を満たします。
3
オプションのオブジェクトタイプ (node または pod)。省略されている場合は、node が想定されます。
4
オプションの <match> リスト。

<match> が省略されない場合、ネストされたすべての <match> セクションが true に評価される必要もあります。そうでない場合には false が想定され、それぞれの <match> セクションのあるプロファイルは適用されず、推奨されません。そのため、ネスト化 (子の <match> セクション) は論理 AND 演算子として機能します。これとは逆に、<match> 一覧のいずれかの項目が一致する場合は、<match> の一覧全体が true に評価されます。そのため、リストは論理 OR 演算子として機能します。

machineConfigLabels が定義されている場合は、マシン設定プールベースのマッチングが指定の recommend: 一覧の項目に対してオンになります。<mcLabels> はマシン設定のラベルを指定します。マシン設定は、プロファイル <tuned_profile_name> についてカーネル起動パラメーターなどのホスト設定を適用するために自動的に作成されます。この場合は、マシン設定セレクターが <mcLabels> に一致するすべてのマシン設定プールを検索し、プロファイル <tuned_profile_name> を確認されるマシン設定プールが割り当てられるすべてのノードに設定する必要があります。マスターロールとワーカーのロールの両方を持つノードをターゲットにするには、マスターロールを使用する必要があります。

リスト項目の match および machineConfigLabels は論理 OR 演算子によって接続されます。match 項目は、最初にショートサーキット方式で評価されます。そのため、true と評価される場合、machineConfigLabels 項目は考慮されません。

重要

マシン設定プールベースのマッチングを使用する場合は、同じハードウェア設定を持つノードを同じマシン設定プールにグループ化することが推奨されます。この方法に従わない場合は、TuneD オペランドが同じマシン設定プールを共有する 2 つ以上のノードの競合するカーネルパラメーターを計算する可能性があります。

例: ノードまたは Pod のラベルベースのマッチング

- match:
  - label: tuned.openshift.io/elasticsearch
    match:
    - label: node-role.kubernetes.io/master
    - label: node-role.kubernetes.io/infra
    type: pod
  priority: 10
  profile: openshift-control-plane-es
- match:
  - label: node-role.kubernetes.io/master
  - label: node-role.kubernetes.io/infra
  priority: 20
  profile: openshift-control-plane
- priority: 30
  profile: openshift-node

上記のコンテナー化された TuneD デーモンの CR は、プロファイルの優先順位に基づいてその recommend.conf ファイルに変換されます。最も高い優先順位 (10) を持つプロファイルは openshift-control-plane-es であるため、これが最初に考慮されます。指定されたノードで実行されるコンテナー化された TuneD デーモンは、同じノードに tuned.openshift.io/elasticsearch ラベルが設定された Pod が実行されているかどうかを確認します。これがない場合は、<match> セクション全体が false として評価されます。このラベルを持つこのような Pod がある場合に、<match> セクションが true に評価されるようにするには、ノードラベルを node-role.kubernetes.io/master または node-role.kubernetes.io/infra にする必要もあります。

優先順位が 10 のプロファイルのラベルが一致した場合は、openshift-control-plane-es プロファイルが適用され、その他のプロファイルは考慮されません。ノード/Pod ラベルの組み合わせが一致しない場合は、2 番目に高い優先順位プロファイル (openshift-control-plane) が考慮されます。このプロファイルは、コンテナー化された TuneD Pod が node-role.kubernetes.io/master または node-role.kubernetes.io/infra ラベルを持つノードで実行される場合に適用されます。

最後に、プロファイル openshift-node には最低の優先順位である 30 が設定されます。これには <match> セクションがないため、常に一致します。これは、より高い優先順位の他のプロファイルが指定されたノードで一致しない場合に openshift-node プロファイルを設定するために、最低の優先順位のノードが適用される汎用的な (catch-all) プロファイルとして機能します。

意志決定ワークフロー

例: マシン設定プールベースのマッチング

apiVersion: tuned.openshift.io/v1
kind: Tuned
metadata:
  name: openshift-node-custom
  namespace: openshift-cluster-node-tuning-operator
spec:
  profile:
  - data: |
      [main]
      summary=Custom OpenShift node profile with an additional kernel parameter
      include=openshift-node
      [bootloader]
      cmdline_openshift_node_custom=+skew_tick=1
    name: openshift-node-custom

  recommend:
  - machineConfigLabels:
      machineconfiguration.openshift.io/role: "worker-custom"
    priority: 20
    profile: openshift-node-custom

ノードの再起動を最小限にするには、ターゲットノードにマシン設定プールのノードセレクターが一致するラベルを使用してラベルを付け、上記の Tuned CR を作成してから、最後にカスタムのマシン設定プール自体を作成します。

クラウドプロバイダー固有の TuneD プロファイル

この機能により、すべてのクラウドプロバイダー固有のノードに、OpenShift Container Platform クラスター上の特定のクラウドプロバイダーに合わせて特別に調整された TuneD プロファイルを簡単に割り当てることができます。これは、追加のノードラベルを追加したり、ノードをマシン設定プールにグループ化したりせずに実行できます。

この機能は、<cloud-provider>://<cloud-provider-specific-id> の形式で spec.providerID ノードオブジェクト値を利用して、NTO オペランドコンテナーの <cloud-provider> の値で /var/lib/tuned/provider ファイルを書き込みます。その後、このファイルのコンテンツは TuneD により、プロバイダー provider-<cloud-provider> プロファイル (存在する場合) を読み込むために使用されます。

openshift-control-plane および openshift-node プロファイルの両方の設定を継承する openshift プロファイルは、条件付きプロファイルの読み込みを使用してこの機能を使用するよう更新されるようになりました。現時点で、NTO や TuneD にクラウドプロバイダー固有のプロファイルは含まれていません。ただし、すべてのクラウドプロバイダー固有のクラスターノードに適用されるカスタムプロファイル provider-<cloud-provider> を作成できます。

GCE クラウドプロバイダープロファイルの例

apiVersion: tuned.openshift.io/v1
kind: Tuned
metadata:
  name: provider-gce
  namespace: openshift-cluster-node-tuning-operator
spec:
  profile:
  - data: |
      [main]
      summary=GCE Cloud provider-specific profile
      # Your tuning for GCE Cloud provider goes here.
    name: provider-gce

注記

プロファイルの継承により、provider-<cloud-provider> プロファイルで指定された設定は、openshift プロファイルとその子プロファイルによって上書きされます。

6.5.3. クラスターに設定されるデフォルトのプロファイル

以下は、クラスターに設定されるデフォルトのプロファイルです。

apiVersion: tuned.openshift.io/v1
kind: Tuned
metadata:
  name: default
  namespace: openshift-cluster-node-tuning-operator
spec:
  profile:
  - data: |
      [main]
      summary=Optimize systems running OpenShift (provider specific parent profile)
      include=-provider-${f:exec:cat:/var/lib/tuned/provider},openshift
    name: openshift
  recommend:
  - profile: openshift-control-plane
    priority: 30
    match:
    - label: node-role.kubernetes.io/master
    - label: node-role.kubernetes.io/infra
  - profile: openshift-node
    priority: 40

OpenShift Container Platform 4.9 以降では、すべての OpenShift TuneD プロファイルが TuneD パッケージに含まれています。oc exec コマンドを使用して、これらのプロファイルの内容を表示できます。

$ oc exec $tuned_pod -n openshift-cluster-node-tuning-operator -- find /usr/lib/tuned/openshift{,-control-plane,-node} -name tuned.conf -exec grep -H ^ {} \;

6.5.4. サポートされている TuneD デーモンプラグイン

[main] セクションを除き、以下の TuneD プラグインは、Tuned CR の profile: セクションで定義されたカスタムプロファイルを使用する場合にサポートされます。

  • audio
  • cpu
  • disk
  • eeepc_she
  • modules
  • mounts
  • net
  • scheduler
  • scsi_host
  • selinux
  • sysctl
  • sysfs
  • usb
  • video
  • vm
  • bootloader

これらのプラグインの一部によって提供される動的チューニング機能の中に、サポートされていない機能があります。以下の TuneD プラグインは現時点でサポートされていません。

  • script
  • systemd
注記

TuneD ブートローダープラグインは、Red Hat Enterprise Linux CoreOS (RHCOS) ワーカーノードのみサポートします。

6.6. ノードの修復、フェンシング、メンテナンス

カーネルのハングやネットワークインターフェイスコントローラー (NIC) の障害などをはじめとするノードレベルの障害が発生した場合、クラスターに必要な作業は減少せず、影響を受けたノードからのワークロードをどこかで再起動する必要があります。これらのワークロードに影響を与える障害は、データの損失、破損、またはその両方のリスクを伴います。ワークロードの復元 (remediation) とノードの復元を開始する前にノードを分離 (fencing) することが重要です。

ノードの修復、フェンシング、メンテナンスの詳細は、Red Hat OpenShift のワークロードの可用性 を参照してください。

6.7. ノードの再起動について

プラットフォームで実行されているアプリケーションを停止せずにノードを再起動するには、まず Pod の退避を実行することが重要です。ルーティング階層によって可用性が高くなっている Pod には、何も実行する必要はありません。ストレージ (通常はデータベース) を必要とするその他の Pod には、1 つの Pod が一時的にオフラインになってもそれらの Pod が作動状態を維持できることを確認する必要があります。ステートフルな Pod の回復性はアプリケーションごとに異なりますが、いずれの場合でも、ノードの非アフィニティー (node anti-affinity) を使用して Pod が使用可能なノードにわたって適切に分散するようにスケジューラーを設定することが重要になります。

別の課題として、ルーターやレジストリーのような重要なインフラストラクチャーを実行しているノードを処理する方法を検討する必要があります。同じノードの退避プロセスが適用されますが、一部のエッジケースについて理解しておくことが重要です。

6.7.1. 重要なインフラストラクチャーを実行するノードの再起動について

ルーター Pod、レジストリー Pod、モニタリング Pod などの重要な OpenShift Container Platform インフラストラクチャーコンポーネントをホストするノードを再起動する場合、これらのコンポーネントを実行するために少なくとも 3 つのノードが利用可能であることを確認します。

以下のシナリオは、2 つのノードのみが利用可能な場合に、どのように OpenShift Container Platform で実行されているアプリケーションでサービスの中断が生じ得るかを示しています。

  • ノード A がスケジュール対象外としてマークされており、すべての Pod の退避が行われている。
  • このノードで実行されているレジストリー Pod がノード B に再デプロイされる。 ノード B が両方のレジストリー Pod を実行しています。
  • ノード B はスケジュール対象外としてマークされ、退避が行われる。
  • ノード B の 2 つの Pod エンドポイントを公開するサービスは、それらがノード A に再デプロイされるまでの短い期間にすべてのエンドポイントを失う。

インフラストラクチャーコンポーネントの 3 つのノードを使用する場合、このプロセスではサービスの中断が生じません。しかし、Pod のスケジューリングにより、退避してローテーションに戻される最後のノードにはレジストリー Pod がありません。他のノードのいずれかには 2 つのレジストリー Pod があります。3 番目のレジストリー Pod を最後のノードでスケジュールするには、Pod の非アフィニティーを使用してスケジューラーが同じノード上で 2 つのレジストリー Pod を見つけるのを防ぎます。

6.7.2. Pod の非アフィニティーを使用するノードの再起動

Pod の非アフィニティーは、ノードの非アフィニティーとは若干異なります。ノードの非アフィニティーの場合、Pod のデプロイ先となる適切な場所が他にない場合には違反が生じる可能性があります。Pod の非アフィニティーの場合は required (必須) または preferred (優先) のいずれかに設定できます。

これが有効になっていると、2 つのインフラストラクチャーノードのみが利用可能で、1 つのノードが再起動される場合に、コンテナーイメージレジストリー Pod は他のノードで実行できなくなります。oc get pods は、適切なノードが利用可能になるまで Pod を Unready (準備が未完了) として報告します。ノードが利用可能になり、すべての Pod が Ready (準備ができている) 状態に戻ると、次のノードを再起動することができます。

手順

Pod の非アフィニティーを使用してノードを再起動するには、以下の手順を実行します。

  1. ノードの仕様を編集して Pod の非アフィニティーを設定します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: with-pod-antiaffinity
    spec:
      affinity:
        podAntiAffinity: 1
          preferredDuringSchedulingIgnoredDuringExecution: 2
          - weight: 100 3
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: registry 4
                  operator: In 5
                  values:
                  - default
              topologyKey: kubernetes.io/hostname
    #...
    1
    Pod の非アフィニティーを設定するためのスタンザです。
    2
    preferred (優先) ルールを定義します。
    3
    preferred (優先) ルールの重みを指定します。最も高い重みを持つノードが優先されます。
    4
    非アフィニティールールが適用される時を決定する Pod ラベルの説明です。ラベルのキーおよび値を指定します。
    5
    演算子は、既存 Pod のラベルと新規 Pod の仕様の matchExpression パラメーターの値のセットの間の関係を表します。これには InNotInExists、または DoesNotExist のいずれかを使用できます。

    この例では、コンテナーイメージレジストリー Pod に registry=default のラベルがあることを想定しています。Pod の非アフィニティーでは任意の Kubernetes の一致式を使用できます。

  2. スケジューリングポリシーファイルで、MatchInterPodAffinity スケジューラー述語を有効にします。
  3. ノードの正常な再起動を実行します。

6.7.3. ルーターを実行しているノードを再起動する方法について

ほとんどの場合、OpenShift Container Platform ルーターを実行している Pod はホストポートを公開します。

PodFitsPorts スケジューラー述語は、同じポートを使用するルーター Pod が同じノード上で実行できないようにし、Pod の非アフィニティーが確保されるようにします。ルーターが高可用性を確保するために IP フェイルオーバーに依存する場合は、他に必要な設定等はありません。

高可用性のための AWS Elastic Load Balancing のような外部サービスに依存するルーター Pod の場合は、ルーターの再起動に対応するサービスが必要になります。

ルーター Pod でホストのポートが設定されていないということも稀にあります。この場合は、インフラストラクチャーノードに関する推奨される再起動プロセスに従う必要があります。

6.7.4. ノードを正常に再起動する

ノードを再起動する前に、ノードでのデータ損失を回避するために、etcd データをバックアップすることを推奨します。

注記

クラスターを管理するために kubeconfig ファイルに証明書を持たせるのではなく、ユーザーが oc login コマンドを実行する必要があるシングルノードの OpenShift クラスターでは、ノードの遮断およびドレイン後に oc adm コマンドが使用できない場合があります。これは、遮断により openshift-oauth-apiserver Pod が実行されないためです。以下の手順で示したように、SSH を使用してノードにアクセスできます。

シングルノードの OpenShift クラスターでは、遮断およびドレイン時に Pod の再スケジューリングはできません。しかし、そうすることで、Pod、特にワークロード Pod が適切に停止し、関連するリソースを解放する時間を得ることができます。

手順

ノードのグレースフル再起動を実行するには、次の手順を実行します。

  1. ノードにスケジュール対象外 (unschedulable) のマークを付けます。

    $ oc adm cordon <node1>
  2. ノードをドレインして、実行中のすべての Pod を削除します。

    $ oc adm drain <node1> --ignore-daemonsets --delete-emptydir-data --force

    カスタムの Pod の Disruption Budget (停止状態の予算、PDB) 関連付けられた Pod を退避できないというエラーが発生することがあります。

    エラーの例

    error when evicting pods/"rails-postgresql-example-1-72v2w" -n "rails" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.

    この場合、drain コマンドを再度実行し、disable-eviction フラグを追加し、PDB チェックを省略します。

    $ oc adm drain <node1> --ignore-daemonsets --delete-emptydir-data --force --disable-eviction
  3. デバッグモードでノードにアクセスします。

    $ oc debug node/<node1>
  4. ルートディレクトリーを /host に変更します。

    $ chroot /host
  5. ノードを再起動します。

    $ systemctl reboot

    すぐに、ノードは NotReady 状態になります。

    注記

    一部のシングルノード OpenShift クラスターでは、openshift-oauth-apiserver Pod が実行されていないため、ノードの遮断およびドレイン後に oc コマンドが使用できない場合があります。SSH でノードに接続し、リブートを実行することができます。

    $ ssh core@<master-node>.<cluster_name>.<base_domain>
    $ sudo systemctl reboot
  6. 再起動が完了したら、以下のコマンドを実行して、ノードをスケジューリング可能な状態にします。

    $ oc adm uncordon <node1>
    注記

    一部のシングルノード OpenShift クラスターでは、openshift-oauth-apiserver Pod が実行されていないため、ノードの遮断およびドレイン後に oc コマンドが使用できない場合があります。SSH を使用してノードに接続し、ノードの遮断を解除します。

    $ ssh core@<target_node>
    $ sudo oc adm uncordon <node> --kubeconfig /etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/localhost.kubeconfig
  7. ノードの準備ができていることを確認します。

    $ oc get node <node1>

    出力例

    NAME    STATUS  ROLES    AGE     VERSION
    <node1> Ready   worker   6d22h   v1.18.3+b0068a8

関連情報

etcd データのバックアップについては、etcd データのバックアップ を参照してください。

6.8. ガベージコレクションを使用しているノードリソースの解放

管理者は、OpenShift Container Platform を使用し、ガベージコレクションによってリソースを解放することにより、ノードを効率的に実行することができます。

OpenShift Container Platform ノードは、2 種類のガベージコレクションを実行します。

  • コンテナーのガベージコレクション: 終了したコンテナーを削除します。
  • イメージのガベージコレクション: 実行中のどの Pod からも参照されていないイメージを削除します。

6.8.1. 終了したコンテナーがガベージコレクションによって削除される仕組みについて

コンテナーのガベージコレクションは、エビクションしきい値を使用して、終了したコンテナーを削除します。

エビクションしきい値がガーベージコレクションに設定されていると、ノードは Pod のコンテナーが API から常にアクセス可能な状態になるよう試みます。Pod が削除された場合、コンテナーも削除されます。コンテナーは Pod が削除されず、エビクションしきい値に達していない限り保持されます。ノードがディスク不足 (disk pressure) の状態になっていると、コンテナーが削除され、それらのログは oc logs を使用してアクセスできなくなります。

  • eviction-soft - ソフトエビクションのしきい値は、エビクションしきい値と要求される管理者指定の猶予期間を組み合わせます。
  • eviction-hard - ハードエビクションのしきい値には猶予期間がなく、検知されると、OpenShift Container Platform はすぐにアクションを実行します。

以下の表は、エビクションしきい値のリストです。

表6.2 コンテナーのガベージコレクションを設定するための変数
ノードの状態エビクションシグナル説明

MemoryPressure

memory.available

ノードで利用可能なメモリー。

DiskPressure

  • nodefs.available
  • nodefs.inodesFree
  • imagefs.available
  • imagefs.inodesFree

ノードのルートファイルシステム (nodefs) またはイメージファイルシステム (imagefs) で利用可能なディスク領域または i ノード。

注記

evictionHard の場合、これらのパラメーターをすべて指定する必要があります。すべてのパラメーターを指定しないと、指定したパラメーターのみが適用され、ガベージコレクションが正しく機能しません。

ノードがソフトエビクションしきい値の上限と下限の間で変動し、その関連する猶予期間を超えていない場合、対応するノードは、truefalse の間で常に変動します。したがって、スケジューラーは適切なスケジュールを決定できない可能性があります。

この変動から保護するには、eviction-pressure-transition-period フラグを使用して、OpenShift Container Platform が不足状態から移行するまでにかかる時間を制御します。OpenShift Container Platform は、false 状態に切り替わる前の指定された期間に、エビクションしきい値を指定された不足状態に一致するように設定しません。

6.8.2. イメージがガベージコレクションによって削除される仕組みについて

イメージガベージコレクションは、実行中の Pod によって参照されていないイメージを削除します。

OpenShift Container Platform は、cAdvisor によって報告されたディスク使用量に基づいて、ノードから削除するイメージを決定します。

イメージのガベージコレクションのポリシーは、以下の 2 つの条件に基づいています。

  • イメージのガべージコレクションをトリガーするディスク使用量のパーセント (整数で表される) です。デフォルトは 85 です。
  • イメージのガべージコレクションが解放しようとするディスク使用量のパーセント (整数で表される) です。デフォルトは 80 です。

イメージのガベージコレクションのために、カスタムリソースを使用して、次の変数のいずれかを変更することができます。

表6.3 イメージのガベージコレクションを設定するための変数
設定説明

imageMinimumGCAge

ガベージコレクションによって削除されるまでの未使用のイメージの有効期間。デフォルトは、2m です。

imageGCHighThresholdPercent

イメージのガべージコレクションをトリガーするディスク使用量のパーセント (整数で表される) です。デフォルトは 85 です。

imageGCLowThresholdPercent

イメージのガべージコレクションが解放しようとするディスク使用量のパーセント (整数で表される) です。デフォルトは 80 です。

以下の 2 つのイメージリストがそれぞれのガベージコレクターの実行で取得されます。

  1. 1 つ以上の Pod で現在実行されているイメージのリスト
  2. ホストで利用可能なイメージのリスト

新規コンテナーの実行時に新規のイメージが表示されます。すべてのイメージにはタイムスタンプのマークが付けられます。イメージが実行中 (上記の最初の一覧) か、新規に検出されている (上記の 2 番目の一覧) 場合、これには現在の時間のマークが付けられます。残りのイメージには以前のタイムスタンプのマークがすでに付けられています。すべてのイメージはタイムスタンプで並び替えられます。

コレクションが開始されると、停止条件を満たすまでイメージが最も古いものから順番に削除されます。

6.8.3. コンテナーおよびイメージのガベージコレクションの設定

管理者は、kubeletConfig オブジェクトを各マシン設定プール用に作成し、OpenShift Container Platform によるガベージコレクションの実行方法を設定できます。

注記

OpenShift Container Platform は、各マシン設定プールの kubeletConfig オブジェクトを 1 つのみサポートします。

次のいずれかの組み合わせを設定できます。

  • コンテナーのソフトエビクション
  • コンテナーのハードエビクション
  • イメージのエビクション

コンテナーのガベージコレクションは終了したコンテナーを削除します。イメージガベージコレクションは、実行中の Pod によって参照されていないイメージを削除します。

前提条件

  1. 次のコマンドを入力して、設定するノードタイプの静的な MachineConfigPool CRD に関連付けられたラベルを取得します。

    $ oc edit machineconfigpool <name>

    以下に例を示します。

    $ oc edit machineconfigpool worker

    出力例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      creationTimestamp: "2022-11-16T15:34:25Z"
      generation: 4
      labels:
        pools.operator.machineconfiguration.openshift.io/worker: "" 1
      name: worker
    #...

    1
    Labels の下にラベルが表示されます。
    ヒント

    ラベルが存在しない場合は、次のようなキー/値のペアを追加します。

    $ oc label machineconfigpool worker custom-kubelet=small-pods

手順

  1. 設定変更のためのカスタムリソース (CR) を作成します。

    重要

    ファイルシステムが 1 つの場合、または /var/lib/kubelet/var/lib/containers/ が同じファイルシステムにある場合、最も大きな値の設定が満たされるとエビクションがトリガーされます。ファイルシステムはエビクションをトリガーします。

    コンテナーのガベージコレクション CR のサンプル設定:

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: worker-kubeconfig 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 2
      kubeletConfig:
        evictionSoft: 3
          memory.available: "500Mi" 4
          nodefs.available: "10%"
          nodefs.inodesFree: "5%"
          imagefs.available: "15%"
          imagefs.inodesFree: "10%"
        evictionSoftGracePeriod:  5
          memory.available: "1m30s"
          nodefs.available: "1m30s"
          nodefs.inodesFree: "1m30s"
          imagefs.available: "1m30s"
          imagefs.inodesFree: "1m30s"
        evictionHard: 6
          memory.available: "200Mi"
          nodefs.available: "5%"
          nodefs.inodesFree: "4%"
          imagefs.available: "10%"
          imagefs.inodesFree: "5%"
        evictionPressureTransitionPeriod: 0s 7
        imageMinimumGCAge: 5m 8
        imageGCHighThresholdPercent: 80 9
        imageGCLowThresholdPercent: 75 10
    #...

    1
    オブジェクトの名前。
    2
    マシン設定プールからラベルを指定します。
    3
    コンテナーのガベージコレクションの場合: エビクションのタイプ: evictionSoft または evictionHard
    4
    コンテナーのガベージコレクションの場合: 特定のエビクショントリガー信号に基づくエビクションしきい値。
    5
    コンテナーのガベージコレクションの場合: ソフトエビクションの猶予期間。このパラメーターは、eviction-hard には適用されません。
    6
    コンテナーのガベージコレクションの場合: 特定のエビクショントリガー信号に基づくエビクションしきい値。evictionHard の場合、これらのパラメーターをすべて指定する必要があります。すべてのパラメーターを指定しないと、指定したパラメーターのみが適用され、ガベージコレクションが正しく機能しません。
    7
    コンテナーのガベージコレクションの場合: エビクションプレッシャー状態から移行するまでの待機時間。
    8
    イメージのガベージコレクションの場合: イメージがガベージコレクションによって削除されるまでの、未使用のイメージの最小保存期間。
    9
    イメージガベージコレクションの場合: イメージガベージコレクションをトリガーするディスク使用率 (整数で表されます)。
    10
    イメージガベージコレクションの場合: イメージガベージコレクションが解放しようとするディスク使用率 (整数で表されます)。
  2. 以下のコマンドを実行して CR を作成します。

    $ oc create -f <file_name>.yaml

    以下に例を示します。

    $ oc create -f gc-container.yaml

    出力例

    kubeletconfig.machineconfiguration.openshift.io/gc-container created

検証

  1. 次のコマンドを入力して、ガベージコレクションがアクティブであることを確認します。カスタムリソースで指定した Machine Config Pool では、変更が完全に実行されるまで UPDATING が 'true` と表示されます。

    $ oc get machineconfigpool

    出力例

    NAME     CONFIG                                   UPDATED   UPDATING
    master   rendered-master-546383f80705bd5aeaba93   True      False
    worker   rendered-worker-b4c51bb33ccaae6fc4a6a5   False     True

6.9. OpenShift Container Platform クラスター内のノードのリソースの割り当て

より信頼性の高いスケジューリングを実現し、ノードにおけるリソースのオーバーコミットを最小限にするために、kubelet および kube-proxy などの基礎となるノードのコンポーネント、および sshd および NetworkManager などの残りのシステムコンポーネントに使用される CPU およびメモリーリソースの一部を予約します。予約するリソースを指定して、スケジューラーに、ノードが Pod で使用できる残りの CPU およびメモリーリソースの詳細を提供します。OpenShift Container Platform がノードに 最適な system-reserved CPU およびメモリーリソースを自動的に決定できるようにする ことも、ノードに 最適なリソースを手動で決定して設定する こともできます。

重要

リソース値を手動で設定するには、kubelet config CR を使用する必要があります。machine config CR は使用できません。

6.9.1. ノードにリソースを割り当てる方法について

OpenShift Container Platform 内のノードコンポーネントの予約された CPU とメモリーリソースは、2 つのノード設定に基づいています。

設定説明

kube-reserved

この設定は OpenShift Container Platform では使用されません。確保する予定の CPU およびメモリーリソースを system-reserved 設定に追加します。

system-reserved

この設定は、CRI-O および Kubelet などのノードコンポーネントおよびシステムコンポーネント用に予約するリソースを特定します。デフォルト設定は、OpenShift Container Platform および Machine Config Operator のバージョンによって異なります。machine-config-operator リポジトリーでデフォルトの systemReserved パラメーターを確認します。

フラグが設定されていない場合、デフォルトが使用されます。いずれのフラグも設定されていない場合、割り当てられるリソースは、割り当て可能なリソースの導入前であるためにノードの容量に設定されます。

注記

reservedSystemCPUs パラメーターを使用して予約される CPU は、kube-reserved または system-reserved を使用した割り当てには使用できません。

6.9.1.1. OpenShift Container Platform による割り当てられたリソースの計算方法

割り当てられたリソースの量は、以下の数式に基づいて計算されます。

[Allocatable] = [Node Capacity] - [system-reserved] - [Hard-Eviction-Thresholds]
注記

Allocatable の値がノードレベルで Pod に対して適用されるために、Hard-Eviction-ThresholdsAllocatable から差し引くと、システムの信頼性が強化されます。

Allocatable が負の値の場合、これは 0 に設定されます。

各ノードは、コンテナーランタイムおよび kubelet によって利用されるシステムリソースを報告します。system-reserved パラメーターの設定を簡素化するには、ノード要約 API を使用してノードに使用するリソースを表示します。ノードの要約は /api/v1/nodes/<node>/proxy/stats/summary で利用できます。

6.9.1.2. ノードによるリソースの制約の適用方法

ノードは、Pod が設定された割り当て可能な値に基づいて消費できるリソースの合計量を制限できます。この機能は、Pod がシステムサービス (コンテナーランタイム、ノードエージェントなど) で必要とされる CPU およびメモリーリソースを使用することを防ぎ、ノードの信頼性を大幅に強化します。ノードの信頼性を強化するために、管理者はリソースの使用に関するターゲットに基づいてリソースを確保する必要があります。

ノードは、quality of service を適用する新規の cgroup 階層を使用してリソースの制約を適用します。すべての Pod は、システムデーモンから切り離された専用の cgroup 階層で起動されます。

管理者は quality of service のある Pod と同様にシステムデーモンを処理する必要があります。システムデーモンは、境界となる制御グループ内でバーストする可能性があり、この動作はクラスターのデプロイメントの一部として管理される必要があります。system-reserved で CPU およびメモリーリソースの量を指定し、システムデーモンの CPU およびメモリーリソースを予約します。

system-reserved 制限を適用すると、重要なシステムサービスが CPU およびメモリーリソースを受信できなることがあります。その結果、重要なシステムサービスは、out-of-memory killer によって終了する可能性があります。そのため、正確な推定値を判別するためにノードの徹底的なプロファイリングを実行した場合や、そのグループのプロセスが out-of-memory killer によって終了する場合に重要なシステムサービスが確実に復元できる場合にのみ system-reserved を適用することが推奨されます。

6.9.1.3. エビクションのしきい値について

ノードがメモリー不足の状態にある場合、ノード全体、およびノードで実行されているすべての Pod に影響が及ぶ可能性があります。たとえば、メモリーの予約量を超える量を使用するシステムデーモンは、メモリー不足のイベントを引き起こす可能性があります。システムのメモリー不足のイベントを防止するか、それが発生する可能性を軽減するために、ノードはリソース不足の処理 (out of resource handling) を行います。

--eviction-hard フラグで一部のメモリーを予約することができます。ノードは、ノードのメモリー可用性が絶対値またはパーセンテージを下回る場合は常に Pod のエビクトを試行します。システムデーモンがノードに存在しない場合、Pod はメモリーの capacity - eviction-hard に制限されます。このため、メモリー不足の状態になる前にエビクションのバッファーとして確保されているリソースは Pod で利用することはできません。

以下の例は、割り当て可能なノードのメモリーに対する影響を示しています。

  • ノード容量: 32Gi
  • --system-reserved is 3Gi
  • --eviction-hard は 100Mi に設定される。

このノードについては、有効なノードの割り当て可能な値は 28.9Gi です。ノードおよびシステムコンポーネントが予約分をすべて使い切る場合、Pod に利用可能なメモリーは 28.9Gi となり、この使用量を超える場合に kubelet は Pod をエビクトします。

トップレベルの cgroup でノードの割り当て可能分 (28.9Gi) を適用する場合、Pod は 28.9Gi を超えることはできません。エビクションは、システムデーモンが 3.1Gi よりも多くのメモリーを消費しない限り実行されません。

上記の例ではシステムデーモンが予約分すべてを使い切らない場合も、ノードのエビクションが開始される前に、Pod では境界となる cgroup からの memcg OOM による強制終了が発生します。この状況で QoS をより効果的に実行するには、ノードですべての Pod のトップレベルの cgroup に対し、ハードエビクションしきい値が Node Allocatable + Eviction Hard Thresholds になるよう適用できます。

システムデーモンがすべての予約分を使い切らない場合で、Pod が 28.9Gi を超えるメモリーを消費する場合、ノードは Pod を常にエビクトします。エビクションが時間内に生じない場合には、Pod が 29Gi のメモリーを消費すると OOM による強制終了が生じます。

6.9.1.4. スケジューラーがリソースの可用性を判別する方法

スケジューラーは、node.Status.Capacity ではなく node.Status.Allocatable の値を使用して、ノードが Pod スケジューリングの候補になるかどうかを判別します。

デフォルトで、ノードはそのマシン容量をクラスターで完全にスケジュール可能であるとして報告します。

6.9.2. ノードのリソースの自動割り当て

OpenShift Container Platform は、特定のマシン設定プールに関連付けられたノードに最適な system-reserved CPU およびメモリーリソースを自動的に判別し、ノードの起動時にそれらの値を使用してノードを更新できます。デフォルトでは、system-reserved CPU は 500m で、system-reserved メモリーは 1Gi です。

ノード上で system-reserved リソースを自動的に判断して割り当てるには、KubeletConfig カスタムリソース (CR) を作成して autoSizingReserved: true パラメーターを設定します。各ノードのスクリプトにより、各ノードにインストールされている CPU およびメモリーの容量に基づいて、予約されたそれぞれのリソースに最適な値が計算されます。増加した容量を考慮に入れたスクリプトでは、予約リソースにもこれに対応する増加を反映させることが必要になります。

最適な system-reserved 設定を自動的に判別することで、クラスターが効率的に実行され、CRI-O や kubelet などのシステムコンポーネントのリソース不足によりノードが失敗することを防ぐことができます。この際、値を手動で計算し、更新する必要はありません。

この機能はデフォルトで無効にされています。

前提条件

  1. 次のコマンドを入力して、設定するノードタイプの静的な MachineConfigPool オブジェクトに関連付けられたラベルを取得します。

    $ oc edit machineconfigpool <name>

    以下に例を示します。

    $ oc edit machineconfigpool worker

    出力例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      creationTimestamp: "2022-11-16T15:34:25Z"
      generation: 4
      labels:
        pools.operator.machineconfiguration.openshift.io/worker: "" 1
      name: worker
    #...

    1
    ラベルが Labels の下に表示されます。
    ヒント

    適切なラベルが存在しない場合は、次のようなキーと値のペアを追加します。

    $ oc label machineconfigpool worker custom-kubelet=small-pods

手順

  1. 設定変更のためのカスタムリソース (CR) を作成します。

    リソース割り当て CR の設定例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: dynamic-node 1
    spec:
      autoSizingReserved: true 2
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 3
    #...

    1
    CR に名前を割り当てます。
    2
    true に設定された autoSizingReserved パラメーターを追加し、OpenShift Container Platform が指定されたラベルに関連付けられたノード上で system-reserved リソースを自動的に判別し、割り当てることができます。それらのノードでの自動割り当てを無効にするには、このパラメーターを false に設定します。
    3
    「前提条件」セクションで設定したマシン設定プールからラベルを指定します。マシン設定プールのラベルは、custom-kubelet: small-pods などの任意のラベルか、デフォルトラベルの pools.operator.machineconfiguration.openshift.io/worker: "" を選択できます。

    上記の例では、すべてのワーカーノードでリソースの自動割り当てを有効にします。OpenShift Container Platform はノードをドレイン (解放) し、kubelet 設定を適用してノードを再起動します。

  2. 次のコマンドを入力して CR を作成します。

    $ oc create -f <file_name>.yaml

検証

  1. 次のコマンドを入力して、設定したノードにログインします。

    $ oc debug node/<node_name>
  2. /host をデバッグシェル内のルートディレクトリーとして設定します。

    # chroot /host
  3. /etc/node-sizing.env ファイルを表示します。

    出力例

    SYSTEM_RESERVED_MEMORY=3Gi
    SYSTEM_RESERVED_CPU=0.08

    kubelet は、/etc/node-sizing.env ファイルの system-reserved 値を使用します。上記の例では、ワーカーノードには 0.08 CPU および 3 Gi のメモリーが割り当てられます。更新が適用されるまでに数分の時間がかかることがあります。

6.9.3. ノードのリソースの手動割り当て

OpenShift Container Platform は、割り当てに使用する CPU およびメモリーリソースタイプをサポートします。ephemeral-resource リソースタイプもサポートされています。cpu タイプの場合、リソース数量をコア単位で指定します (例: 200m0.51)。memory および ephemeral-storage の場合、リソース数量をバイト単位で指定します (例: 200Ki50Mi5Gi)。デフォルトでは、system-reserved CPU は 500m で、system-reserved メモリーは 1Gi です。

管理者は、kubelet config カスタムリソース (CR) を使用して、一連の <resource_type>=<resource_quantity> ペア (例: cpu=200m,memory=512Mi) を設定できます。

重要

リソース値を手動で設定するには、kubelet config CR を使用する必要があります。machine config CR は使用できません。

推奨される system-reserved 値の詳細は、推奨される system-reserved 値 を参照してください。

前提条件

  1. 次のコマンドを入力して、設定するノードタイプの静的な MachineConfigPool CRD に関連付けられたラベルを取得します。

    $ oc edit machineconfigpool <name>

    以下に例を示します。

    $ oc edit machineconfigpool worker

    出力例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      creationTimestamp: "2022-11-16T15:34:25Z"
      generation: 4
      labels:
        pools.operator.machineconfiguration.openshift.io/worker: "" 1
      name: worker
    #...

    1
    Labels の下にラベルが表示されます。
    ヒント

    ラベルが存在しない場合は、次のようなキー/値のペアを追加します。

    $ oc label machineconfigpool worker custom-kubelet=small-pods

手順

  1. 設定変更のためのカスタムリソース (CR) を作成します。

    リソース割り当て CR の設定例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: set-allocatable 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 2
      kubeletConfig:
        systemReserved: 3
          cpu: 1000m
          memory: 1Gi
    #...

    1
    CR に名前を割り当てます。
    2
    マシン設定プールからラベルを指定します。
    3
    ノードコンポーネントおよびシステムコンポーネント用に予約するリソースを指定します。
  2. 以下のコマンドを実行して CR を作成します。

    $ oc create -f <file_name>.yaml

6.10. クラスター内のノードに特定の CPU を割り当てる

static CPU マネージャーポリシー を使用すると、クラスター内の特定のノードで使用するために特定の CPU を予約できます。たとえば、24 CPU のあるシステムでは、コントロールプレーン用に 0 - 3 の番号が付けられた CPU を予約して、コンピュートノードが CPU 4 - 23 を使用できるようにすることができます。

6.10.1. ノードの CPU の予約

特定のノード用に予約される CPU のリストを明示的に定義するには、KubeletConfig カスタムリソース (CR) を作成して reservedSystemCPUs パラメーターを定義します。このリストは、systemReserved パラメーターを使用して予約されている CPU よりも優先されます。

手順

  1. 設定する必要のあるノードタイプの Machine Config Pool (MCP) に関連付けられたラベルを取得します。

    $ oc describe machineconfigpool <name>

    以下に例を示します。

    $ oc describe machineconfigpool worker

    出力例

    Name:         worker
    Namespace:
    Labels:       machineconfiguration.openshift.io/mco-built-in=
                  pools.operator.machineconfiguration.openshift.io/worker= 1
    Annotations:  <none>
    API Version:  machineconfiguration.openshift.io/v1
    Kind:         MachineConfigPool
    #...

    1
    MCP ラベルを取得します。
  2. KubeletConfig CR の YAML ファイルを作成します。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: set-reserved-cpus 1
    spec:
      kubeletConfig:
        reservedSystemCPUs: "0,1,2,3" 2
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 3
    #...
    1
    CR の名前を指定します。
    2
    MCP に関連付けられたノード用に予約する CPU のコア ID を指定します。
    3
    MCP からラベルを指定します。
  3. CR オブジェクトを作成します。

    $ oc create -f <file_name>.yaml

関連情報

6.11. kubelet の TLS セキュリティープロファイルの有効化

TLS (Transport Layer Security) セキュリティープロファイルを使用して、kubelet が HTTP サーバーとして機能している際に必要とする TLS 暗号を定義できます。kubelet はその HTTP/GRPC サーバーを使用して Kubernetes API サーバーと通信し、コマンドを Pod に送信して kubelet 経由で Pod で exec コマンドを実行します。

TLS セキュリティープロファイルは、kubelet と Kubernetes API サーバー間の通信を保護するために、Kubernetes API サーバーが kubelet に接続する際に使用しなければならない TLS 暗号を定義します。

注記

デフォルトで、kubelet が Kubernetes API サーバーでクライアントとして動作する場合、TLS パラメーターを API サーバーと自動的にネゴシエートします。

6.11.1. TLS セキュリティープロファイルについて

TLS (Transport Layer Security) セキュリティープロファイルを使用して、さまざまな OpenShift Container Platform コンポーネントに必要な TLS 暗号を定義できます。OpenShift Container Platform の TLS セキュリティープロファイルは、Mozilla が推奨する設定 に基づいています。

コンポーネントごとに、以下の TLS セキュリティープロファイルのいずれかを指定できます。

表6.4 TLS セキュリティープロファイル
プロファイル説明

Old

このプロファイルは、レガシークライアントまたはライブラリーでの使用を目的としています。このプロファイルは、Old 後方互換性 の推奨設定に基づいています。

Old プロファイルには、最小 TLS バージョン 1.0 が必要です。

注記

Ingress Controller の場合、TLS の最小バージョンは 1.0 から 1.1 に変換されます。

Intermediate

このプロファイルは、大多数のクライアントに推奨される設定です。これは、Ingress Controller、kubelet、およびコントロールプレーンのデフォルトの TLS セキュリティープロファイルです。このプロファイルは、Intermediate 互換性 の推奨設定に基づいています。

Intermediate プロファイルには、最小 TLS バージョン 1.2 が必要です。

Modern

このプロファイルは、後方互換性を必要としない Modern のクライアントでの使用を目的としています。このプロファイルは、Modern 互換性 の推奨設定に基づいています。

Modern プロファイルには、最小 TLS バージョン 1.3 が必要です。

カスタム

このプロファイルを使用すると、使用する TLS バージョンと暗号を定義できます。

警告

無効な設定により問題が発生する可能性があるため、Custom プロファイルを使用する際には注意してください。

注記

事前定義されたプロファイルタイプのいずれかを使用する場合、有効なプロファイル設定はリリース間で変更される可能性があります。たとえば、リリース X.Y.Z にデプロイされた Intermediate プロファイルを使用する仕様がある場合、リリース X.Y.Z+1 へのアップグレードにより、新規のプロファイル設定が適用され、ロールアウトが生じる可能性があります。

6.11.2. kubelet の TLS セキュリティープロファイルの設定

HTTP サーバーとしての動作時に kubelet の TLS セキュリティープロファイルを設定するには、KubeletConfig カスタムリソース (CR) を作成して特定のノード用に事前定義済みの TLS セキュリティープロファイルまたはカスタム TLS セキュリティープロファイルを指定します。TLS セキュリティープロファイルが設定されていない場合には、TLS セキュリティープロファイルは Intermediate になります。

ワーカーノードで Old TLS セキュリティープロファイルを設定する KubeletConfig CR のサンプル

apiVersion: config.openshift.io/v1
kind: KubeletConfig
 ...
spec:
  tlsSecurityProfile:
    old: {}
    type: Old
  machineConfigPoolSelector:
    matchLabels:
      pools.operator.machineconfiguration.openshift.io/worker: ""
#...

設定済みのノードの kubelet.conf ファイルで、設定済みの TLS セキュリティープロファイルの暗号化および最小 TLS セキュリティープロファイルを確認できます。

前提条件

  • cluster-admin ロールを持つユーザーとして OpenShift Container Platform にログインしている。

手順

  1. KubeletConfig CR を作成し、TLS セキュリティープロファイルを設定します。

    カスタム プロファイルの KubeletConfig CR のサンプル

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: set-kubelet-tls-security-profile
    spec:
      tlsSecurityProfile:
        type: Custom 1
        custom: 2
          ciphers: 3
          - ECDHE-ECDSA-CHACHA20-POLY1305
          - ECDHE-RSA-CHACHA20-POLY1305
          - ECDHE-RSA-AES128-GCM-SHA256
          - ECDHE-ECDSA-AES128-GCM-SHA256
          minTLSVersion: VersionTLS11
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 4
    #...

    1
    TLS セキュリティープロファイルタイプ (OldIntermediate、または Custom) を指定します。デフォルトは Intermediate です。
    2
    選択したタイプに適切なフィールドを指定します。
    • old: {}
    • intermediate: {}
    • custom:
    3
    custom タイプには、TLS 暗号のリストと最小許容 TLS バージョンを指定します。
    4
    オプション: TLS セキュリティープロファイルを適用するノードのマシン設定プールラベルを指定します。
  2. KubeletConfig オブジェクトを作成します。

    $ oc create -f <filename>

    クラスター内のワーカーノードの数によっては、設定済みのノードが 1 つずつ再起動されるのを待機します。

検証

プロファイルが設定されていることを確認するには、ノードが Ready になってから以下の手順を実行します。

  1. 設定済みノードのデバッグセッションを開始します。

    $ oc debug node/<node_name>
  2. /host をデバッグシェル内のルートディレクトリーとして設定します。

    sh-4.4# chroot /host
  3. kubelet.conf ファイルを表示します。

    sh-4.4# cat /etc/kubernetes/kubelet.conf

    出力例

      "kind": "KubeletConfiguration",
      "apiVersion": "kubelet.config.k8s.io/v1beta1",
    #...
      "tlsCipherSuites": [
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
        "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
      ],
      "tlsMinVersion": "VersionTLS12",
    #...

6.12. Machine Config Daemon メトリック

Machine Config Daemon は Machine Config Operator の一部です。これはクラスター内のすべてのノードで実行されます。Machine Config Daemon は、各ノードの設定変更および更新を管理します。

6.12.1. Machine Config Daemon メトリック

OpenShift Container Platform 4.3 以降、Machine Config Daemon はメトリックのセットを提供します。これらのメトリクスには、Prometheus クラスターモニタリングスタックを使用してアクセスできます。

以下の表では、これらのメトリクスのセットを説明しています。一部のエントリーには、特定のログを取得するためのコマンドが含まれています。ただし、最も包括的なログのセットは oc adm must-gather コマンドを使用して利用できます。

注記

Name 列と Description 列に * が付いているメトリクスは、パフォーマンスの問題を引き起こす可能性のある重大なエラーを表します。このような問題により、更新およびアップグレードが続行されなくなる可能性があります。

表6.5 MCO メトリクス
名前形式説明備考

mcd_host_os_and_version

[]string{"os", "version"}

RHCOS や RHEL など、MCD が実行されている OS を示します。RHCOS の場合、バージョンは指定されます。

 

mcd_drain_err*

 

ドレイン (解放) の失敗時に受信されるエラーをログに記録します。*

ドレイン (解放) が成功するには、複数回試行する必要がある可能性があり、ターミナルでは、ドレイン (解放) に失敗すると更新を続行できなくなります。ドレイン (解放) にかかる時間を示す drain_time メトリクスはトラブルシューティングに役立つ可能性があります。

詳細な調査を実行するには、以下を実行してログを表示します。

$ oc logs -f -n openshift-machine-config-operator machine-config-daemon-<hash> -c machine-config-daemon

mcd_pivot_err*

[]string{"err", "node", "pivot_target"}

ピボットで発生するログ。*

ピボットのエラーにより、OS のアップグレードを続行できなくなる可能性があります。

さらに調査するには、次のコマンドを実行して machine-config-daemon コンテナーからのログを確認します。

$ oc logs -f -n openshift-machine-config-operator machine-config-daemon-<hash> -c machine-config-daemon

mcd_state

[]string{"state", "reason"}

指定ノードの Machine Config Daemon の状態。状態のオプションとして、"Done"、"Working"、および "Degraded" があります。"Degraded" の場合は、理由も含まれます。

詳細な調査を実行するには、以下を実行してログを表示します。

$ oc logs -f -n openshift-machine-config-operator machine-config-daemon-<hash> -c machine-config-daemon

mcd_kubelet_state*

 

kubelet の正常性に関する失敗をログに記録します。*

これは、失敗数が 0 で空になることが予想されます。失敗数が 2 を超えると、しきい値を超えたことを示すエラーが出されます。これは kubelet の正常性に関連した問題の可能性を示します。

詳細な調査を行うには、以下のコマンドを実行してノードにアクセスし、そのすべてのログを表示します。

$ oc debug node/<node> — chroot /host journalctl -u kubelet

mcd_reboot_err*

[]string{"message", "err", "node"}

再起動の失敗と対応するエラーをログに記録します。*

これは空になることが予想されますが、これは再起動が成功したことを示します。

詳細な調査を実行するには、以下を実行してログを表示します。

$ oc logs -f -n openshift-machine-config-operator machine-config-daemon-<hash> -c machine-config-daemon

mcd_update_state

[]string{"config", "err"}

設定更新の成功または失敗、および対応するエラーをログに記録します。

予想される値は rendered-master/rendered-worker-XXXX です。更新に失敗すると、エラーが表示されます。

詳細な調査を実行するには、以下を実行してログを表示します。

$ oc logs -f -n openshift-machine-config-operator machine-config-daemon-<hash> -c machine-config-daemon

6.13. インフラストラクチャーノードの作成

重要

高度なマシン管理およびスケーリング機能は、Machine API が動作しているクラスターでのみ使用できます。user-provisioned infrastructure を持つクラスターでは、Machine API を使用するために追加の検証と設定が必要です。

インフラストラクチャープラットフォームタイプが none のクラスターでは、Machine API を使用できません。この制限は、クラスターに接続されている計算マシンが、この機能をサポートするプラットフォームにインストールされている場合でも適用されます。このパラメーターは、インストール後に変更することはできません。

クラスターのプラットフォームタイプを表示するには、以下のコマンドを実行します。

$ oc get infrastructure cluster -o jsonpath='{.status.platform}'

インフラストラクチャーマシンセットを使用して、デフォルトのルーター、統合コンテナーイメージレジストリー、およびクラスターメトリクスおよびモニタリングのコンポーネントなどのインフラストラクチャーコンポーネントのみをホストするマシンを作成できます。これらのインフラストラクチャーマシンは、環境の実行に必要なサブスクリプションの合計数にカウントされません。

実稼働デプロイメントでは、インフラストラクチャーコンポーネントを保持するために 3 つ以上のマシンセットをデプロイすることが推奨されます。OpenShift Logging と Red Hat OpenShift Service Mesh の両方が Elasticsearch をデプロイします。これには、3 つのインスタンスを異なるノードにインストールする必要があります。これらの各ノードは、高可用性のために異なるアベイラビリティーゾーンにデプロイできます。この設定には、可用性ゾーンごとに 1 つずつ、合計 3 つの異なるマシンセットが必要です。複数のアベイラビリティーゾーンを持たないグローバル Azure リージョンでは、アベイラビリティーセットを使用して高可用性を確保できます。

注記

インフラストラクチャーノードに NoSchedule taint を追加すると、そのノードで実行されている既存の DNS Pod は misscheduled としてマークされます。misscheduled DNS Pod に対する toleration の追加 または削除を行う必要があります。

6.13.1. OpenShift Container Platform インフラストラクチャーコンポーネント

セルフマネージド Red Hat OpenShift の各サブスクリプションには、OpenShift Container Platform とその他の OpenShift 関連コンポーネントのエンタイトルメントが含まれています。これらのエンタイトルメントは、OpenShift Container Platform のコントロールプレーンおよびインフラストラクチャーのワークロードを実行するために含まれています。サイジング時にこれらのエンタイトルメントを考慮する必要はありません。

インフラストラクチャーノードとしての要件を満たし、含まれるエンタイトルメントを使用するには、(エンドユーザーのアプリケーションに含まれない) クラスターをサポートするコンポーネントだけを、それらのインスタンス上で実行します。たとえば、次のコンポーネントがあります。

  • Kubernetes および OpenShift Container Platform コントロールプレーンサービス
  • デフォルトルーター
  • 統合コンテナーイメージレジストリー
  • HAProxy ベースの Ingress Controller
  • ユーザー定義プロジェクトのモニタリング用のコンポーネントを含む、クラスターメトリクスの収集またはモニタリングサービス
  • クラスター集計ロギング
  • Red Hat Quay
  • Red Hat OpenShift Data Foundation
  • Red Hat Advanced Cluster Management for Kubernetes
  • Kubernetes 用 Red Hat Advanced Cluster Security
  • Red Hat OpenShift GitOps
  • Red Hat OpenShift Pipelines
  • Red Hat OpenShift Service Mesh

他のコンテナー、Pod またはコンポーネントを実行するノードは、サブスクリプションが適用される必要のあるワーカーノードです。

インフラストラクチャーノードおよびインフラストラクチャーノードで実行できるコンポーネントの詳細は、OpenShift sizing and subscription guide for enterprise Kubernetes の「Red Hat OpenShift control plane and infrastructure nodes」セクションを参照してください。

インフラストラクチャーノードを作成するには、マシンセットを使用する か、ノードにラベルを付ける か、マシン設定プールを使用します

6.13.1.1. 専用インフラストラクチャーノードの作成
重要

installer-provisioned infrastructure 環境またはコントロールプレーンノードがマシン API によって管理されているクラスターについて、Creating infrastructure machine set を参照してください。

クラスターの要件により、インフラストラクチャー ( infra ノードとも呼ばれる) がプロビジョニングされます。インストーラーは、コントロールプレーンノードとワーカーノードのプロビジョニングのみを提供します。ワーカーノードは、ラベル付けによって、インフラストラクチャーノードまたはアプリケーション (app とも呼ばれる) として指定できます。

手順

  1. アプリケーションノードとして機能させるワーカーノードにラベルを追加します。

    $ oc label node <node-name> node-role.kubernetes.io/app=""
  2. インフラストラクチャーノードとして機能する必要のあるワーカーノードにラベルを追加します。

    $ oc label node <node-name> node-role.kubernetes.io/infra=""
  3. 該当するノードに infra ロールおよび app ロールがあるかどうかを確認します。

    $ oc get nodes
  4. デフォルトのクラスタースコープのセレクターを作成するには、以下を実行します。デフォルトのノードセレクターはすべての namespace で作成された Pod に適用されます。これにより、Pod の既存のノードセレクターとの交差が作成され、Pod のセレクターをさらに制限します。

    重要

    デフォルトのノードセレクターのキーが Pod のラベルのキーと競合する場合、デフォルトのノードセレクターは適用されません。

    ただし、Pod がスケジュール対象外になる可能性のあるデフォルトノードセレクターを設定しないでください。たとえば、Pod のラベルが node-role.kubernetes.io/master="" などの別のノードロールに設定されている場合、デフォルトのノードセレクターを node-role.kubernetes.io/infra="" などの特定のノードロールに設定すると、Pod がスケジュール不能になる可能性があります。このため、デフォルトのノードセレクターを特定のノードロールに設定する際には注意が必要です。

    または、プロジェクトノードセレクターを使用して、クラスター全体でのノードセレクターの競合を避けることができます。

    1. Scheduler オブジェクトを編集します。

      $ oc edit scheduler cluster
    2. 適切なノードセレクターと共に defaultNodeSelector フィールドを追加します。

      apiVersion: config.openshift.io/v1
      kind: Scheduler
      metadata:
        name: cluster
      spec:
        defaultNodeSelector: node-role.kubernetes.io/infra="" 1
      # ...
      1
      この例のノードセレクターは、デフォルトでインフラストラクチャーノードに Pod をデプロイします。
    3. 変更を適用するためにファイルを保存します。

これで、インフラストラクチャーリソースを新しくラベル付けされた infra ノードに移動できます。

第7章 コンテナーの使用

7.1. コンテナーについて

OpenShift Container Platform アプリケーションの基本的な単位は コンテナー と呼ばれています。Linux コンテナーテクノロジー は、指定されたリソースのみと対話するために実行中のプロセスを分離する軽量なメカニズムです。

数多くのアプリケーションインスタンスは、相互のプロセス、ファイル、ネットワークなどを可視化せずに単一ホストのコンテナーで実行される可能性があります。通常、コンテナーは任意のワークロードに使用されますが、各コンテナーは Web サーバーまたはデータベースなどの (通常は "マイクロサービス" と呼ばれることが多い) 単一サービスを提供します。

Linux カーネルは数年にわたりコンテナーテクノロジーの各種機能を統合してきました。OpenShift Container Platform および Kubernetes は複数ホストのインストール間でコンテナーのオーケストレーションを実行する機能を追加します。

7.1.1. コンテナーおよび RHEL カーネルメモリーについて

Red Hat Enterprise Linux (RHEL) の動作により、CPU 使用率の高いノードのコンテナーは、予想以上に多いメモリーを消費しているように見える可能性があります。メモリー消費量の増加は、RHEL カーネルの kmem_cache によって引き起こされる可能性があります。RHEL カーネルは、それぞれの cgroup に kmem_cache を作成します。パフォーマンスの強化のために、kmem_cache には cpu_cache と任意の NUMA ノードのノードキャッシュが含まれます。これらのキャッシュはすべてカーネルメモリーを消費します。

これらのキャッシュに保存されるメモリーの量は、システムが使用する CPU の数に比例します。結果として、CPU の数が増えると、より多くのカーネルメモリーがこれらのキャッシュに保持されます。これらのキャッシュのカーネルメモリーの量が増えると、OpenShift Container Platform コンテナーで設定済みのメモリー制限を超える可能性があり、これにより、コンテナーが強制終了される可能性があります。

カーネルメモリーの問題によりコンテナーが失われないようにするには、コンテナーが十分なメモリーを要求することを確認します。以下の式を使用して、kmem_cache が消費するメモリー量を見積ることができます。この場合、nproc は、nproc コマンドで報告される利用可能なプロセス数です。コンテナーの要求の上限が低くなる場合、この値にコンテナーメモリーの要件を加えた分になります。

$(nproc) X 1/2 MiB

7.1.2. コンテナーエンジンとコンテナーランタイムについて

コンテナーエンジン は、コマンドラインオプションやイメージのプルなど、ユーザーの要求を処理するソフトウェアです。コンテナーエンジンは、コンテナーランタイム (下位レベルのコンテナーランタイム とも呼ばれる) を使用して、コンテナーのデプロイと操作に必要なコンポーネントを実行および管理します。コンテナーエンジンまたはコンテナーランタイムとやり取りする必要はほとんどありません。

注記

OpenShift Container Platform のドキュメントでは、コンテナーランタイムという用語を使用して、下位レベルのコンテナー ランタイム を指します。他のドキュメントでは、コンテナーエンジンをコンテナーランタイムと呼んでいる場合があります。

OpenShift Container Platform は、コンテナーエンジンとして CRI-O を使用し、コンテナーランタイムとして runC または crun を使用します。デフォルトのコンテナーランタイムは runC です。どちらのコンテナーランタイムも、Open Container Initiative (OCI) ランタイム仕様に準拠しています。

CRI-O は Kubernetes ネイティブコンテナーエンジン実装です。これはオペレーティングシステムに密接に統合し、Kubernetes の効率的で最適化されたエクスペリエンスを提供します。CRI-O コンテナーエンジンは、各 OpenShift Container Platform クラスターノードで systemd サービスとして実行されます。

Docker によって開発され、Open Container Project によって維持されている runC は、Go で記述された軽量で移植可能なコンテナーランタイムです。Red Hat によって開発された crun は、完全に C で記述された高速で低メモリーのコンテナーランタイムです。OpenShift Container Platform 4.14 の時点で、2 つのいずれかを選択できます。

crun は、runC に対して次のようないくつかの改善点があります。

  • 小さいバイナリー
  • より迅速な処理
  • メモリーのフットプリントが小さい。

runC には、次のような利点があります。

  • 最も一般的な OCI コンテナーランタイム。
  • 生産期間が長くなります。
  • CRI-O のデフォルトのコンテナーランタイム。

必要に応じて、2 つのコンテナーランタイム間を移動できます。

使用するコンテナーランタイムの設定は、CRI-O パラメーターの編集に使用する ContainerRuntimeConfig CR の作成 を参照してください。

7.2. Pod のデプロイ前の、Init コンテナーの使用によるタスクの実行

OpenShift Container Platform は、Init コンテナー を提供します。 このコンテナーは、アプリケーションコンテナーの前に実行される特殊なコンテナーであり、アプリのイメージに存在しないユーティリティーまたはセットアップスクリプトを含めることができます。

7.2.1. Init コンテナーについて

Pod の残りの部分がデプロイされる前に、init コンテナーリソースを使用して、タスクを実行することができます。

Pod は、アプリケーションコンテナーに加えて、init コンテナーを持つことができます。Init コンテナーにより、セットアップスクリプトとバインディングコードを再編成できます。

Init コンテナーは以下のことを行うことができます。

  • セキュリティー上の理由のためにアプリケーションコンテナーイメージに含めることが望ましくないユーティリティーを含めることができ、それらを実行できます。
  • アプリのイメージに存在しないセットアップに必要なユーティリティーまたはカスタムコードを含めることができます。たとえば、単に Sed、Awk、Python、Dig のようなツールをセットアップ時に使用するために別のイメージからイメージを作成する必要はありません。
  • Linux namespace を使用して、アプリケーションコンテナーがアクセスできないシークレットへのアクセスなど、アプリケーションコンテナーとは異なるファイルシステムビューを設定できます。

各 Init コンテナーは、次のコンテナーが起動する前に正常に完了している必要があります。そのため、Init コンテナーには、一連の前提条件が満たされるまでアプリケーションコンテナーの起動をブロックしたり、遅延させたりする簡単な方法となります。

たとえば、以下は Init コンテナーを使用するいくつかの方法になります。

  • 以下のようなシェルコマンドでサービスが作成されるまで待機します。

    for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
  • 以下のようなコマンドを使用して、Downward API からリモートサーバーにこの Pod を登録します。

    $ curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d ‘instance=$()&ip=$()’
  • sleep 60 のようなコマンドを使用して、アプリケーションコンテナーが起動するまでしばらく待機します。
  • Git リポジトリーのクローンをボリュームに作成します。
  • 設定ファイルに値を入力し、テンプレートツールを実行して、主要なアプリコンテナーの設定ファイルを動的に生成します。たとえば、設定ファイルに POD_IP の値を入力し、Jinja を使用して主要なアプリ設定ファイルを生成します。

詳細は、Kubernetes ドキュメント を参照してください。

7.2.2. Init コンテナーの作成

以下の例は、2 つの init コンテナーを持つ単純な Pod の概要を示しています。1 つ目は myservice を待機し、2 つ目は mydb を待機します。両方のコンテナーが完了すると、Pod が開始されます。

手順

  1. Init コンテナーの Pod を作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: myapp-pod
        labels:
          app: myapp
      spec:
        containers:
        - name: myapp-container
          image: registry.access.redhat.com/ubi9/ubi:latest
          command: ['sh', '-c', 'echo The app is running! && sleep 3600']
        initContainers:
        - name: init-myservice
          image: registry.access.redhat.com/ubi9/ubi:latest
          command: ['sh', '-c', 'until getent hosts myservice; do echo waiting for myservice; sleep 2; done;']
        - name: init-mydb
          image: registry.access.redhat.com/ubi9/ubi:latest
          command: ['sh', '-c', 'until getent hosts mydb; do echo waiting for mydb; sleep 2; done;']
      # ...
    2. Pod を作成します。

      $ oc create -f myapp.yaml
    3. Pod のステータスを表示します。

      $ oc get pods

      出力例

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     0/1       Init:0/2            0          5s

      Pod のステータス Init:0/2 は、2 つのサービスを待機していることを示します。

  2. myservice サービスを作成します。

    1. 以下のような YAML ファイルを作成します。

      kind: Service
      apiVersion: v1
      metadata:
        name: myservice
      spec:
        ports:
        - protocol: TCP
          port: 80
          targetPort: 9376
    2. Pod を作成します。

      $ oc create -f myservice.yaml
    3. Pod のステータスを表示します。

      $ oc get pods

      出力例

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     0/1       Init:1/2            0          5s

      Pod のステータス Init:1/2 は、1 つのサービス (この場合は mydb サービス) を待機していることを示します。

  3. mydb サービスを作成します。

    1. 以下のような YAML ファイルを作成します。

      kind: Service
      apiVersion: v1
      metadata:
        name: mydb
      spec:
        ports:
        - protocol: TCP
          port: 80
          targetPort: 9377
    2. Pod を作成します。

      $ oc create -f mydb.yaml
    3. Pod のステータスを表示します。

      $ oc get pods

      出力例

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     1/1       Running             0          2m

      Pod のステータスは、サービスを待機しておらず、実行中であることを示していました。

7.3. ボリュームの使用によるコンテナーデータの永続化

コンテナー内のファイルは一時的なものです。そのため、コンテナーがクラッシュしたり停止したりした場合は、データが失われます。ボリューム を使用すると、Pod 内のコンテナーが使用しているデータを永続化できます。ボリュームはディレクトリーであり、Pod 内のコンテナーからアクセスすることができます。 ここでは、データが Pod の有効期間中保存されます。

7.3.1. ボリュームについて

ボリュームとは Pod およびコンテナーで利用可能なマウントされたファイルシステムのことであり、これらは数多くのホストのローカルまたはネットワーク割り当てストレージのエンドポイントでサポートされる場合があります。コンテナーはデフォルトで永続性がある訳ではなく、それらのコンテンツは再起動時にクリアされます。

ボリュームのファイルシステムにエラーが含まれないようにし、かつエラーが存在する場合はそれを修復するために、OpenShift Container Platform は mount ユーティリティーの前に fsck ユーティリティーを起動します。これはボリュームを追加するか、既存ボリュームを更新する際に実行されます。

最も単純なボリュームタイプは emptyDir です。これは、単一マシンの一時的なディレクトリーです。管理者はユーザーによる Pod に自動的に割り当てられる永続ボリュームの要求を許可することもできます。

注記

emptyDir ボリュームストレージは、FSGroup パラメーターがクラスター管理者によって有効にされている場合は Pod の FSGroup に基づいてクォータで制限できます。

7.3.2. OpenShift Container Platform CLI によるボリュームの操作

CLI コマンド oc set volume を使用して、レプリケーションコントローラーやデプロイメント設定などの Pod テンプレートを持つオブジェクトのボリュームおよびボリュームマウントを追加し、削除することができます。また、Pod または Pod テンプレートを持つオブジェクトのボリュームをリスト表示することもできます。

oc set volume コマンドは以下の一般的な構文を使用します。

$ oc set volume <object_selection> <operation> <mandatory_parameters> <options>
オブジェクトの選択
oc set volume コマンドの object_seletion パラメーターに、以下のいずれかを指定します。
表7.1 オブジェクトの選択
構文説明

<object_type> <name>

タイプ <object_type><name> を選択します。

deploymentConfig registry

<object_type>/<name>

タイプ <object_type><name> を選択します。

deploymentConfig/registry

<object_type>--selector=<object_label_selector>

所定のラベルセレクターに一致するタイプ <object_type> のリソースを選択します。

deploymentConfig--selector="name=registry"

<object_type> --all

タイプ <object_type> のすべてのリソースを選択します。

deploymentConfig --all

-f または --filename=<file_name>

リソースを編集するために使用するファイル名、ディレクトリー、または URL です。

-f registry-deployment-config.json

操作
oc set volume コマンドの operation パラメーターに --add または --remove を指定します。
必須パラメーター
いずれの必須パラメーターも選択された操作に固有のものであり、これらについては後のセクションで説明します。
オプション
いずれのオプションも選択された操作に固有のものであり、これらについては後のセクションで説明します。

7.3.3. Pod のボリュームとボリュームマウントのリスト表示

Pod または Pod テンプレートのボリュームおよびボリュームマウントをリスト表示することができます。

手順

ボリュームをリスト表示するには、以下の手順を実行します。

$ oc set volume <object_type>/<name> [options]

ボリュームのサポートされているオプションをリスト表示します。

オプション説明デフォルト

--name

ボリュームの名前。

 

-c, --containers

名前でコンテナーを選択します。すべての文字に一致するワイルドカード '*' を取ることもできます。

'*'

以下に例を示します。

  • Pod p1 のすべてのボリュームをリスト表示するには、以下を実行します。

    $ oc set volume pod/p1
  • すべてのデプロイメント設定で定義されるボリューム v1 をリスト表示するには、以下の手順を実行します。

    $ oc set volume dc --all --name=v1

7.3.4. Pod へのボリュームの追加

Pod にボリュームとボリュームマウントを追加することができます。

手順

ボリューム、ボリュームマウントまたはそれらの両方を Pod テンプレートに追加するには、以下を実行します。

$ oc set volume <object_type>/<name> --add [options]
表7.2 ボリュームを追加するためのサポートされるオプション
オプション説明デフォルト

--name

ボリュームの名前。

指定がない場合は、自動的に生成されます。

-t, --type

ボリュームソースの名前。サポートされる値は emptyDirhostPathsecretconfigmappersistentVolumeClaim または projected です。

emptyDir

-c, --containers

名前でコンテナーを選択します。すべての文字に一致するワイルドカード '*' を取ることもできます。

'*'

-m, --mount-path

選択されたコンテナー内のマウントパス。コンテナーのルート (/) や、ホストとコンテナーで同じパスにはマウントしないでください。これは、コンテナーに十分な特権が付与されている場合に、ホストシステムを破壊する可能性があります (例: ホストの /dev/pts ファイル)。ホストをマウントするには、/host を使用するのが安全です。

 

--path

ホストパス。--type=hostPath の必須パラメーターです。コンテナーのルート (/) や、ホストとコンテナーで同じパスにはマウントしないでください。これは、コンテナーに十分な特権が付与されている場合に、ホストシステムを破壊する可能性があります (例: ホストの /dev/pts ファイル)。ホストをマウントするには、/host を使用するのが安全です。

 

--secret-name

シークレットの名前。--type=secret の必須パラメーターです。

 

--configmap-name

configmap の名前。--type=configmap の必須のパラメーターです。

 

--claim-name

永続ボリューム要求の名前。--type=persistentVolumeClaim の必須パラメーターです。

 

--source

JSON 文字列としてのボリュームソースの詳細。必要なボリュームソースが --type でサポートされない場合に推奨されます。

 

-o, --output

サーバー上で更新せずに変更したオブジェクトを表示します。サポートされる値は jsonyaml です。

 

--output-version

指定されたバージョンで変更されたオブジェクトを出力します。

api-version

以下に例を示します。

  • 新規ボリュームソース emptyDirregistry DeploymentConfig オブジェクトに追加するには、以下を実行します。

    $ oc set volume dc/registry --add
    ヒント

    あるいは、以下の YAML を適用してボリュームを追加できます。

    例7.1 ボリュームを追加したデプロイメント設定の例

    kind: DeploymentConfig
    apiVersion: apps.openshift.io/v1
    metadata:
      name: registry
      namespace: registry
    spec:
      replicas: 3
      selector:
        app: httpd
      template:
        metadata:
          labels:
            app: httpd
        spec:
          volumes: 1
            - name: volume-pppsw
              emptyDir: {}
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              ports:
                - containerPort: 8080
                  protocol: TCP
    1
    ボリュームソース emptyDir を追加します。
  • レプリケーションコントローラー r1 のシークレット secret1 を使用してボリューム v1 を追加し、コンテナー内の /data でマウントするには、以下を実行します。

    $ oc set volume rc/r1 --add --name=v1 --type=secret --secret-name='secret1' --mount-path=/data
    ヒント

    あるいは、以下の YAML を適用してボリュームを追加できます。

    例7.2 ボリュームおよびシークレットを追加したレプリケーションコントローラーの例

    kind: ReplicationController
    apiVersion: v1
    metadata:
      name: example-1
      namespace: example
    spec:
      replicas: 0
      selector:
        app: httpd
        deployment: example-1
        deploymentconfig: example
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: httpd
            deployment: example-1
            deploymentconfig: example
        spec:
          volumes: 1
            - name: v1
              secret:
                secretName: secret1
                defaultMode: 420
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              volumeMounts: 2
                - name: v1
                  mountPath: /data
    1
    ボリュームおよびシークレットを追加します。
    2
    コンテナーのマウントパスを追加します。
  • 要求名 pvc1 を使用して既存の永続ボリューム v1 をディスク上のデプロイメント設定 dc.json に追加し、ボリュームをコンテナー c1/data にマウントし、サーバー上で DeploymentConfig オブジェクトを更新します。

    $ oc set volume -f dc.json --add --name=v1 --type=persistentVolumeClaim \
      --claim-name=pvc1 --mount-path=/data --containers=c1
    ヒント

    あるいは、以下の YAML を適用してボリュームを追加できます。

    例7.3 永続ボリュームが追加されたデプロイメント設定の例

    kind: DeploymentConfig
    apiVersion: apps.openshift.io/v1
    metadata:
      name: example
      namespace: example
    spec:
      replicas: 3
      selector:
        app: httpd
      template:
        metadata:
          labels:
            app: httpd
        spec:
          volumes:
            - name: volume-pppsw
              emptyDir: {}
            - name: v1 1
              persistentVolumeClaim:
                claimName: pvc1
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              ports:
                - containerPort: 8080
                  protocol: TCP
              volumeMounts: 2
                - name: v1
                  mountPath: /data
    1
    `pvc1 という名前の永続ボリューム要求を追加します。
    2
    コンテナーのマウントパスを追加します。
  • すべてのレプリケーションコントローラー向けにリビジョン 5125c45f9f563 を使い、Git リポジトリー https://github.com/namespace1/project1 に基づいてボリューム v1 を追加するには、以下の手順を実行します。

    $ oc set volume rc --all --add --name=v1 \
      --source='{"gitRepo": {
                    "repository": "https://github.com/namespace1/project1",
                    "revision": "5125c45f9f563"
                }}'

7.3.5. Pod 内のボリュームとボリュームマウントの更新

Pod 内のボリュームとボリュームマウントを変更することができます。

手順

--overwrite オプションを使用して、既存のボリュームを更新します。

$ oc set volume <object_type>/<name> --add --overwrite [options]

以下に例を示します。

  • レプリケーションコントローラー r1 の既存ボリューム v1 を既存の永続ボリューム要求 pvc1 に置き換えるには、以下の手順を実行します。

    $ oc set volume rc/r1 --add --overwrite --name=v1 --type=persistentVolumeClaim --claim-name=pvc1
    ヒント

    または、以下の YAML を適用してボリュームを置き換えることもできます。

    例7.4 pvc1という名前の永続ボリューム要求を持つレプリケーションコントローラーの例

    kind: ReplicationController
    apiVersion: v1
    metadata:
      name: example-1
      namespace: example
    spec:
      replicas: 0
      selector:
        app: httpd
        deployment: example-1
        deploymentconfig: example
      template:
        metadata:
          labels:
            app: httpd
            deployment: example-1
            deploymentconfig: example
        spec:
          volumes:
            - name: v1 1
              persistentVolumeClaim:
                claimName: pvc1
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              ports:
                - containerPort: 8080
                  protocol: TCP
              volumeMounts:
                - name: v1
                  mountPath: /data
    1
    永続ボリューム要求を pvc1 に設定します。
  • DeploymentConfig オブジェクトの d1 のマウントポイントを、ボリューム v1/opt に変更するには、以下を実行します。

    $ oc set volume dc/d1 --add --overwrite --name=v1 --mount-path=/opt
    ヒント

    または、以下の YAML を適用してマウントポイントを変更できます。

    例7.5 マウントポイントがoptに設定されたデプロイメント設定の例

    kind: DeploymentConfig
    apiVersion: apps.openshift.io/v1
    metadata:
      name: example
      namespace: example
    spec:
      replicas: 3
      selector:
        app: httpd
      template:
        metadata:
          labels:
            app: httpd
        spec:
          volumes:
            - name: volume-pppsw
              emptyDir: {}
            - name: v2
              persistentVolumeClaim:
                claimName: pvc1
            - name: v1
              persistentVolumeClaim:
                claimName: pvc1
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              ports:
                - containerPort: 8080
                  protocol: TCP
              volumeMounts: 1
                - name: v1
                  mountPath: /opt
    1
    マウントポイントを /opt に設定します。

7.3.6. Pod からのボリュームおよびボリュームマウントの削除

Pod からボリュームまたはボリュームマウントを削除することができます。

手順

Pod テンプレートからボリュームを削除するには、以下を実行します。

$ oc set volume <object_type>/<name> --remove [options]
表7.3 ボリュームを削除するためにサポートされるオプション
オプション説明デフォルト

--name

ボリュームの名前。

 

-c, --containers

名前でコンテナーを選択します。すべての文字に一致するワイルドカード '*' を取ることもできます。

'*'

--confirm

複数のボリュームを 1 度に削除することを示します。

 

-o, --output

サーバー上で更新せずに変更したオブジェクトを表示します。サポートされる値は jsonyaml です。

 

--output-version

指定されたバージョンで変更されたオブジェクトを出力します。

api-version

以下に例を示します。

  • DeploymentConfig オブジェクトの d1からボリューム v1 を削除するには、以下を実行します。

    $ oc set volume dc/d1 --remove --name=v1
  • DeploymentConfig オブジェクトの d1c1 のコンテナーからボリューム v1 をアンマウントし、d1 のコンテナーで参照されていない場合にボリューム v1 を削除するには、以下の手順を実行します。

    $ oc set volume dc/d1 --remove --name=v1 --containers=c1
  • レプリケーションコントローラー r1 のすべてのボリュームを削除するには、以下の手順を実行します。

    $ oc set volume rc/r1 --remove --confirm

7.3.7. Pod 内での複数の用途のためのボリュームの設定

ボリュームを、単一 Pod で複数の使用目的のためにボリュームを共有するように設定できます。この場合、volumeMounts.subPath プロパティーを使用し、ボリュームのルートの代わりにボリューム内に subPath 値を指定します。

注記

既存のスケジュールされた Pod に subPath パラメーターを追加することはできません。

手順

  1. ボリューム内のファイルのリストを表示するには、oc rsh コマンドを実行します。

    $ oc rsh <pod>

    出力例

    sh-4.2$ ls /path/to/volume/subpath/mount
    example_file1 example_file2 example_file3

  2. subPath を指定します。

    subPath パラメーターを含む Pod 仕様の例

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-site
    spec:
        containers:
        - name: mysql
          image: mysql
          volumeMounts:
          - mountPath: /var/lib/mysql
            name: site-data
            subPath: mysql 1
        - name: php
          image: php
          volumeMounts:
          - mountPath: /var/www/html
            name: site-data
            subPath: html 2
        volumes:
        - name: site-data
          persistentVolumeClaim:
            claimName: my-site-data

    1
    データベースは mysql フォルダーに保存されます。
    2
    HTML コンテンツは html フォルダーに保存されます。

7.4. Projected ボリュームによるボリュームのマッピング

Projected ボリューム は、いくつかの既存のボリュームソースを同じディレクトリーにマップします。

以下のタイプのボリュームソースをデプロイメントできます。

  • シークレット
  • Config Map
  • Downward API
注記

すべてのソースは Pod と同じ namespace に置かれる必要があります。

7.4.1. Projected ボリュームについて

Projected ボリュームはこれらのボリュームソースの任意の組み合わせを単一ディレクトリーにマップし、ユーザーの以下の実行を可能にします。

  • 単一ボリュームを、複数のシークレットのキー、設定マップ、および Downward API 情報で自動的に設定し、各種の情報ソースで単一ディレクトリーを合成できるようにします。
  • 各項目のパスを明示的に指定して、単一ボリュームを複数シークレットのキー、設定マップ、および Downward API 情報で設定し、ユーザーがボリュームの内容を完全に制御できるようにします。
重要

RunAsUser パーミッションが Linux ベースの Pod のセキュリティーコンテキストに設定されている場合、Projected ファイルには、コンテナーユーザー所有権を含む適切なパーミッションが設定されます。ただし、Windows の同等の RunAsUsername パーミッションが Windows Pod に設定されている場合、kubelet は Projected ボリュームのファイルに正しい所有権を設定できません。

そのため、Windows Pod のセキュリティーコンテキストに設定された RunAsUsername パーミッションは、OpenShift Container Platform で実行される Windows の Projected ボリュームには適用されません。

以下の一般的なシナリオは、Projected ボリュームを使用する方法を示しています。

設定マップ、シークレット、Downward API
Projected ボリュームを使用すると、パスワードが含まれる設定データでコンテナーをデプロイできます。これらのリソースを使用するアプリケーションは、Red Hat OpenStack Platform (RHOSP) を Kubernetes にデプロイしている可能性があります。設定データは、サービスが実稼働用またはテストで使用されるかによって異なった方法でアセンブルされる必要がある可能性があります。Pod に実稼働またはテストのラベルが付けられている場合、Downward API セレクター metadata.labels を使用して適切な RHOSP 設定を生成できます。
設定マップ + シークレット
Projected ボリュームにより、設定データおよびパスワードを使用してコンテナーをデプロイできます。たとえば、設定マップを、Vault パスワードファイルを使用して暗号解除する暗号化された機密タスクで実行する場合があります。
ConfigMap + Downward API.
Projected ボリュームにより、Pod 名 (metadata.name セレクターで選択可能) を含む設定を生成できます。このアプリケーションは IP トラッキングを使用せずに簡単にソースを判別できるよう要求と共に Pod 名を渡すことができます。
シークレット + Downward API
Projected ボリュームにより、Pod の namespace (metadata.namespace セレクターで選択可能) を暗号化するためのパブリックキーとしてシークレットを使用できます。この例では、Operator はこのアプリケーションを使用し、暗号化されたトランスポートを使用せずに namespace 情報を安全に送信できるようになります。
7.4.1.1. Pod 仕様の例

以下は、Projected ボリュームを作成するための Pod 仕様の例です。

シークレット、Downward API および設定マップを含む Pod

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts: 1
    - name: all-in-one
      mountPath: "/projected-volume"2
      readOnly: true 3
  volumes: 4
  - name: all-in-one 5
    projected:
      defaultMode: 0400 6
      sources:
      - secret:
          name: mysecret 7
          items:
            - key: username
              path: my-group/my-username 8
      - downwardAPI: 9
          items:
            - path: "labels"
              fieldRef:
                fieldPath: metadata.labels
            - path: "cpu_limit"
              resourceFieldRef:
                containerName: container-test
                resource: limits.cpu
      - configMap: 10
          name: myconfigmap
          items:
            - key: config
              path: my-group/my-config
              mode: 0777 11

1
シークレットを必要とする各コンテナーの volumeMounts セクションを追加します。
2
シークレットが表示される未使用ディレクトリーのパスを指定します。
3
readOnlytrue に設定します。
4
それぞれの Projected ボリュームソースをリスト表示するために volumes ブロックを追加します。
5
ボリュームの名前を指定します。
6
ファイルに実行パーミッションを設定します。
7
シークレットを追加します。シークレットオブジェクトの名前を追加します。使用する必要のあるそれぞれのシークレットはリスト表示される必要があります。
8
mountPath の下にシークレットへのパスを指定します。ここで、シークレットファイルは /projected-volume/my-group/my-username になります。
9
Downward API ソースを追加します。
10
ConfigMap ソースを追加します。
11
特定のデプロイメントにおけるモードを設定します。
注記

Pod に複数のコンテナーがある場合、それぞれのコンテナーには volumeMounts セクションが必要ですが、1 つの volumes セクションのみが必要になります。

デフォルト以外のパーミッションモデルが設定された複数シークレットを含む Pod

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      defaultMode: 0755
      sources:
      - secret:
          name: mysecret
          items:
            - key: username
              path: my-group/my-username
      - secret:
          name: mysecret2
          items:
            - key: password
              path: my-group/my-password
              mode: 511

注記

defaultMode はデプロイメントされるレベルでのみ指定でき、各ボリュームソースには指定されません。ただし、上記のように個々のデプロイメントに関する mode を明示的に指定できます。

7.4.1.2. パスに関する留意事項
設定されるパスが同一である場合のキー間の競合

複数のキーを同じパスで設定する場合、Pod 仕様は有効な仕様として受け入れられません。以下の例では、mysecret および myconfigmap に指定されるパスは同じです。

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      sources:
      - secret:
          name: mysecret
          items:
            - key: username
              path: my-group/data
      - configMap:
          name: myconfigmap
          items:
            - key: config
              path: my-group/data

ボリュームファイルのパスに関連する以下の状況を検討しましょう。

設定されたパスのないキー間の競合
上記のシナリオの場合と同様に、実行時の検証が実行される唯一のタイミングはすべてのパスが Pod の作成時に認識される時です。それ以外の場合は、競合の発生時に指定された最新のリソースがこれより前のすべてのものを上書きします (これは Pod 作成後に更新されるリソースについても同様です)。
1 つのパスが明示的なパスであり、もう 1 つのパスが自動的にデプロイメントされるパスである場合の競合
自動的にデプロイメントされるデータに一致するユーザー指定パスによって競合が生じる場合、前述のように後からのリソースがこれより前のすべてのものを上書きします。

7.4.2. Pod の Projected ボリュームの設定

Projected ボリュームを作成する場合は、Projected ボリュームについて で説明されているボリュームファイルパスの状態を考慮します。

以下の例では、Projected ボリュームを使用して、既存のシークレットボリュームソースをマウントする方法が示されています。以下の手順は、ローカルファイルからユーザー名およびパスワードのシークレットを作成するために実行できます。その後に、シークレットを同じ共有ディレクトリーにマウントするために Projected ボリュームを使用して 1 つのコンテナーを実行する Pod を作成します。

このユーザー名とパスワードの値には、base64 でエンコードされた任意の有効な文字列を使用できます。

以下の例は、base64 の admin を示しています。

$ echo -n "admin" | base64

出力例

YWRtaW4=

以下の例は、base64 のパスワード 1f2d1e2e67df を示しています。

$ echo -n "1f2d1e2e67df" | base64

出力例

MWYyZDFlMmU2N2Rm

手順

既存のシークレットボリュームソースをマウントするために Projected ボリュームを使用するには、以下を実行します。

  1. シークレットを作成します。

    1. 次のような YAML ファイルを作成し、パスワードとユーザー情報を適切に置き換えます。

      apiVersion: v1
      kind: Secret
      metadata:
        name: mysecret
      type: Opaque
      data:
        pass: MWYyZDFlMmU2N2Rm
        user: YWRtaW4=
    2. 以下のコマンドを使用してシークレットを作成します。

      $ oc create -f <secrets-filename>

      以下に例を示します。

      $ oc create -f secret.yaml

      出力例

      secret "mysecret" created

    3. シークレットが以下のコマンドを使用して作成されていることを確認できます。

      $ oc get secret <secret-name>

      以下に例を示します。

      $ oc get secret mysecret

      出力例

      NAME       TYPE      DATA      AGE
      mysecret   Opaque    2         17h

      $ oc get secret <secret-name> -o yaml

      以下に例を示します。

      $ oc get secret mysecret -o yaml
      apiVersion: v1
      data:
        pass: MWYyZDFlMmU2N2Rm
        user: YWRtaW4=
      kind: Secret
      metadata:
        creationTimestamp: 2017-05-30T20:21:38Z
        name: mysecret
        namespace: default
        resourceVersion: "2107"
        selfLink: /api/v1/namespaces/default/secrets/mysecret
        uid: 959e0424-4575-11e7-9f97-fa163e4bd54c
      type: Opaque
  2. 投影されたボリュームを持つ Pod を作成します。

    1. volumes セクションを含む、次のような YAML ファイルを作成します。

      kind: Pod
      metadata:
        name: test-projected-volume
      spec:
        containers:
        - name: test-projected-volume
          image: busybox
          args:
          - sleep
          - "86400"
          volumeMounts:
          - name: all-in-one
            mountPath: "/projected-volume"
            readOnly: true
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop:
                  - ALL
        volumes:
        - name: all-in-one
          projected:
            sources:
            - secret:
                name: mysecret 1
      1
      作成されたシークレットの名前。
    2. 設定ファイルから Pod を作成します。

      $ oc create -f <your_yaml_file>.yaml

      以下に例を示します。

      $ oc create -f secret-pod.yaml

      出力例

      pod "test-projected-volume" created

  3. Pod コンテナーが実行中であることを確認してから、Pod への変更を確認します。

    $ oc get pod <name>

    以下に例を示します。

    $ oc get pod test-projected-volume

    出力は以下のようになります。

    出力例

    NAME                    READY     STATUS    RESTARTS   AGE
    test-projected-volume   1/1       Running   0          14s

  4. 別のターミナルで、oc exec コマンドを使用し、実行中のコンテナーに対してシェルを開きます。

    $ oc exec -it <pod> <command>

    以下に例を示します。

    $ oc exec -it test-projected-volume -- /bin/sh
  5. シェルで、projected-volumes ディレクトリーにデプロイメントされるソースが含まれることを確認します。

    / # ls

    出力例

    bin               home              root              tmp
    dev               proc              run               usr
    etc               projected-volume  sys               var

7.5. コンテナーによる API オブジェクト使用の許可

Downward API は、OpenShift Container Platform に結合せずにコンテナーが API オブジェクトの情報を使用できるメカニズムです。この情報には、Pod の名前、namespace およびリソース値が含まれます。コンテナーは、環境変数やボリュームプラグインを使用して Downward API からの情報を使用できます。

7.5.1. Downward API の使用によるコンテナーへの Pod 情報の公開

Downward API には、Pod の名前、プロジェクト、リソースの値などの情報が含まれます。コンテナーは、環境変数やボリュームプラグインを使用して Downward API からの情報を使用できます。

Pod 内のフィールドは、FieldRef API タイプを使用して選択されます。FieldRef には 2 つのフィールドがあります。

フィールド説明

fieldPath

Pod に関連して選択するフィールドのパスです。

apiVersion

fieldPath セレクターの解釈に使用する API バージョンです。

現時点で v1 API の有効なセレクターには以下が含まれます。

セレクター説明

metadata.name

Pod の名前です。これは環境変数およびボリュームでサポートされています。

metadata.namespace

Pod の namespace です。 これは環境変数およびボリュームでサポートされています。

metadata.labels

Pod のラベルです。これはボリュームでのみサポートされ、環境変数ではサポートされていません。

metadata.annotations

Pod のアノテーションです。これはボリュームでのみサポートされ、環境変数ではサポートされていません。

status.podIP

Pod の IP です。これは環境変数でのみサポートされ、ボリュームではサポートされていません。

apiVersion フィールドは、指定されていない場合は、対象の Pod テンプレートの API バージョンにデフォルト設定されます。

7.5.2. Downward API を使用してコンテナーの値を使用する方法について

コンテナーは、環境変数やボリュームプラグインを使用して API の値を使用することができます。選択する方法により、コンテナーは以下を使用できます。

  • Pod の名前
  • Pod プロジェクト/namespace
  • Pod のアノテーション
  • Pod のラベル

アノテーションとラベルは、ボリュームプラグインのみを使用して利用できます。

7.5.2.1. 環境変数の使用によるコンテナー値の使用

コンテナーの環境変数を設定する際に、EnvVar タイプの valueFrom フィールド (タイプは EnvVarSource) を使用して、変数の値が value フィールドで指定されるリテラル値ではなく、FieldRef ソースからの値になるように指定します。

この方法で使用できるのは Pod の定数属性のみです。変数の値の変更についてプロセスに通知する方法でプロセスを起動すると、環境変数を更新できなくなるためです。環境変数を使用してサポートされるフィールドには、以下が含まれます。

  • Pod の名前
  • Pod プロジェクト/namespace

手順

  1. コンテナーで使用する環境変数を含む新しい Pod 仕様を作成します。

    1. 次のような pod.yaml ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: MY_POD_NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
        restartPolicy: Never
      # ...
    2. pod.yaml ファイルから Pod を作成します。

      $ oc create -f pod.yaml

検証

  • コンテナーのログで MY_POD_NAME および MY_POD_NAMESPACE の値を確認します。

    $ oc logs -p dapi-env-test-pod
7.5.2.2. ボリュームプラグインを使用したコンテナー値の使用

コンテナーは、ボリュームプラグイン使用して API 値を使用できます。

コンテナーは、以下を使用できます。

  • Pod の名前
  • Pod プロジェクト/namespace
  • Pod のアノテーション
  • Pod のラベル

手順

ボリュームプラグインを使用するには、以下の手順を実行します。

  1. コンテナーで使用する環境変数を含む新しい Pod 仕様を作成します。

    1. 次のような volume-pod.yaml ファイルを作成します。

      kind: Pod
      apiVersion: v1
      metadata:
        labels:
          zone: us-east-coast
          cluster: downward-api-test-cluster1
          rack: rack-123
        name: dapi-volume-test-pod
        annotations:
          annotation1: "345"
          annotation2: "456"
      spec:
        containers:
          - name: volume-test-container
            image: gcr.io/google_containers/busybox
            command: ["sh", "-c", "cat /tmp/etc/pod_labels /tmp/etc/pod_annotations"]
            volumeMounts:
              - name: podinfo
                mountPath: /tmp/etc
                readOnly: false
        volumes:
        - name: podinfo
          downwardAPI:
            defaultMode: 420
            items:
            - fieldRef:
                fieldPath: metadata.name
              path: pod_name
            - fieldRef:
                fieldPath: metadata.namespace
              path: pod_namespace
            - fieldRef:
                fieldPath: metadata.labels
              path: pod_labels
            - fieldRef:
                fieldPath: metadata.annotations
              path: pod_annotations
        restartPolicy: Never
      # ...
    2. volume-pod.yaml ファイルから Pod を作成します。

      $ oc create -f volume-pod.yaml

検証

  • コンテナーのログを確認し、設定されたフィールドの有無を確認します。

    $ oc logs -p dapi-volume-test-pod

    出力例

    cluster=downward-api-test-cluster1
    rack=rack-123
    zone=us-east-coast
    annotation1=345
    annotation2=456
    kubernetes.io/config.source=api

7.5.3. Downward API を使用してコンテナーリソースを使用する方法について

Pod の作成時に、Downward API を使用してコンピューティングリソースの要求および制限に関する情報を挿入し、イメージおよびアプリケーションの作成者が特定の環境用のイメージを適切に作成できるようにします。

環境変数またはボリュームプラグインを使用してこれを実行できます。

7.5.3.1. 環境変数を使用したコンテナーリソースの使用

Pod を作成するときは、Downward API を使用し、環境変数を使用してコンピューティングリソースの要求と制限に関する情報を挿入できます。

Pod 設定の作成時に、spec.container フィールド内の resources フィールドの内容に対応する環境変数を指定します。

注記

リソース制限がコンテナー設定に含まれていない場合、Downward API はデフォルトでノードの CPU およびメモリーの割り当て可能な値に設定されます。

手順

  1. 注入するリソースを含む新しい Pod 仕様を作成します。

    1. 次のような pod.yaml ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: test-container
            image: gcr.io/google_containers/busybox:1.24
            command: [ "/bin/sh", "-c", "env" ]
            resources:
              requests:
                memory: "32Mi"
                cpu: "125m"
              limits:
                memory: "64Mi"
                cpu: "250m"
            env:
              - name: MY_CPU_REQUEST
                valueFrom:
                  resourceFieldRef:
                    resource: requests.cpu
              - name: MY_CPU_LIMIT
                valueFrom:
                  resourceFieldRef:
                    resource: limits.cpu
              - name: MY_MEM_REQUEST
                valueFrom:
                  resourceFieldRef:
                    resource: requests.memory
              - name: MY_MEM_LIMIT
                valueFrom:
                  resourceFieldRef:
                    resource: limits.memory
      # ...
    2. pod.yaml ファイルから Pod を作成します。

      $ oc create -f pod.yaml
7.5.3.2. ボリュームプラグインを使用したコンテナーリソースの使用

Pod を作成するときは、Downward API を使用し、ボリュームプラグインを使用してコンピューティングリソースの要求と制限に関する情報を挿入できます。

Pod 設定の作成時に、spec.volumes.downwardAPI.items フィールドを使用して spec.resources フィールドに対応する必要なリソースを記述します。

注記

リソース制限がコンテナー設定に含まれていない場合、Downward API はデフォルトでノードの CPU およびメモリーの割り当て可能な値に設定されます。

手順

  1. 注入するリソースを含む新しい Pod 仕様を作成します。

    1. 次のような pod.yaml ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: client-container
            image: gcr.io/google_containers/busybox:1.24
            command: ["sh", "-c", "while true; do echo; if [[ -e /etc/cpu_limit ]]; then cat /etc/cpu_limit; fi; if [[ -e /etc/cpu_request ]]; then cat /etc/cpu_request; fi; if [[ -e /etc/mem_limit ]]; then cat /etc/mem_limit; fi; if [[ -e /etc/mem_request ]]; then cat /etc/mem_request; fi; sleep 5; done"]
            resources:
              requests:
                memory: "32Mi"
                cpu: "125m"
              limits:
                memory: "64Mi"
                cpu: "250m"
            volumeMounts:
              - name: podinfo
                mountPath: /etc
                readOnly: false
        volumes:
          - name: podinfo
            downwardAPI:
              items:
                - path: "cpu_limit"
                  resourceFieldRef:
                    containerName: client-container
                    resource: limits.cpu
                - path: "cpu_request"
                  resourceFieldRef:
                    containerName: client-container
                    resource: requests.cpu
                - path: "mem_limit"
                  resourceFieldRef:
                    containerName: client-container
                    resource: limits.memory
                - path: "mem_request"
                  resourceFieldRef:
                    containerName: client-container
                    resource: requests.memory
      # ...
    2. volume-pod.yaml ファイルから Pod を作成します。

      $ oc create -f volume-pod.yaml

7.5.4. Downward API を使用したシークレットの使用

Pod の作成時に、Downward API を使用してシークレットを挿入し、イメージおよびアプリケーションの作成者が特定の環境用のイメージを作成できるようにできます。

手順

  1. 注入するシークレットを作成します。

    1. 次のような secret.yaml ファイルを作成します。

      apiVersion: v1
      kind: Secret
      metadata:
        name: mysecret
      data:
        password: <password>
        username: <username>
      type: kubernetes.io/basic-auth
    2. secret.yaml ファイルからシークレットオブジェクトを作成します。

      $ oc create -f secret.yaml
  2. 上記の Secret オブジェクトから username フィールドを参照する Pod を作成します。

    1. 次のような pod.yaml ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_SECRET_USERNAME
                valueFrom:
                  secretKeyRef:
                    name: mysecret
                    key: username
        restartPolicy: Never
      # ...
    2. pod.yaml ファイルから Pod を作成します。

      $ oc create -f pod.yaml

検証

  • コンテナーのログで MY_SECRET_USERNAME の値を確認します。

    $ oc logs -p dapi-env-test-pod

7.5.5. Downward API を使用した設定マップの使用

Pod の作成時に、Downward API を使用して設定マップの値を挿入し、イメージおよびアプリケーションの作成者が特定の環境用のイメージを作成することができるようにすることができます。

手順

  1. 注入する値を含む config map を作成します。

    1. 次のような configmap.yaml ファイルを作成します。

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: myconfigmap
      data:
        mykey: myvalue
    2. configmap.yaml ファイルから config map を作成します。

      $ oc create -f configmap.yaml
  2. 上記の config map を参照する Pod を作成します。

    1. 次のような pod.yaml ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_CONFIGMAP_VALUE
                valueFrom:
                  configMapKeyRef:
                    name: myconfigmap
                    key: mykey
        restartPolicy: Always
      # ...
    2. pod.yaml ファイルから Pod を作成します。

      $ oc create -f pod.yaml

検証

  • コンテナーのログで MY_CONFIGMAP_VALUE の値を確認します。

    $ oc logs -p dapi-env-test-pod

7.5.6. 環境変数の参照

Pod の作成時に、$() 構文を使用して事前に定義された環境変数の値を参照できます。環境変数の参照が解決されない場合、値は提供された文字列のままになります。

手順

  1. 既存の環境変数を参照する Pod を作成します。

    1. 次のような pod.yaml ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_EXISTING_ENV
                value: my_value
              - name: MY_ENV_VAR_REF_ENV
                value: $(MY_EXISTING_ENV)
        restartPolicy: Never
      # ...
    2. pod.yaml ファイルから Pod を作成します。

      $ oc create -f pod.yaml

検証

  • コンテナーのログで MY_ENV_VAR_REF_ENV 値を確認します。

    $ oc logs -p dapi-env-test-pod

7.5.7. 環境変数の参照のエスケープ

Pod の作成時に、二重ドル記号を使用して環境変数の参照をエスケープできます。次に値は指定された値の単一ドル記号のバージョンに設定されます。

手順

  1. 既存の環境変数を参照する Pod を作成します。

    1. 次のような pod.yaml ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_NEW_ENV
                value: $$(SOME_OTHER_ENV)
        restartPolicy: Never
      # ...
    2. pod.yaml ファイルから Pod を作成します。

      $ oc create -f pod.yaml

検証

  • コンテナーのログで MY_NEW_ENV 値を確認します。

    $ oc logs -p dapi-env-test-pod

7.6. OpenShift Container Platform コンテナーへの/からのファイルのコピー

CLI を使用して、rsync コマンドでコンテナーのリモートディレクトリーにローカルファイルをコピーするか、そのディレクトリーからローカルファイルをコピーすることができます。

7.6.1. ファイルをコピーする方法について

oc rsync コマンドまたは remote sync は、バックアップと復元を実行するためにデータベースアーカイブを Pod にコピー、または Pod からコピーするのに役立つツールです。また、実行中の Pod がソースファイルのホットリロードをサポートする場合に、ソースコードの変更を開発のデバッグ目的で実行中の Pod にコピーするためにも、oc rsync を使用できます。

$ oc rsync <source> <destination> [-c <container>]
7.6.1.1. 要件
Copy Source の指定

oc rsync コマンドのソース引数はローカルディレクトリーまた Pod ディレクトリーのいずれかを示す必要があります。個々のファイルはサポートされていません。

Pod ディレクトリーを指定する場合、ディレクトリー名の前に Pod 名を付ける必要があります。

<pod name>:<dir>

ディレクトリー名がパスセパレーター (/) で終了する場合、ディレクトリーの内容のみが宛先にコピーされます。それ以外の場合は、ディレクトリーとその内容が宛先にコピーされます。

Copy Destination の指定
oc rsync コマンドの宛先引数はディレクトリーを参照する必要があります。ディレクトリーが存在せず、rsync がコピーに使用される場合、ディレクトリーが作成されます。
宛先でのファイルの削除
--delete フラグは、ローカルディレクトリーにないリモートディレクトリーにあるファイルを削除するために使用できます。
ファイル変更に関する継続的な同期

--watch オプションを使用すると、コマンドはソースパスでファイルシステムの変更をモニターし、変更が生じるとそれらを同期します。この引数を指定すると、コマンドは無期限に実行されます。

同期は短い非表示期間の後に実行され、急速に変化するファイルシステムによって同期呼び出しが継続的に実行されないようにします。

--watch オプションを使用する場合、動作は通常 oc rsync に渡される引数の使用を含め oc rsync を繰り返し手動で起動する場合と同様になります。そのため、--delete などの oc rsync の手動の呼び出しで使用される同じフラグでこの動作を制御できます。

7.6.2. コンテナーへの/からのファイルのコピー

コンテナーへの/からのローカルファイルのコピーのサポートは CLI に組み込まれています。

前提条件

oc rsync を使用する場合は、以下の点に注意してください。

  • rsync がインストールされていること。oc rsync コマンドは、クライアントマシンおよびリモートコンテナー上に存在する場合は、ローカルの rsync ツールを使用。

    rsync がローカルの場所またはリモートコンテナーに見つからない場合は、tar アーカイブがローカルに作成されてからコンテナーに送信されます。ここで、tar ユーティリティーがファイルのデプロイメントに使用されます。リモートコンテナーで tar を利用できない場合は、コピーに失敗します。

    tar のコピー方法は oc rsync と同様に機能する訳ではありません。たとえば、oc rsync は、宛先ディレクトリーが存在しない場合にはこれを作成し、ソースと宛先間の差分のファイルのみを送信します。

    注記

    Windows では、cwRsync クライアントが oc rsync コマンドで使用するためにインストールされ、PATH に追加される必要があります。

手順

  • ローカルディレクトリーを Pod ディレクトリーにコピーするには、以下の手順を実行します。

    $ oc rsync <local-dir> <pod-name>:/<remote-dir> -c <container-name>

    以下に例を示します。

    $ oc rsync /home/user/source devpod1234:/src -c user-container
  • Pod ディレクトリーをローカルディレクトリーにコピーするには、以下の手順を実行します。

    $ oc rsync devpod1234:/src /home/user/source

    出力例

    $ oc rsync devpod1234:/src/status.txt /home/user/

7.6.3. 高度な Rsync 機能の使用

oc rsync コマンドは標準の rsync よりも少ないコマンドラインのオプションを表示します。oc rsync で利用できない標準の rsync コマンドラインオプションを使用する必要がある場合 (例: --exclude-from=FILE オプション)、以下のように回避策として標準 rsync--rsh (-e) オプション、または RSYNC_RSH 環境変数を使用できる場合があります。

$ rsync --rsh='oc rsh' --exclude-from=<file_name> <local-dir> <pod-name>:/<remote-dir>

または、以下を実行します。

RSYNC_RSH 変数をエクスポートします。

$ export RSYNC_RSH='oc rsh'

次に、rsync コマンドを実行します。

$ rsync --exclude-from=<file_name> <local-dir> <pod-name>:/<remote-dir>

上記の例のいずれも標準の rsync をリモートシェルプログラムとして oc rsh を使用するように設定してリモート Pod に接続できるようにします。これらは oc rsync を実行する代替方法となります。

7.7. OpenShift Container Platform コンテナーでのリモートコマンドの実行

OpenShift Container Platform コンテナーでリモートコマンドを実行するために、CLI を使用することができます。

7.7.1. コンテナーでのリモートコマンドの実行

リモートコンテナーコマンドの実行についてサポートは CLI に組み込まれています。

手順

コンテナーでコマンドを実行するには、以下の手順を実行します。

$ oc exec <pod> [-c <container>] -- <command> [<arg_1> ... <arg_n>]

以下に例を示します。

$ oc exec mypod date

出力例

Thu Apr  9 02:21:53 UTC 2015

重要

セキュリティー保護の理由 により、oc exec コマンドは、コマンドが cluster-admin ユーザーによって実行されている場合を除き、特権付きコンテナーにアクセスしようとしても機能しません。

7.7.2. クライアントからのリモートコマンドを開始するためのプロトコル

クライアントは要求を Kubernetes API サーバーに対して実行してコンテナーのリモートコマンドの実行を開始します。

/proxy/nodes/<node_name>/exec/<namespace>/<pod>/<container>?command=<command>

上記の URL には以下が含まれます。

  • <node_name> はノードの FQDN です。
  • <namespace> はターゲット Pod のプロジェクトです。
  • <pod> はターゲット Pod の名前です。
  • <container> はターゲットコンテナーの名前です。
  • <command> は実行される必要なコマンドです。

以下に例を示します。

/proxy/nodes/node123.openshift.com/exec/myns/mypod/mycontainer?command=date

さらに、クライアントはパラメーターを要求に追加して以下について指示します。

  • クライアントはリモートクライアントのコマンドに入力を送信する (標準入力: stdin)。
  • クライアントのターミナルは TTY である。
  • リモートコンテナーのコマンドは標準出力 (stdout) からクライアントに出力を送信する。
  • リモートコンテナーのコマンドは標準エラー出力 (stderr) からクライアントに出力を送信する。

exec 要求の API サーバーへの送信後、クライアントは多重化ストリームをサポートするものに接続をアップグレードします。現在の実装では HTTP/2 を使用しています。

クライアントは標準入力 (stdin)、標準出力 (stdout)、および標準エラー出力 (stderr) 用にそれぞれのストリームを作成します。ストリームを区別するために、クライアントはストリームの streamType ヘッダーを stdinstdout、または stderr のいずれかに設定します。

リモートコマンド実行要求の処理が終了すると、クライアントはすべてのストリームやアップグレードされた接続および基礎となる接続を閉じます。

7.8. コンテナー内のアプリケーションにアクセスするためのポート転送の使用

OpenShift Container Platform は、Pod へのポート転送をサポートします。

7.8.1. ポート転送について

CLI を使用して 1 つ以上のローカルポートを Pod に転送できます。これにより、指定されたポートまたはランダムのポートでローカルにリッスンでき、Pod の所定ポートへ/からデータを転送できます。

ポート転送のサポートは、CLI に組み込まれています。

$ oc port-forward <pod> [<local_port>:]<remote_port> [...[<local_port_n>:]<remote_port_n>]

CLI はユーザーによって指定されたそれぞれのローカルポートでリッスンし、以下で説明されているプロトコルで転送を実行します。

ポートは以下の形式を使用して指定できます。

5000

クライアントはポート 5000 でローカルにリッスンし、Pod の 5000 に転送します。

6000:5000

クライアントはポート 6000 でローカルにリッスンし、Pod の 5000 に転送します。

:5000 または 0:5000

クライアントは空きのローカルポートを選択し、Pod の 5000 に転送します。

OpenShift Container Platform は、クライアントからのポート転送要求を処理します。要求を受信すると、OpenShift Container Platform は応答をアップグレードし、クライアントがポート転送ストリームを作成するまで待機します。OpenShift Container Platform が新規ストリームを受信したら、ストリームと Pod のポート間でデータをコピーします。

アーキテクチャーの観点では、Pod のポートに転送するためのいくつかのオプションがあります。サポートされている OpenShift Container Platform 実装はノードホストで直接 nsenter を直接呼び出して、Pod ネットワークの namespace に入ってから、socat を呼び出してストリームと Pod のポート間でデータをコピーします。ただし、カスタムの実装には、nsenter および socat を実行する helper Pod の実行を含めることができ、その場合は、それらのバイナリーをホストにインストールする必要はありません。

7.8.2. ポート転送の使用

CLI を使用して、1 つ以上のローカルポートの Pod へのポート転送を実行できます。

手順

以下のコマンドを使用して、Pod 内の指定されたポートでリッスンします。

$ oc port-forward <pod> [<local_port>:]<remote_port> [...[<local_port_n>:]<remote_port_n>]

以下に例を示します。

  • 以下のコマンドを使用して、ポート 5000 および 6000 でローカルにリッスンし、Pod のポート 5000 および 6000 との間でデータを転送します。

    $ oc port-forward <pod> 5000 6000

    出力例

    Forwarding from 127.0.0.1:5000 -> 5000
    Forwarding from [::1]:5000 -> 5000
    Forwarding from 127.0.0.1:6000 -> 6000
    Forwarding from [::1]:6000 -> 6000

  • 以下のコマンドを使用して、ポート 8888 でローカルにリッスンし、Pod の 5000 に転送します。

    $ oc port-forward <pod> 8888:5000

    出力例

    Forwarding from 127.0.0.1:8888 -> 5000
    Forwarding from [::1]:8888 -> 5000

  • 以下のコマンドを使用して、空きポートでローカルにリッスンし、Pod の 5000 に転送します。

    $ oc port-forward <pod> :5000

    出力例

    Forwarding from 127.0.0.1:42390 -> 5000
    Forwarding from [::1]:42390 -> 5000

    または、以下を実行します。

    $ oc port-forward <pod> 0:5000

7.8.3. クライアントからのポート転送を開始するためのプロトコル

クライアントは Kubernetes API サーバーに対して要求を実行して Pod へのポート転送を実行します。

/proxy/nodes/<node_name>/portForward/<namespace>/<pod>

上記の URL には以下が含まれます。

  • <node_name> はノードの FQDN です。
  • <namespace> はターゲット Pod の namespace です。
  • <pod> はターゲット Pod の名前です。

以下に例を示します。

/proxy/nodes/node123.openshift.com/portForward/myns/mypod

ポート転送要求を API サーバーに送信した後に、クライアントは多重化ストリームをサポートするものに接続をアップグレードします。現在の実装では Hyptertext Transfer Protocol Version 2 (HTTP/2) を使用しています。

クライアントは Pod のターゲットポートを含む port ヘッダーでストリームを作成します。ストリームに書き込まれるすべてのデータは kubelet 経由でターゲット Pod およびポートに送信されます。同様に、転送された接続で Pod から送信されるすべてのデータはクライアントの同じストリームに送信されます。

クライアントは、ポート転送要求が終了するとすべてのストリーム、アップグレードされた接続および基礎となる接続を閉じます。

7.9. コンテナーでの sysctl の使用

Sysctl の設定は Kubernetes を通じて公開され、ユーザーは実行時に特定のカーネルパラメーターを変更することができます。namespace を使用する sysctl のみを Pod 上で独立して設定できます。sysctl に namespace がない場合 (ノードレベルと呼ばれる)、Node Tuning Operator をしようなどなど、sysctl を設定する別の方法を使用する必要があります。

ネットワーク sysctl は特殊な sysctl カテゴリーです。ネットワーク sysctl には、以下が含まれます。

  • すべてのネットワークで有効な、net.ipv4.ip_local_port_range ようなシステム全体の sysctl。これらは、ノード上の各 Pod に対して個別に設定できます。
  • 特定の Pod の特定の追加ネットワークインターフェイスにのみ適用されるインターフェイス固有の sysctl (net.ipv4.conf.IFNAME.accept_local など)。これらは、追加のネットワーク設定ごとに個別に設定できます。ネットワークインターフェイスの作成後に tuning-cni で設定を使用して、これらを設定します。

さらに 安全 とみなされる sysctl のみがデフォルトでホワイトリストに入れられます。 他の 安全でない sysctl はノードで手動で有効にし、ユーザーが使用できるようにできます。

関連情報

sysctl を設定していて、それがノードレベルでない場合は、Node Tuning Operator の使用 セクションで該当する手順に関する情報を確認できます。

7.9.1. sysctl について

Linux では、管理者は sysctl インターフェイスを使用してランタイム時にカーネルパラメーターを変更することができます。パラメーターは /proc/sys/ 仮想プロセスファイルシステムから利用できます。これらのパラメーターは以下を含む各種のサブシステムを対象とします。

  • カーネル (共通の接頭辞: kernel.)
  • ネットワーク (共通の接頭辞: net.)
  • 仮想メモリー (共通の接頭辞: vm.)
  • MDADM (共通の接頭辞: dev.)

追加のサブシステムについては、カーネルのドキュメント で説明されています。すべてのパラメーターの一覧を表示するには、以下のコマンドを実行します。

$ sudo sysctl -a

7.9.2. namespace とノードレベルの sysctls

Linux カーネルでは、数多くの sysctl に namespace が使用されています。これは、それらをノードの各 Pod に対して個別に設定できることを意味します。namespace の使用は、sysctl を Kubernetes 内の Pod 環境でアクセス可能にするための要件になります。

以下の sysctl は namespace を使用するものとして知られている sysctl です。

  • kernel.shm*
  • kernel.msg*
  • kernel.sem
  • fs.mqueue.*

また、net.* グループの大半の sysctl には namespace が使用されていることが知られています。それらの namespace の使用は、カーネルのバージョンおよびディストリビューターによって異なります。

namespace が使用されていない sysctl は ノードレベル と呼ばれており、クラスター管理者がノードの基礎となる Linux ディストリビューションを使用 (例: /etc/sysctls.conf ファイルを変更) するか、特権付きコンテナーでデーモンセットを使用することによって手動で設定する必要があります。Node Tuning Operator を使用して node-level を設定できます。

注記

特殊な sysctl が設定されたノードに taint のマークを付けることを検討してください。それらの sysctl 設定を必要とするノードにのみ Pod をスケジュールします。taint および toleration 機能を使用してノードにマークを付けます。

7.9.3. 安全および安全でない sysctl

sysctl は 安全な および 安全でない sysctl に分類されます。

システム全体の sysctl を安全に考慮するには、namespace を指定する必要があります。namespace を使用した sysctl は namespace と Pod 間で分離されるようにします。1 つの Pod に sysctl を設定する場合は、以下のいずれかを追加することはできません。

  • この設定はノードのその他の Pod に影響を与えないものである。
  • ノードの正常性に切り離す。
  • この設定は Pod のリソース制限を超える CPU またはメモリーリソースの取得を許可しないものである。
注記

namespace を使用するだけでは、sysctl を安全に考慮するには不十分です。

OpenShift Container Platform で許可リストに追加されていない sysctl は、OpenShift Container Platform では安全でないと見なされます。

安全でない sysctl はデフォルトでは許可されません。システム全体の sysctl の場合、クラスター管理者はノードごとに手動で有効にする必要があります。無効にされた安全でない sysctl が設定された Pod はスケジュールされますが、起動されません。

注記

インターフェイス固有の安全でない sysctls を手動で有効にすることはできません。

OpenShift Container Platform は以下のシステム全体およびインターフェイス固有の安全な sysctl を許可された安全なリストに追加します。

表7.4 システム全体の安全な sysctl
sysctl説明

kernel.shm_rmid_forced

1 に設定すると、現在の IPC namespace のすべての共有メモリーオブジェクトは自動的に IPC_RMID を使用します。詳細は、shm_rmid_forced を参照してください。

net.ipv4.ip_local_port_range

TCP および UDP によって使用されるローカルポート範囲を定義して、ローカルポートを選択します。最初の番号は最初のポート番号で、2 番目の番号は最後のローカルポート番号になります。可能であれば、これらの数値は異なるパリティー (偶数値と奇数値) を持つ方が良い。ip_unprivileged_port_start よりも大きくなければなりません。デフォルト値は、それぞれ 32768 および 60999 です。詳細は、ip_local_port_range を参照してください。

net.ipv4.tcp_syncookies

net.ipv4.tcp_syncookies を設定すると、カーネルは、通常、半分に開いた接続キューが満杯になるまで TCP SYN パケットを処理します。この時点で、SYN クッキー機能が開始します。この機能により、サービス拒否攻撃下であっても、システムは有効な接続を受け入れることができます。詳細は、tcp_syncookies を参照してください。

net.ipv4.ping_group_range

これにより、ICMP_PROTO データグラムソケットがグループ範囲内のユーザーに制限されます。デフォルトは 1 0 で、nobody は root であっても ping ソケットを作成できます。詳細は、ping_group_range を参照してください。

net.ipv4.ip_unprivileged_port_start

これは、ネットワーク namespace 内の最初の権限のないポートを定義します。特権ポートをすべて無効にするには、これを 0 に設定します。特権ポートは ip_local_port_range と重複できません。詳細は、ip_unprivileged_port_start を参照してください。

net.ipv4.ip_local_reserved_ports

アプリケーションまたはサービス用に予約するローカルポートの範囲をコンマ区切りで指定します。

表7.5 インターフェイス固有の安全な sysctl
sysctl説明

net.ipv4.conf.IFNAME.accept_redirects

IPv4 ICMP リダイレクトメッセージを受信します。

net.ipv4.conf.IFNAME.accept_source_route

SRR (Strict Source Route) オプションの付いた IPv4 パケットを受け入れる。

net.ipv4.conf.IFNAME.arp_accept

ARP テーブルにない IPv4 アドレスで余計な ARP フレームの動作を定義します。

  • 0: ARP テーブルに新しいエントリーを作成しません。
  • 1: ARP テーブルに新しいエントリーを作成します。

net.ipv4.conf.IFNAME.arp_notify

IPv4 アドレスとデバイスの変更を通知するモードを定義します。

net.ipv4.conf.IFNAME.disable_policy

この IPv4 インターフェイスの IPSEC ポリシー (SPD) を無効にします。

net.ipv4.conf.IFNAME.secure_redirects

インターフェイスの現在のゲートウェイリストにリストされているゲートウェイに対する ICMP リダイレクトメッセージのみを受信します。

net.ipv4.conf.IFNAME.send_redirects

送信リダイレクトは、ノードがルーターとして動作する場合にのみ有効になります。つまり、ホストは ICMP リダイレクトメッセージを送信しないでください。これは、特定の宛先で利用可能なルーティングパスの改善についてホストに通知するためにルーターによって使用されます。

net.ipv6.conf.IFNAME.accept_ra

IPv6 ルーター広告を受け入れ、それらを使用して自動設定します。また、ルーター要請の送信の可否を判断します。ルーターへの通知は、機能の設定がルーター広告を受け入れる場合にのみ送信されます。

net.ipv6.conf.IFNAME.accept_redirects

IPv6 ICMP リダイレクトメッセージを受信します。

net.ipv6.conf.IFNAME.accept_source_route

SRR オプションで IPv6 パケットを受信します。

net.ipv6.conf.IFNAME.arp_accept

ARP テーブルに存在しない IPv6 アドレスで余計な ARP フレームの動作を定義します。

  • 0: ARP テーブルに新しいエントリーを作成しません。
  • 1: ARP テーブルに新しいエントリーを作成します。

net.ipv6.conf.IFNAME.arp_notify

IPv6 アドレスとデバイスの変更を通知するモードを定義します。

net.ipv6.neigh.IFNAME.base_reachable_time_ms

このパラメーターは、IPv6 の neighbour テーブルで、IP マッピングの有効期間に対するハードウェアアドレスを制御します。

net.ipv6.neigh.IFNAME.retrans_time_ms

隣接する検出メッセージの再送信タイマーを設定します。

注記

tuning CNI プラグインを使用してこれらの値を設定する場合は、値 IFNAME をそのまま使用します。インターフェイス名は IFNAME トークンによって表され、ランタイム時にインターフェイスの実際の名前に置き換えられます。

7.9.4. インターフェイス固有の安全な sysctls リストの更新

OpenShift Container Platform には、安全なインターフェイス固有の sysctl の定義済みリストが含まれています。このリストを変更するには、openshift-multus namespace で cni-sysctl-allowlist を更新します。

重要

インターフェイス固有の安全な sysctl リストの更新のサポートは、テクノロジープレビュー機能のみです。テクノロジープレビュー機能は、Red Hat 製品のサービスレベルアグリーメント (SLA) の対象外であり、機能的に完全ではないことがあります。Red Hat は、実稼働環境でこれらを使用することを推奨していません。テクノロジープレビューの機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。

Red Hat のテクノロジープレビュー機能のサポート範囲に関する詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。

この手順に従って、安全な sysctl の定義済みリストを変更します。この手順では、デフォルトの許可リストを拡張する方法を説明します。

手順

  1. 次のコマンドを実行して、既存の定義済みリストを表示します。

    $ oc get cm -n openshift-multus cni-sysctl-allowlist -oyaml

    予想される出力

    apiVersion: v1
    data:
      allowlist.conf: |-
        ^net.ipv4.conf.IFNAME.accept_redirects$
        ^net.ipv4.conf.IFNAME.accept_source_route$
        ^net.ipv4.conf.IFNAME.arp_accept$
        ^net.ipv4.conf.IFNAME.arp_notify$
        ^net.ipv4.conf.IFNAME.disable_policy$
        ^net.ipv4.conf.IFNAME.secure_redirects$
        ^net.ipv4.conf.IFNAME.send_redirects$
        ^net.ipv6.conf.IFNAME.accept_ra$
        ^net.ipv6.conf.IFNAME.accept_redirects$
        ^net.ipv6.conf.IFNAME.accept_source_route$
        ^net.ipv6.conf.IFNAME.arp_accept$
        ^net.ipv6.conf.IFNAME.arp_notify$
        ^net.ipv6.neigh.IFNAME.base_reachable_time_ms$
        ^net.ipv6.neigh.IFNAME.retrans_time_ms$
    kind: ConfigMap
    metadata:
      annotations:
        kubernetes.io/description: |
          Sysctl allowlist for nodes.
        release.openshift.io/version: 4.14.0-0.nightly-2022-11-16-003434
      creationTimestamp: "2022-11-17T14:09:27Z"
      name: cni-sysctl-allowlist
      namespace: openshift-multus
      resourceVersion: "2422"
      uid: 96d138a3-160e-4943-90ff-6108fa7c50c3

  2. 次のコマンドを使用してリストを編集します。

    $ oc edit cm -n openshift-multus cni-sysctl-allowlist -oyaml

    たとえば、より厳密なリバースパス転送を実装できるようにするには、次のように ^net.ipv4.conf.IFNAME.rp_filter$^net.ipv6.conf.IFNAME.rp_filter$ をリストに追加する必要があります。

    # Please edit the object below. Lines beginning with a '#' will be ignored,
    # and an empty file will abort the edit. If an error occurs while saving this file will be
    # reopened with the relevant failures.
    #
    apiVersion: v1
    data:
      allowlist.conf: |-
        ^net.ipv4.conf.IFNAME.accept_redirects$
        ^net.ipv4.conf.IFNAME.accept_source_route$
        ^net.ipv4.conf.IFNAME.arp_accept$
        ^net.ipv4.conf.IFNAME.arp_notify$
        ^net.ipv4.conf.IFNAME.disable_policy$
        ^net.ipv4.conf.IFNAME.secure_redirects$
        ^net.ipv4.conf.IFNAME.send_redirects$
        ^net.ipv4.conf.IFNAME.rp_filter$
        ^net.ipv6.conf.IFNAME.accept_ra$
        ^net.ipv6.conf.IFNAME.accept_redirects$
        ^net.ipv6.conf.IFNAME.accept_source_route$
        ^net.ipv6.conf.IFNAME.arp_accept$
        ^net.ipv6.conf.IFNAME.arp_notify$
        ^net.ipv6.neigh.IFNAME.base_reachable_time_ms$
        ^net.ipv6.neigh.IFNAME.retrans_time_ms$
        ^net.ipv6.conf.IFNAME.rp_filter$
  3. 変更をファイルに保存して終了します。

    注記

    sysctl の削除もサポートされています。ファイルを編集し、sysctl または sysctls を削除してから、変更を保存して終了します。

検証

IPv4 のより厳密なリバースパス転送を強制するには、次の手順に従います。リバースパスフォワーディングの詳細は、リバースパスフォワーディング を参照してください。

  1. 次の内容で、reverse-path-fwd-example.yaml などのネットワーク接続定義を作成します。

    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: tuningnad
      namespace: default
    spec:
      config: '{
        "cniVersion": "0.4.0",
        "name": "tuningnad",
        "plugins": [{
          "type": "bridge"
          },
          {
          "type": "tuning",
          "sysctl": {
             "net.ipv4.conf.IFNAME.rp_filter": "1"
            }
        }
      ]
    }'
  2. 以下のコマンドを実行して yaml を適用します。

    $ oc apply -f reverse-path-fwd-example.yaml

    出力例

    networkattachmentdefinition.k8.cni.cncf.io/tuningnad created

  3. 次の YAML を使用して、examplepod.yaml などの Pod を作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: example
      labels:
        app: httpd
      namespace: default
      annotations:
        k8s.v1.cni.cncf.io/networks: tuningnad  1
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: httpd
          image: 'image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest'
          ports:
            - containerPort: 8080
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
    1
    設定済みの NetworkAttachmentDefinition の名前を指定します。
  4. 以下のコマンドを実行して yaml を適用します。

    $ oc apply -f examplepod.yaml
  5. 次のコマンドを実行して、Pod が作成されていることを確認します。

    $ oc get pod

    出力例

    NAME      READY   STATUS    RESTARTS   AGE
    example   1/1     Running   0          47s

  6. 次のコマンドを実行して、Pod にログインします。

    $ oc rsh example
  7. 設定された sysctl フラグの値を確認します。たとえば、次のコマンドを実行して値 net.ipv4.conf.net1.rp_filter を見つけます。

    sh-4.4# sysctl net.ipv4.conf.net1.rp_filter

    予想される出力

    net.ipv4.conf.net1.rp_filter = 1

7.9.5. 安全な sysctl での Pod の起動

Pod の securityContext を使用して sysctl を Pod に設定できます。securityContext は同じ Pod 内のすべてのコンテナーに適用されます。

安全な sysctl はデフォルトで許可されます。

この例では、Pod securityContext を使用して以下の安全な sysctl を設定します。

  • kernel.shm_rmid_forced
  • net.ipv4.ip_local_port_range
  • net.ipv4.tcp_syncookies
  • net.ipv4.ping_group_range
警告

オペレーティングシステムが不安定になるのを防ぐには、変更の影響を確認している場合にのみ sysctl パラメーターを変更します。

以下の手順を使用して、設定される sysctl 設定で Pod を起動します。

注記

ほとんどの場合、既存の Pod 定義を変更し、securityContext 仕様を追加します。

手順

  1. 以下の例のように、サンプル Pod を定義し、securityContext 仕様を追加する YAML ファイルの sysctl_pod.yaml を作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: sysctl-example
      namespace: default
    spec:
      containers:
      - name: podexample
        image: centos
        command: ["bin/bash", "-c", "sleep INF"]
        securityContext:
          runAsUser: 2000 1
          runAsGroup: 3000 2
          allowPrivilegeEscalation: false 3
          capabilities: 4
            drop: ["ALL"]
      securityContext:
        runAsNonRoot: true 5
        seccompProfile: 6
          type: RuntimeDefault
        sysctls:
        - name: kernel.shm_rmid_forced
          value: "1"
        - name: net.ipv4.ip_local_port_range
          value: "32770       60666"
        - name: net.ipv4.tcp_syncookies
          value: "0"
        - name: net.ipv4.ping_group_range
          value: "0           200000000"
    1
    runAsUser は、コンテナーが実行されるユーザー ID を制御します。
    2
    runAsGroup は、コンテナーが実行されるプライマリーグループ ID を制御します。
    3
    allowPrivilegeEscalation は、Pod が特権の昇格を許可するように要求できるかどうかを決定します。指定しない場合、デフォルトで true に設定されます。このブール値は、no_new_privs フラグがコンテナープロセスに設定されるかどうかを直接制御します。
    4
    capabilities は、完全なルートアクセスを許可せずに権限操作を許可します。このポリシーにより、すべての機能が Pod から削除されます。
    5
    runAsNonRoot: true は、コンテナーが 0 以外の任意の UID を持つユーザーで実行されることを要求します。
    6
    RuntimeDefault は、Pod またはコンテナーワークロードのデフォルトの seccomp プロファイルを有効にします。
  2. 以下のコマンドを実行して Pod を作成します。

    $ oc apply -f sysctl_pod.yaml
  3. 次のコマンドを実行して、Pod が作成されていることを確認します。

    $ oc get pod

    出力例

    NAME              READY   STATUS            RESTARTS   AGE
    sysctl-example    1/1     Running           0          14s

  4. 次のコマンドを実行して、Pod にログインします。

    $ oc rsh sysctl-example
  5. 設定された sysctl フラグの値を確認します。たとえば、以下のコマンドを実行して kernel.shm_rmid_forced の値を見つけます。

    sh-4.4# sysctl kernel.shm_rmid_forced

    予想される出力

    kernel.shm_rmid_forced = 1

7.9.6. 安全でない sysctl での Pod の起動

安全でない sysctl が設定された Pod は、クラスター管理者がそのノードの安全でない sysctl を明示的に有効にしない限り、いずれのノードでも起動に失敗します。ノードレベルの sysctl の場合のように、それらの Pod を正しいノードにスケジュールするには、taint および toleration、またはノードのラベルを使用します。

以下の例では Pod の securityContext を使用して安全な sysctl kernel.shm_rmid_forced および 2 つの安全でない sysctl net.core.somaxconn および kernel.msgmax を設定します。仕様では 安全な sysctl と 安全でない sysctl は区別されません。

警告

オペレーティングシステムが不安定になるのを防ぐには、変更の影響を確認している場合にのみ sysctl パラメーターを変更します。

以下の例は、安全な sysctl を Pod 仕様に追加する際に発生する内容を示しています。

手順

  1. 以下の例のように、サンプル Pod を定義し、securityContext 仕様を追加する YAML ファイル sysctl-example-unsafe.yaml を作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: sysctl-example-unsafe
    spec:
      containers:
      - name: podexample
        image: centos
        command: ["bin/bash", "-c", "sleep INF"]
        securityContext:
          runAsUser: 2000
          runAsGroup: 3000
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
        sysctls:
        - name: kernel.shm_rmid_forced
          value: "0"
        - name: net.core.somaxconn
          value: "1024"
        - name: kernel.msgmax
          value: "65536"
  2. 以下のコマンドを使用して Pod を作成します。

    $ oc apply -f sysctl-example-unsafe.yaml
  3. 以下のコマンドを使用して安全でない sysctl がノードに許可されないため、Pod がスケジュールされているがデプロイされないことを確認します。

    $ oc get pod

    出力例

    NAME                       READY             STATUS            RESTARTS   AGE
    sysctl-example-unsafe      0/1               SysctlForbidden   0          14s

7.9.7. 安全でない sysctl の有効化

クラスター管理者は、高パフォーマンスまたはリアルタイムのアプリケーション調整などの非常に特殊な状況で特定の安全でない sysctl を許可することができます。

安全でない sysctl を使用する必要がある場合、クラスター管理者は特定のタイプのノードに対してそれらを個別に有効にする必要があります。sysctl には namespace を使用する必要があります。

Security Context Constraints の allowedUnsafeSysctls フィールドに sysctl または sysctl パターンのリストを指定することで、どの sysctl を Pod に設定するかをさらに制御できます。

  • allowedUnsafeSysctls オプションは、高パフォーマンスやリアルタイムのアプリケーションチューニングなどの特定ニーズを管理します。
警告

安全でないという性質上、安全でない sysctl は各自の責任で使用されます。 場合によっては、コンテナーの正しくない動作やリソース不足、またはノードの破損などの深刻な問題が生じる可能性があります。

手順

  1. 以下のコマンドを実行して、OpenShift Container Platform クラスターの既存の MachineConfig オブジェクトをリスト表示し、マシン設定にラベルを付ける方法を決定します。

    $ oc get machineconfigpool

    出力例

    NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
    master   rendered-master-bfb92f0cd1684e54d8e234ab7423cc96   True      False      False      3              3                   3                     0                      42m
    worker   rendered-worker-21b6cb9a0f8919c88caf39db80ac1fce   True      False      False      3              3                   3                     0                      42m

  2. 以下のコマンドを実行して、安全でない sysctl が設定されたコンテナーが実行されるマシン設定プールにラベルを追加します。

    $ oc label machineconfigpool worker custom-kubelet=sysctl
  3. KubeletConfig カスタムリソース (CR) を定義する YAML ファイル set-sysctl-worker.yaml を作成します。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: custom-kubelet
    spec:
      machineConfigPoolSelector:
        matchLabels:
          custom-kubelet: sysctl 1
      kubeletConfig:
        allowedUnsafeSysctls: 2
          - "kernel.msg*"
          - "net.core.somaxconn"
    1
    マシン設定プールからラベルを指定します。
    2
    許可する必要のある安全でない sysctl を一覧表示します。
  4. 以下のコマンドを実行してオブジェクトを作成します。

    $ oc apply -f set-sysctl-worker.yaml
  5. 以下のコマンドを実行して、Machine Config Operator が新規のレンダリングされた設定を生成し、これをマシンに適用します。

    $ oc get machineconfigpool worker -w

    数分後、UPDATING のステータスが True から False に変化します。

    NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
    worker   rendered-worker-f1704a00fc6f30d3a7de9a15fd68a800   False     True       False      3              2                   2                     0                      71m
    worker   rendered-worker-f1704a00fc6f30d3a7de9a15fd68a800   False     True       False      3              2                   3                     0                      72m
    worker   rendered-worker-0188658afe1f3a183ec8c4f14186f4d5   True      False      False      3              3                   3                     0                      72m
  6. 次の例に示すように、サンプルの Pod を定義する YAML ファイル sysctl-example-safe-unsafe.yaml を作成し、securityContext の仕様を追加します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: sysctl-example-safe-unsafe
    spec:
      containers:
      - name: podexample
        image: centos
        command: ["bin/bash", "-c", "sleep INF"]
        securityContext:
          runAsUser: 2000
          runAsGroup: 3000
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
        sysctls:
        - name: kernel.shm_rmid_forced
          value: "0"
        - name: net.core.somaxconn
          value: "1024"
        - name: kernel.msgmax
          value: "65536"
  7. 以下のコマンドを実行して Pod を作成します。

    $ oc apply -f sysctl-example-safe-unsafe.yaml

    予想される出力

    Warning: would violate PodSecurity "restricted:latest": forbidden sysctls (net.core.somaxconn, kernel.msgmax)
    pod/sysctl-example-safe-unsafe created

  8. 次のコマンドを実行して、Pod が作成されていることを確認します。

    $ oc get pod

    出力例

    NAME                         READY   STATUS    RESTARTS   AGE
    sysctl-example-safe-unsafe   1/1     Running   0          19s

  9. 次のコマンドを実行して、Pod にログインします。

    $ oc rsh sysctl-example-safe-unsafe
  10. 設定された sysctl フラグの値を確認します。たとえば、以下のコマンドを実行して net.core.somaxconn の値を見つけます。

    sh-4.4# sysctl net.core.somaxconn

    予想される出力

    net.core.somaxconn = 1024

安全でない sysctl が許可され、値は更新された Pod 仕様の securityContext 仕様で定義されているように設定されるようになりました。

7.9.8. 関連情報

第8章 クラスターの操作

8.1. OpenShift Container Platform クラスター内のシステムイベント情報の表示

OpenShift Container Platform のイベントは OpenShift Container Platform クラスターの API オブジェクトに対して発生するイベントに基づいてモデル化されます。

8.1.1. イベントについて

イベントにより、OpenShift Container Platform はリソースに依存しない方法で実際のイベントに関する情報を記録できます。また、開発者および管理者が統一された方法でシステムコンポーネントに関する情報を使用できるようにします。

8.1.2. CLI を使用したイベントの表示

CLI を使用し、特定のプロジェクト内のイベントのリストを取得できます。

手順

  • プロジェクト内のイベントを表示するには、以下のコマンドを使用します。

    $ oc get events [-n <project>] 1
    1
    プロジェクトの名前。

    以下に例を示します。

    $ oc get events -n openshift-config

    出力例

    LAST SEEN   TYPE      REASON                   OBJECT                      MESSAGE
    97m         Normal    Scheduled                pod/dapi-env-test-pod       Successfully assigned openshift-config/dapi-env-test-pod to ip-10-0-171-202.ec2.internal
    97m         Normal    Pulling                  pod/dapi-env-test-pod       pulling image "gcr.io/google_containers/busybox"
    97m         Normal    Pulled                   pod/dapi-env-test-pod       Successfully pulled image "gcr.io/google_containers/busybox"
    97m         Normal    Created                  pod/dapi-env-test-pod       Created container
    9m5s        Warning   FailedCreatePodSandBox   pod/dapi-volume-test-pod    Failed create pod sandbox: rpc error: code = Unknown desc = failed to create pod network sandbox k8s_dapi-volume-test-pod_openshift-config_6bc60c1f-452e-11e9-9140-0eec59c23068_0(748c7a40db3d08c07fb4f9eba774bd5effe5f0d5090a242432a73eee66ba9e22): Multus: Err adding pod to network "openshift-sdn": cannot set "openshift-sdn" ifname to "eth0": no netns: failed to Statfs "/proc/33366/ns/net": no such file or directory
    8m31s       Normal    Scheduled                pod/dapi-volume-test-pod    Successfully assigned openshift-config/dapi-volume-test-pod to ip-10-0-171-202.ec2.internal

  • OpenShift Container Platform コンソールからプロジェクト内のイベントを表示するには、以下を実行します。

    1. OpenShift Container Platform コンソールを起動します。
    2. HomeEvents をクリックし、プロジェクトを選択します。
    3. イベントを表示するリソースに移動します。たとえば、HomeProjects → <project-name> → <resource-name> の順に移動します。

      Pod やデプロイメントなどの多くのオブジェクトには、独自の イベント タブもあります。それらのタブには、オブジェクトに関連するイベントが表示されます。

8.1.3. イベントのリスト

このセクションでは、OpenShift Container Platform のイベントを説明します。

表8.1 設定イベント
名前説明

FailedValidation

Pod 設定の検証に失敗しました。

表8.2 コンテナーイベント
名前説明

BackOff

バックオフ (再起動) によりコンテナーが失敗しました。

Created

コンテナーが作成されました。

Failed

プル/作成/起動が失敗しました。

Killing

コンテナーを強制終了しています。

Started

コンテナーが起動しました。

Preempting

他の Pod のプリエンプションを実行します。

ExceededGracePeriod

コンテナーランタイムは、指定の猶予期間以内に Pod を停止しませんでした。

表8.3 正常性に関するイベント
名前説明

Unhealthy

コンテナーが正常ではありません。

表8.4 イメージイベント
名前説明

BackOff

バックオフ (コンテナー起動、イメージのプル)。

ErrImageNeverPull

イメージの NeverPull Policy の違反があります。

Failed

イメージのプルに失敗しました。

InspectFailed

イメージの検査に失敗しました。

Pulled

イメージのプルに成功し、コンテナーイメージがマシンにすでに置かれています。

Pulling

イメージをプルしています。

表8.5 イメージマネージャーイベント
名前説明

FreeDiskSpaceFailed

空きディスク容量に関連する障害が発生しました。

InvalidDiskCapacity

無効なディスク容量です。

表8.6 ノードイベント
名前説明

FailedMount

ボリュームのマウントに失敗しました。

HostNetworkNotSupported

ホストのネットワークがサポートされていません。

HostPortConflict

ホスト/ポートの競合

KubeletSetupFailed

Kubelet のセットアップに失敗しました。

NilShaper

シェイパーが定義されていません。

NodeNotReady

ノードの準備ができていません。

NodeNotSchedulable

ノードがスケジュール可能ではありません。

NodeReady

ノードの準備ができています。

NodeSchedulable

ノードがスケジュール可能です。

NodeSelectorMismatching

ノードセレクターの不一致があります。

OutOfDisk

ディスクの空き容量が不足しています。

Rebooted

ノードが再起動しました。

Starting

kubelet を起動しています。

FailedAttachVolume

ボリュームの割り当てに失敗しました。

FailedDetachVolume

ボリュームの割り当て解除に失敗しました。

VolumeResizeFailed

ボリュームの拡張/縮小に失敗しました。

VolumeResizeSuccessful

正常にボリュームを拡張/縮小しました。

FileSystemResizeFailed

ファイルシステムの拡張/縮小に失敗しました。

FileSystemResizeSuccessful

正常にファイルシステムが拡張/縮小されました。

FailedUnMount

ボリュームのマウント解除に失敗しました。

FailedMapVolume

ボリュームのマッピングに失敗しました。

FailedUnmapDevice

デバイスのマッピング解除に失敗しました。

AlreadyMountedVolume

ボリュームがすでにマウントされています。

SuccessfulDetachVolume

ボリュームの割り当てが正常に解除されました。

SuccessfulMountVolume

ボリュームが正常にマウントされました。

SuccessfulUnMountVolume

ボリュームのマウントが正常に解除されました。

ContainerGCFailed

コンテナーのガベージコレクションに失敗しました。

ImageGCFailed

イメージのガベージコレクションに失敗しました。

FailedNodeAllocatableEnforcement

システム予約の Cgroup 制限の実施に失敗しました。

NodeAllocatableEnforced

システム予約の Cgroup 制限を有効にしました。

UnsupportedMountOption

マウントオプションが非対応です。

SandboxChanged

Pod のサンドボックスが変更されました。

FailedCreatePodSandBox

Pod のサンドボックスの作成に失敗しました。

FailedPodSandBoxStatus

Pod サンドボックスの状態取得に失敗しました。

表8.7 Pod ワーカーイベント
名前説明

FailedSync

Pod の同期が失敗しました。

表8.8 システムイベント
名前説明

SystemOOM

クラスターに OOM (out of memory) 状態が発生しました。

表8.9 Pod に関するイベント
名前説明

FailedKillPod

Pod の停止に失敗しました。

FailedCreatePodContainer

Pod コンテナーの作成に失敗しました。

Failed

Pod データディレクトリーの作成に失敗しました。

NetworkNotReady

ネットワークの準備ができていません。

FailedCreate

作成エラー: <error-msg>

SuccessfulCreate

作成された Pod: <pod-name>

FailedDelete

削除エラー: <error-msg>

SuccessfulDelete

削除した Pod: <pod-id>

表8.10 Horizontal Pod AutoScaler に関するイベント
名前説明

SelectorRequired

セレクターが必要です。

InvalidSelector

セレクターを適切な内部セレクターオブジェクトに変換できませんでした。

FailedGetObjectMetric

HPA はレプリカ数を計算できませんでした。

InvalidMetricSourceType

不明なメトリクスソースタイプです。

ValidMetricFound

HPA は正常にレプリカ数を計算できました。

FailedConvertHPA

指定の HPA への変換に失敗しました。

FailedGetScale

HPA コントローラーは、ターゲットの現在のスケーリングを取得できませんでした。

SucceededGetScale

HPA コントローラーは、ターゲットの現在のスケールを取得できました。

FailedComputeMetricsReplicas

表示されているメトリクスに基づく必要なレプリカ数の計算に失敗しました。

FailedRescale

新しいサイズ: <size>; 理由: <msg>; エラー: <error-msg>

SuccessfulRescale

新しいサイズ: <size>; 理由: <msg>.

FailedUpdateStatus

状況の更新に失敗しました。

表8.11 ネットワークイベント (openshift-sdn)
名前説明

Starting

OpenShift SDN を開始します。

NetworkFailed

Pod のネットワークインターフェイスがなくなり、Pod が停止します。

表8.12 ネットワークイベント (kube-proxy)
名前説明

NeedPods

サービスポート <serviceName>:<port> は Pod が必要です。

表8.13 ボリュームイベント
名前説明

FailedBinding

利用可能な永続ボリュームがなく、ストレージクラスが設定されていません。

VolumeMismatch

ボリュームサイズまたはクラスが要求の内容と異なります。

VolumeFailedRecycle

再利用 Pod の作成エラー

VolumeRecycled

ボリュームの再利用時に発生します。

RecyclerPod

Pod の再利用時に発生します。

VolumeDelete

ボリュームの削除時に発生します。

VolumeFailedDelete

ボリュームの削除時のエラー。

ExternalProvisioning

要求のボリュームが手動または外部ソフトウェアでプロビジョニングされる場合に発生します。

ProvisioningFailed

ボリュームのプロビジョニングに失敗しました。

ProvisioningCleanupFailed

プロビジョニングしたボリュームの消去エラー

ProvisioningSucceeded

ボリュームが正常にプロビジョニングされる場合に発生します。

WaitForFirstConsumer

Pod のスケジューリングまでバインドが遅延します。

表8.14 ライフサイクルフック
名前説明

FailedPostStartHook

ハンドラーが Pod の起動に失敗しました。

FailedPreStopHook

ハンドラーが pre-stop に失敗しました。

UnfinishedPreStopHook

Pre-stop フックが完了しませんでした。

表8.15 デプロイメント
名前説明

DeploymentCancellationFailed

デプロイメントのキャンセルに失敗しました。

DeploymentCancelled

デプロイメントがキャンセルされました。

DeploymentCreated

新規レプリケーションコントローラーが作成されました。

IngressIPRangeFull

サービスに割り当てる Ingress IP がありません。

表8.16 スケジューラーイベント
名前説明

FailedScheduling

Pod のスケジューリングに失敗: <pod-namespace>/<pod-name>。このイベントは AssumePodVolumes の失敗、バインドの拒否など、複数の理由で発生します。

Preempted

ノード <node-name> にある <preemptor-namespace>/<preemptor-name>

Scheduled

<node-name>. に <pod-name> が正常に割り当てられました。

表8.17 デーモンセットイベント
名前説明

SelectingAll

このデーモンセットは全 Pod を選択しています。空でないセレクターが必要です。

FailedPlacement

<node-name> への Pod の配置に失敗しました。

FailedDaemonPod

ノード <node-name> で問題のあるデーモン Pod <pod-name> が見つかりました。この Pod の終了を試行します。

表8.18 LoadBalancer サービスイベント
名前説明

CreatingLoadBalancerFailed

ロードバランサーの作成エラー

DeletingLoadBalancer

ロードバランサーを削除します。

EnsuringLoadBalancer

ロードバランサーを確保します。

EnsuredLoadBalancer

ロードバランサーを確保しました。

UnAvailableLoadBalancer

LoadBalancer サービスに利用可能なノードがありません。

LoadBalancerSourceRanges

新規の LoadBalancerSourceRanges を表示します。例: <old-source-range> → <new-source-range>

LoadbalancerIP

新しい IP アドレスを表示します。例: <old-ip> → <new-ip>

ExternalIP

外部 IP アドレスを表示します。例: Added: <external-ip>

UID

新しい UID を表示します。例: <old-service-uid> → <new-service-uid>

ExternalTrafficPolicy

新しい ExternalTrafficPolicy を表示します。例: <old-policy> → <new-policy>

HealthCheckNodePort

新しい HealthCheckNodePort を表示します。例: <old-node-port> → new-node-port>

UpdatedLoadBalancer

新規ホストでロードバランサーを更新しました。

LoadBalancerUpdateFailed

新規ホストでのロードバランサーの更新に失敗しました。

DeletingLoadBalancer

ロードバランサーを削除します。

DeletingLoadBalancerFailed

ロードバランサーの削除エラー。

DeletedLoadBalancer

ロードバランサーを削除しました。

8.2. OpenShift Container Platform のノードが保持できる Pod の数の見積り

クラスター管理者は、OpenShift Cluster Capacity Tool を使用して、現在のリソースが使い切られる前にそれらを増やすべくスケジュール可能な Pod 数を表示し、スケジュール可能な Pod 数を表示したり、Pod を今後スケジュールできるようにすることができます。この容量は、クラスター内の個別ノードからのものを集めたものであり、これには CPU、メモリー、ディスク領域などが含まれます。

8.2.1. OpenShift Cluster Capacity Tool について

OpenShift Cluster Capacity Tool は、より正確な見積もりを出すべく、スケジュールの一連の意思決定をシミュレーションし、リソースが使い切られる前にクラスターでスケジュールできる入力 Pod のインスタンス数を判別します。

注記

ノード間に分散しているすべてのリソースがカウントされないため、残りの割り当て可能な容量は概算となります。残りのリソースのみが分析対象となり、クラスターでのスケジュール可能な所定要件を持つ Pod のインスタンス数という点から消費可能な容量を見積もります。

Pod のスケジューリングはその選択およびアフィニティー条件に基づいて特定のノードセットだけがサポートされる可能性があります。そのため、クラスターでスケジュール可能な残りの Pod 数を見積もることが困難になる場合があります。

OpenShift Cluster Capacity Tool は、コマンドラインからスタンドアロンのユーティリティーとして実行することも、OpenShift Container Platform クラスター内の Pod でジョブとして実行することもできます。これを Pod 内のジョブとしてツールを実行すると、介入なしに複数回実行することができます。

8.2.2. コマンドラインでの OpenShift Cluster Capacity Tool の実行

コマンドラインから OpenShift Cluster Capacity Tool を実行して、クラスターにスケジュール設定可能な Pod 数を見積ることができます。

ツールがリソース使用状況を見積もるために使用するサンプル Pod 仕様ファイルを作成します。pod spec はそのリソース要件を limits または requests として指定します。クラスター容量ツールは、Pod のリソース要件をその見積もりの分析に反映します。

前提条件

  1. OpenShift Cluster Capacity Tool を実行します。これは、Red Hat エコシステムカタログからコンテナーイメージとして入手できます。
  2. サンプルの Pod 仕様ファイルを作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: small-pod
        labels:
          app: guestbook
          tier: frontend
      spec:
        containers:
        - name: php-redis
          image: gcr.io/google-samples/gb-frontend:v4
          imagePullPolicy: Always
          resources:
            limits:
              cpu: 150m
              memory: 100Mi
            requests:
              cpu: 150m
              memory: 100Mi
    2. クラスターロールを作成します。

      $ oc create -f <file_name>.yaml

      以下に例を示します。

      $ oc create -f pod-spec.yaml

手順

コマンドラインでクラスター容量ツールを使用するには、次のようにします。

  1. ターミナルから、Red Hat レジストリーにログインします。

    $ podman login registry.redhat.io
  2. クラスター容量ツールのイメージをプルします。

    $ podman pull registry.redhat.io/openshift4/ose-cluster-capacity
  3. クラスター容量ツールを実行します。

    $ podman run -v $HOME/.kube:/kube:Z -v $(pwd):/cc:Z  ose-cluster-capacity \
    /bin/cluster-capacity --kubeconfig /kube/config --<pod_spec>.yaml /cc/<pod_spec>.yaml \
    --verbose

    ここでは、以下のようになります。

    <pod_spec>.yaml
    使用する Pod の仕様を指定します。
    verbose
    クラスター内の各ノードでスケジュールできる Pod の数の詳細な説明を出力します。

    出力例

    small-pod pod requirements:
    	- CPU: 150m
    	- Memory: 100Mi
    
    The cluster can schedule 88 instance(s) of the pod small-pod.
    
    Termination reason: Unschedulable: 0/5 nodes are available: 2 Insufficient cpu,
    3 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't
    tolerate.
    
    Pod distribution among nodes:
    small-pod
    	- 192.168.124.214: 45 instance(s)
    	- 192.168.124.120: 43 instance(s)

    上記の例では、クラスターにスケジュールできる推定 Pod の数は 88 です。

8.2.3. OpenShift Cluster Capacity Tool を Pod 内のジョブとして実行する

OpenShift Cluster Capacity Tool を Pod 内のジョブとして実行すると、ユーザーの介入を必要とせずにツールを複数回実行できます。OpenShift Cluster Capacity Tool は、ConfigMap オブジェクトを使用してジョブとして実行します。

前提条件

OpenShift Cluster Capacity Tool をダウンロードしてインストールします。

手順

クラスター容量ツールを実行するには、以下の手順を実行します。

  1. クラスターロールを作成します。

    1. 以下のような YAML ファイルを作成します。

      kind: ClusterRole
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: cluster-capacity-role
      rules:
      - apiGroups: [""]
        resources: ["pods", "nodes", "persistentvolumeclaims", "persistentvolumes", "services", "replicationcontrollers"]
        verbs: ["get", "watch", "list"]
      - apiGroups: ["apps"]
        resources: ["replicasets", "statefulsets"]
        verbs: ["get", "watch", "list"]
      - apiGroups: ["policy"]
        resources: ["poddisruptionbudgets"]
        verbs: ["get", "watch", "list"]
      - apiGroups: ["storage.k8s.io"]
        resources: ["storageclasses"]
        verbs: ["get", "watch", "list"]
    2. 次のコマンドを実行して、クラスターのロールを作成します。

      $ oc create -f <file_name>.yaml

      以下に例を示します。

      $ oc create sa cluster-capacity-sa
  2. サービスアカウントを作成します。

    $ oc create sa cluster-capacity-sa -n default
  3. ロールをサービスアカウントに追加します。

    $ oc adm policy add-cluster-role-to-user cluster-capacity-role \
        system:serviceaccount:<namespace>:cluster-capacity-sa

    ここでは、以下のようになります。

    <namespace>
    Pod が配置されている名前空間を指定します。
  4. Pod 仕様を定義して、作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: small-pod
        labels:
          app: guestbook
          tier: frontend
      spec:
        containers:
        - name: php-redis
          image: gcr.io/google-samples/gb-frontend:v4
          imagePullPolicy: Always
          resources:
            limits:
              cpu: 150m
              memory: 100Mi
            requests:
              cpu: 150m
              memory: 100Mi
    2. 以下のコマンドを実行して Pod を作成します。

      $ oc create -f <file_name>.yaml

      以下に例を示します。

      $ oc create -f pod.yaml
  5. 以下のコマンドを実行して config map オブジェクトを作成します。

    $ oc create configmap cluster-capacity-configmap \
        --from-file=pod.yaml=pod.yaml

    クラスター容量分析は、cluster-capacity-configmap という名前の config map オブジェクトを使用してボリュームにマウントされ、入力 Pod 仕様ファイル pod.yaml はパス /test-pod のボリューム test-volume にマウントされます。

  6. ジョブ仕様ファイルの以下のサンプルを使用して、ジョブを作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: batch/v1
      kind: Job
      metadata:
        name: cluster-capacity-job
      spec:
        parallelism: 1
        completions: 1
        template:
          metadata:
            name: cluster-capacity-pod
          spec:
              containers:
              - name: cluster-capacity
                image: openshift/origin-cluster-capacity
                imagePullPolicy: "Always"
                volumeMounts:
                - mountPath: /test-pod
                  name: test-volume
                env:
                - name: CC_INCLUSTER 1
                  value: "true"
                command:
                - "/bin/sh"
                - "-ec"
                - |
                  /bin/cluster-capacity --podspec=/test-pod/pod.yaml --verbose
              restartPolicy: "Never"
              serviceAccountName: cluster-capacity-sa
              volumes:
              - name: test-volume
                configMap:
                  name: cluster-capacity-configmap
      1
      クラスター容量ツールにクラスター内で Pod として実行されていることを認識させる環境変数です。
      ConfigMappod.yaml キーは Pod 仕様ファイル名と同じですが、これは必須ではありません。これを実行することで、入力 Pod 仕様ファイルは /test-pod/pod.yaml として Pod 内でアクセスできます。
    2. 次のコマンドを実行して、クラスター容量イメージを Pod 内のジョブとして実行します。

      $ oc create -f cluster-capacity-job.yaml

検証

  1. ジョブログを確認し、クラスター内でスケジュールできる Pod の数を確認します。

    $ oc logs jobs/cluster-capacity-job

    出力例

    small-pod pod requirements:
            - CPU: 150m
            - Memory: 100Mi
    
    The cluster can schedule 52 instance(s) of the pod small-pod.
    
    Termination reason: Unschedulable: No nodes are available that match all of the
    following predicates:: Insufficient cpu (2).
    
    Pod distribution among nodes:
    small-pod
            - 192.168.124.214: 26 instance(s)
            - 192.168.124.120: 26 instance(s)

8.3. 制限範囲によるリソース消費の制限

デフォルトで、コンテナーは OpenShift Container Platform クラスターのバインドされていないコンピュートリソースで実行されます。制限範囲は、プロジェクト内の特定オブジェクトのリソースの消費を制限できます。

  • Pod およびコンテナー: Pod およびそれらのコンテナーの CPU およびメモリーの最小および最大要件を設定できます。
  • イメージストリーム: ImageStream オブジェクトのイメージおよびタグの数に制限を設定できます。
  • イメージ: 内部レジストリーにプッシュできるイメージのサイズを制限することができます。
  • 永続ボリューム要求 (PVC): 要求できる PVC のサイズを制限できます。

Pod が制限範囲で課される制約を満たさない場合、Pod を namespace に作成することはできません。

8.3.1. 制限範囲について

LimitRange オブジェクトで定義される制限範囲。プロジェクトのリソース消費を制限します。プロジェクトで、Pod、コンテナー、イメージ、イメージストリーム、または永続ボリューム要求 (PVC) の特定のリソース制限を設定できます。

すべてのリソース作成および変更要求は、プロジェクトのそれぞれの LimitRange オブジェクトに対して評価されます。リソースが列挙される制約のいずれかに違反する場合、そのリソースは拒否されます。

以下は、Pod、コンテナー、イメージ、イメージストリーム、または PVC のすべてのコンポーネントの制限範囲オブジェクトを示しています。同じオブジェクト内のこれらのコンポーネントのいずれかまたはすべての制限を設定できます。リソースを制御するプロジェクトごとに、異なる制限範囲オブジェクトを作成します。

コンテナーの制限オブジェクトのサンプル

apiVersion: "v1"
kind: "LimitRange"
metadata:
  name: "resource-limits"
spec:
  limits:
    - type: "Container"
      max:
        cpu: "2"
        memory: "1Gi"
      min:
        cpu: "100m"
        memory: "4Mi"
      default:
        cpu: "300m"
        memory: "200Mi"
      defaultRequest:
        cpu: "200m"
        memory: "100Mi"
      maxLimitRequestRatio:
        cpu: "10"

8.3.1.1. コンポーネントの制限について

以下の例は、それぞれのコンポーネントの制限範囲パラメーターを示しています。これらの例は明確にするために使用されます。必要に応じて、いずれかまたはすべてのコンポーネントの単一の LimitRange オブジェクトを作成できます。

8.3.1.1.1. コンテナーの制限

制限範囲により、Pod の各コンテナーが特定のプロジェクトについて要求できる最小および最大 CPU およびメモリーを指定できます。コンテナーがプロジェクトに作成される場合、Pod 仕様のコンテナー CPU およびメモリー要求は LimitRange オブジェクトに設定される値に準拠する必要があります。そうでない場合には、Pod は作成されません。

  • コンテナーの CPU またはメモリーの要求および制限は、LimitRange オブジェクトで指定されるコンテナーの min リソース制約以上である必要があります。
  • コンテナーの CPU またはメモリーの要求と制限は、LimitRange オブジェクトで指定されたコンテナーの max リソース制約以下である必要があります。

    LimitRange オブジェクトが max CPU を定義する場合、Pod 仕様に CPU request 値を定義する必要はありません。ただし、制限範囲で指定される最大 CPU 制約を満たす CPU limit 値を指定する必要があります。

  • コンテナー制限の要求に対する比率は、LimitRange オブジェクトに指定されるコンテナーの maxLimitRequestRatio 値以下である必要があります。

    LimitRange オブジェクトで maxLimitRequestRatio 制約を定義する場合、新規コンテナーには request および limit 値の両方が必要になります。OpenShift Container Platform は、limitrequest で除算して制限の要求に対する比率を算出します。この値は、1 より大きい正の整数でなければなりません。

    たとえば、コンテナーの limit 値が cpu: 500 で、request 値が cpu: 100 である場合、cpu の要求に対する制限の比は 5 になります。この比率は maxLimitRequestRatio より小さいか等しくなければなりません。

Pod 仕様でコンテナーリソースメモリーまたは制限を指定しない場合、制限範囲オブジェクトに指定されるコンテナーの default または defaultRequest CPU およびメモリー値はコンテナーに割り当てられます。

コンテナー LimitRange オブジェクトの定義

apiVersion: "v1"
kind: "LimitRange"
metadata:
  name: "resource-limits" 1
spec:
  limits:
    - type: "Container"
      max:
        cpu: "2" 2
        memory: "1Gi" 3
      min:
        cpu: "100m" 4
        memory: "4Mi" 5
      default:
        cpu: "300m" 6
        memory: "200Mi" 7
      defaultRequest:
        cpu: "200m" 8
        memory: "100Mi" 9
      maxLimitRequestRatio:
        cpu: "10" 10

1
LimitRange オブジェクトの名前です。
2
Pod の単一コンテナーが要求できる CPU の最大量です。
3
Pod の単一コンテナーが要求できるメモリーの最大量です。
4
Pod の単一コンテナーが要求できる CPU の最小量です。
5
Pod の単一コンテナーが要求できるメモリーの最小量です。
6
コンテナーが使用できる CPU のデフォルト量 (Pod 仕様に指定されていない場合)。
7
コンテナーが使用できるメモリーのデフォルト量 (Pod 仕様に指定されていない場合)。
8
コンテナーが要求できる CPU のデフォルト量 (Pod 仕様に指定されていない場合)。
9
コンテナーが要求できるメモリーのデフォルト量 (Pod 仕様に指定されていない場合)。
10
コンテナーの要求に対する制限の最大比率。
8.3.1.1.2. Pod の制限

制限範囲により、所定プロジェクトの Pod 全体でのすべてのコンテナーの CPU およびメモリーの最小および最大の制限を指定できます。コンテナーをプロジェクトに作成するには、Pod 仕様のコンテナー CPU およびメモリー要求は LimitRange オブジェクトに設定される値に準拠する必要があります。そうでない場合には、Pod は作成されません。

Pod 仕様でコンテナーリソースメモリーまたは制限を指定しない場合、制限範囲オブジェクトに指定されるコンテナーの default または defaultRequest CPU およびメモリー値はコンテナーに割り当てられます。

Pod のすべてのコンテナーにおいて、以下を満たしている必要があります。

  • コンテナーの CPU またはメモリーの要求および制限は、LimitRange オブジェクトに指定される Pod の min リソース制約以上である必要があります。
  • コンテナーの CPU またはメモリーの要求および制限は、LimitRange オブジェクトに指定される Pod の max リソース制約以下である必要があります。
  • コンテナー制限の要求に対する比率は、LimitRange オブジェクトに指定される maxLimitRequestRatio 制約以下である必要があります。

Pod LimitRange オブジェクト定義

apiVersion: "v1"
kind: "LimitRange"
metadata:
  name: "resource-limits" 1
spec:
  limits:
    - type: "Pod"
      max:
        cpu: "2" 2
        memory: "1Gi" 3
      min:
        cpu: "200m" 4
        memory: "6Mi" 5
      maxLimitRequestRatio:
        cpu: "10" 6

1
制限範囲オブジェクトの名前です。
2
すべてのコンテナーにおいて Pod が要求できる CPU の最大量です。
3
すべてのコンテナーにおいて Pod が要求できるメモリーの最大量です。
4
すべてのコンテナーにおいて Pod が要求できる CPU の最小量です。
5
すべてのコンテナーにおいて Pod が要求できるメモリーの最小量です。
6
コンテナーの要求に対する制限の最大比率。
8.3.1.1.3. イメージの制限

LimitRange オブジェクトを使用すると、OpenShift イメージレジストリーにプッシュできるイメージの最大サイズを指定できます。

OpenShift イメージレジストリーにイメージをプッシュする場合、以下を満たす必要があります。

  • イメージのサイズは、LimitRange オブジェクトで指定されるイメージの max サイズ以下である必要があります。

イメージ LimitRange オブジェクトの定義

apiVersion: "v1"
kind: "LimitRange"
metadata:
  name: "resource-limits" 1
spec:
  limits:
    - type: openshift.io/Image
      max:
        storage: 1Gi 2

1
LimitRange オブジェクトの名前。
2
OpenShift イメージレジストリーにプッシュできるイメージの最大サイズ。
注記

制限を超える Blob がレジストリーにアップロードされないようにするために、クォータを実施するようレジストリーを設定する必要があります。

警告

イメージのサイズは、アップロードされるイメージのマニフェストで常に表示される訳ではありません。これは、とりわけ Docker 1.10 以上で作成され、v2 レジストリーにプッシュされたイメージの場合に該当します。このようなイメージが古い Docker デーモンでプルされると、イメージマニフェストはレジストリーによってスキーマ v1 に変換されますが、この場合サイズ情報が欠落します。イメージに設定されるストレージの制限がこのアップロードを防ぐことはありません。

現在、この問題 への対応が行われています。

8.3.1.1.4. イメージストリームの制限

LimitRange オブジェクトにより、イメージストリームの制限を指定できます。

各イメージストリームについて、以下が当てはまります。

  • ImageStream 仕様のイメージタグ数は、LimitRange オブジェクトの openshift.io/image-tags 制約以下である必要があります。
  • ImageStream 仕様のイメージへの一意の参照数は、制限範囲オブジェクトの openshift.io/images 制約以下である必要があります。

イメージストリーム LimitRange オブジェクト定義

apiVersion: "v1"
kind: "LimitRange"
metadata:
  name: "resource-limits" 1
spec:
  limits:
    - type: openshift.io/ImageStream
      max:
        openshift.io/image-tags: 20 2
        openshift.io/images: 30 3

1
LimitRange オブジェクトの名前。
2
イメージストリーム仕様の imagestream.spec.tags パラメーターの一意のイメージタグの最大数。
3
imagestream 仕様の imagestream.status.tags パラメーターの一意のイメージ参照の最大数。

openshift.io/image-tags リソースは、一意のイメージ参照を表します。使用できる参照は、ImageStreamTagImageStreamImage および DockerImage になります。タグは、oc tag および oc import-image コマンドを使用して作成できます。内部参照か外部参照であるかの区別はありません。ただし、ImageStream の仕様でタグ付けされる一意の参照はそれぞれ 1 回のみカウントされます。内部コンテナーイメージレジストリーへのプッシュを制限しませんが、タグの制限に役立ちます。

openshift.io/images リソースは、イメージストリームのステータスに記録される一意のイメージ名を表します。これにより、OpenShift イメージレジストリーにプッシュできるイメージ数を制限できます。内部参照か外部参照であるかの区別はありません。

8.3.1.1.5. 永続ボリューム要求の制限

LimitRange オブジェクトにより、永続ボリューム要求 (PVC) で要求されるストレージを制限できます。

プロジェクトのすべての永続ボリューム要求において、以下が一致している必要があります。

  • 永続ボリューム要求 (PVC) のリソース要求は、LimitRange オブジェクトに指定される PVC の min 制約以上である必要があります。
  • 永続ボリューム要求 (PVC) のリソース要求は、LimitRange オブジェクトに指定される PVC の max 制約以下である必要があります。

PVC LimitRange オブジェクト定義

apiVersion: "v1"
kind: "LimitRange"
metadata:
  name: "resource-limits" 1
spec:
  limits:
    - type: "PersistentVolumeClaim"
      min:
        storage: "2Gi" 2
      max:
        storage: "50Gi" 3

1
LimitRange オブジェクトの名前。
2
永続ボリューム要求で要求できるストレージの最小量です。
3
永続ボリューム要求で要求できるストレージの最大量です。

8.3.2. 制限範囲の作成

制限範囲をプロジェクトに適用するには、以下を実行します。

  1. 必要な仕様で LimitRange オブジェクトを作成します。

    apiVersion: "v1"
    kind: "LimitRange"
    metadata:
      name: "resource-limits" 1
    spec:
      limits:
        - type: "Pod" 2
          max:
            cpu: "2"
            memory: "1Gi"
          min:
            cpu: "200m"
            memory: "6Mi"
        - type: "Container" 3
          max:
            cpu: "2"
            memory: "1Gi"
          min:
            cpu: "100m"
            memory: "4Mi"
          default: 4
            cpu: "300m"
            memory: "200Mi"
          defaultRequest: 5
            cpu: "200m"
            memory: "100Mi"
          maxLimitRequestRatio: 6
            cpu: "10"
        - type: openshift.io/Image 7
          max:
            storage: 1Gi
        - type: openshift.io/ImageStream 8
          max:
            openshift.io/image-tags: 20
            openshift.io/images: 30
        - type: "PersistentVolumeClaim" 9
          min:
            storage: "2Gi"
          max:
            storage: "50Gi"
    1
    LimitRange オブジェクトの名前を指定します。
    2
    Pod の制限を設定するには、必要に応じて CPU およびメモリーの最小および最大要求を指定します。
    3
    コンテナーの制限を設定するには、必要に応じて CPU およびメモリーの最小および最大要求を指定します。
    4
    オプション: コンテナーの場合、Pod 仕様で指定されていない場合、コンテナーが使用できる CPU またはメモリーのデフォルト量を指定します。
    5
    オプション: コンテナーの場合、Pod 仕様で指定されていない場合、コンテナーが要求できる CPU またはメモリーのデフォルト量を指定します。
    6
    オプション: コンテナーの場合、Pod 仕様で指定できる要求に対する制限の最大比率を指定します。
    7
    Image オブジェクトに制限を設定するには、OpenShift イメージレジストリーにプッシュできるイメージの最大サイズを設定します。
    8
    イメージストリームの制限を設定するには、必要に応じて ImageStream オブジェクトファイルにあるイメージタグおよび参照の最大数を設定します。
    9
    永続ボリューム要求の制限を設定するには、要求できるストレージの最小および最大量を設定します。
  2. オブジェクトを作成します。

    $ oc create -f <limit_range_file> -n <project> 1
    1
    作成した YAML ファイルの名前と、制限を適用する必要のあるプロジェクトを指定します。

8.3.3. 制限の表示

Web コンソールでプロジェクトの Quota ページに移動し、プロジェクトで定義される制限を表示できます。

CLI を使用して制限範囲の詳細を表示することもできます。

  1. プロジェクトで定義される LimitRange オブジェクトのリストを取得します。たとえば、demoproject というプロジェクトの場合は以下のようになります。

    $ oc get limits -n demoproject
    NAME              CREATED AT
    resource-limits   2020-07-15T17:14:23Z
  2. 関連のある LimitRange オブジェクトを記述します。 たとえば、resource-limits 制限範囲の場合は以下のようになります。

    $ oc describe limits resource-limits -n demoproject
    Name:                           resource-limits
    Namespace:                      demoproject
    Type                            Resource                Min     Max     Default Request Default Limit   Max Limit/Request Ratio
    ----                            --------                ---     ---     --------------- -------------   -----------------------
    Pod                             cpu                     200m    2       -               -               -
    Pod                             memory                  6Mi     1Gi     -               -               -
    Container                       cpu                     100m    2       200m            300m            10
    Container                       memory                  4Mi     1Gi     100Mi           200Mi           -
    openshift.io/Image              storage                 -       1Gi     -               -               -
    openshift.io/ImageStream        openshift.io/image      -       12      -               -               -
    openshift.io/ImageStream        openshift.io/image-tags -       10      -               -               -
    PersistentVolumeClaim           storage                 -       50Gi    -               -               -

8.3.4. 制限範囲の削除

プロジェクトで制限を実施しないように有効な LimitRange オブジェクト削除するには、以下を実行します。

  • 以下のコマンドを実行します。

    $ oc delete limits <limit_name>

8.4. コンテナーメモリーとリスク要件を満たすためのクラスターメモリーの設定

クラスター管理者は、以下を実行し、クラスターがアプリケーションメモリーの管理を通じて効率的に動作するようにすることができます。

  • コンテナー化されたアプリケーションコンポーネントのメモリーおよびリスク要件を判別し、それらの要件を満たすようコンテナーメモリーパラメーターを設定する
  • コンテナー化されたアプリケーションランタイム (OpenJDK など) を、設定されたコンテナーメモリーパラメーターに基づいて最適に実行されるよう設定する
  • コンテナーでの実行に関連するメモリー関連のエラー状態を診断し、これを解決する

8.4.1. アプリケーションメモリーの管理について

まず OpenShift Container Platform によるコンピュートリソースの管理方法の概要をよく読んでから次の手順に進むことを推奨します。

各種のリソース (メモリー、cpu、ストレージ) に応じて、OpenShift Container Platform ではオプションの 要求 および 制限 の値を Pod の各コンテナーに設定できます。

メモリー要求とメモリー制限について、以下の点に注意してください。

  • メモリー要求

    • メモリー要求値は、指定される場合 OpenShift Container Platform スケジューラーに影響を与えます。スケジューラーは、コンテナーのノードへのスケジュール時にメモリー要求を考慮し、コンテナーの使用のために選択されたノードで要求されたメモリーをフェンスオフします。
    • ノードのメモリーが使い切られると、OpenShift Container Platform はメモリー使用がメモリー要求を最も超過しているコンテナーのエビクションを優先します。メモリー消費の深刻な状況が生じる場合、ノードの OOM killer は同様のメトリックに基づいてコンテナーでプロセスを選択し、これを強制終了する場合があります。
    • クラスター管理者は、メモリー要求値に対してクォータを割り当てるか、デフォルト値を割り当てることができます。
    • クラスター管理者は、クラスターのオーバーコミットを管理するために開発者が指定するメモリー要求の値を上書きできます。
  • メモリー制限

    • メモリー制限値が指定されている場合、コンテナーのすべてのプロセスに割り当て可能なメモリーにハード制限を指定します。
    • コンテナーのすべてのプロセスで割り当てられるメモリーがメモリー制限を超過する場合、ノードの OOM (Out of Memory) killer はコンテナーのプロセスをすぐに選択し、これを強制終了します。
    • メモリー要求とメモリー制限の両方が指定される場合、メモリー制限の値はメモリー要求の値よりも大きいか、これと等しくなければなりません。
    • クラスター管理者は、メモリーの制限値に対してクォータを割り当てるか、デフォルト値を割り当てることができます。
    • 最小メモリー制限は 12 MB です。Cannot allocate memory Pod イベントのためにコンテナーの起動に失敗すると、メモリー制限は低くなります。メモリー制限を引き上げるか、これを削除します。制限を削除すると、Pod は制限のないノードのリソースを消費できるようになります。
8.4.1.1. アプリケーションメモリーストラテジーの管理

OpenShift Container Platform でアプリケーションメモリーをサイジングする手順は以下の通りです。

  1. 予想されるコンテナーのメモリー使用の判別

    必要時に予想される平均およびピーク時のコンテナーのメモリー使用を判別します (例: 別の負荷テストを実行)。コンテナーで並行して実行されている可能性のあるすべてのプロセスを必ず考慮に入れるようにしてください。 たとえば、メインのアプリケーションは付属スクリプトを生成しているかどうかを確認します。

  2. リスク選好 (risk appetite) の判別

    エビクションのリスク選好を判別します。リスク選好のレベルが低い場合、コンテナーは予想されるピーク時の使用量と安全マージンのパーセンテージに応じてメモリーを要求します。リスク選好が高くなる場合、予想される平均の使用量に応じてメモリーを要求することがより適切な場合があります。

  3. コンテナーのメモリー要求の設定

    上記に基づいてコンテナーのメモリー要求を設定します。要求がアプリケーションのメモリー使用をより正確に表示することが望ましいと言えます。要求が高すぎる場合には、クラスターおよびクォータの使用が非効率となります。要求が低すぎる場合、アプリケーションのエビクションの可能性が高くなります。

  4. コンテナーのメモリー制限の設定 (必要な場合)

    必要時にコンテナーのメモリー制限を設定します。制限を設定すると、コンテナーのすべてのプロセスのメモリー使用量の合計が制限を超える場合にコンテナーのプロセスがすぐに強制終了されるため、いくつかの利点をもたらします。まずは予期しないメモリー使用の超過を早期に明確にする ("fail fast" (早く失敗する)) ことができ、次にプロセスをすぐに中止できます。

    一部の OpenShift Container Platform クラスターでは制限値を設定する必要があります。 制限に基づいて要求を上書きする場合があります。 また、一部のアプリケーションイメージは、要求値よりも検出が簡単なことから設定される制限値に依存します。

    メモリー制限が設定される場合、これは予想されるピーク時のコンテナーのメモリー使用量と安全マージンのパーセンテージよりも低い値に設定することはできません。

  5. アプリケーションが調整されていることの確認

    適切な場合は、設定される要求および制限値に関連してアプリケーションが調整されていることを確認します。この手順は、JVM などのメモリーをプールするアプリケーションにおいてとくに当てはまります。残りの部分では、これを説明します。

8.4.2. OpenShift Container Platform の OpenJDK 設定について

デフォルトの OpenJDK 設定はコンテナー化された環境では機能しません。そのため、コンテナーで OpenJDK を実行する場合は常に追加の Java メモリー設定を指定する必要があります。

JVM のメモリーレイアウトは複雑で、バージョンに依存しており、このドキュメントではこれについて詳細には説明しません。ただし、コンテナーで OpenJDK を実行する際のスタートにあたって少なくとも以下の 3 つのメモリー関連のタスクが主なタスクになります。

  1. JVM 最大ヒープサイズを上書きする。
  2. JVM が未使用メモリーをオペレーティングシステムに解放するよう促す (適切な場合)。
  3. コンテナー内のすべての JVM プロセスが適切に設定されていることを確認する。

コンテナーでの実行に向けて JVM ワークロードを最適に調整する方法はこのドキュメントでは扱いませんが、これには複数の JVM オプションを追加で設定することが必要になる場合があります。

8.4.2.1. JVM の最大ヒープサイズを上書きする方法について

数多くの Java ワークロードにおいて、JVM ヒープはメモリーの最大かつ単一のコンシューマーです。現時点で OpenJDK は、OpenJDK がコンテナー内で実行されているかにかかわらず、ヒープに使用されるコンピュートノードのメモリーの最大 1/4 (1/-XX:MaxRAMFraction) を許可するようデフォルトで設定されます。そのため、コンテナーのメモリー制限も設定されている場合には、この動作をオーバーライドすることが 必須 です。

上記を実行する方法として、2 つ以上の方法を使用できます:

  • コンテナーのメモリー制限が設定されており、JVM で実験的なオプションがサポートされている場合には、-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap を設定します。

    注記

    JDK 11 では UseCGroupMemoryLimitForHeap オプションが削除されました。-XX:+UseContainerSupport を代わりに使用します。

    これにより、-XX:MaxRAM がコンテナーのメモリー制限に設定され、最大ヒープサイズ (-XX:MaxHeapSize / -Xmx) が 1/-XX:MaxRAMFraction に設定されます (デフォルトでは 1/4)。

  • -XX:MaxRAM-XX:MaxHeapSize または -Xmx のいずれかを直接上書きします。

    このオプションには、値のハードコーディングが必要になりますが、安全マージンを計算できるという利点があります。

8.4.2.2. JVM で未使用メモリーをオペレーティングシステムに解放するよう促す方法について

デフォルトで、OpenJDK は未使用メモリーをオペレーティングシステムに積極的に返しません。これは多くのコンテナー化された Java ワークロードには適していますが、例外として、コンテナー内に JVM と共存する追加のアクティブなプロセスがあるワークロードの場合を考慮する必要があります。 それらの追加のプロセスはネイティブのプロセスである場合や追加の JVM の場合、またはこれら 2 つの組み合わせである場合もあります。

Java ベースのエージェントは、次の JVM 引数を使用して、JVM が未使用のメモリーをオペレーティングシステムに解放するように促すことができます。

-XX:+UseParallelGC
-XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -XX:GCTimeRatio=4
-XX:AdaptiveSizePolicyWeight=90.

これらの引数は、割り当てられたメモリーが使用中のメモリー (-XX:MaxHeapFreeRatio) の 110% を超え、ガベージコレクター (-XX:GCTimeRatio) での CPU 時間の 20% を使用する場合は常にヒープメモリーをオペレーティングシステムに返すことが意図されています。アプリケーションのヒープ割り当てが初期のヒープ割り当て (-XX:InitialHeapSize / -Xms で上書きされる) を下回ることはありません。詳細は、Tuning Java’s footprint in OpenShift (Part 1)Tuning Java’s footprint in OpenShift (Part 2)、および OpenJDK and Containers を参照してください。

8.4.2.3. コンテナー内のすべての JVM プロセスが適切に設定されていることを確認する方法について

複数の JVM が同じコンテナーで実行される場合、それらすべてが適切に設定されていることを確認する必要があります。多くのワークロードでは、それぞれの JVM に memory budget のパーセンテージを付与する必要があります。 これにより大きな安全マージンが残される場合があります。

多くの Java ツールは JVM を設定するために各種の異なる環境変数 (JAVA_OPTSGRADLE_OPTS など) を使用します。 適切な設定が適切な JVM に渡されていることを確認するのが容易でない場合もあります。

JAVA_TOOL_OPTIONS 環境変数は常に OpenJDK によって考慮され、JAVA_TOOL_OPTIONS に指定された値は、JVM コマンドラインに指定される他のオプションによって上書きされます。デフォルトでは、これらのオプションが Java ベースのエージェントイメージで実行されるすべての JVM ワークロードに対してデフォルトで使用されるようにするために、OpenShift Container Platform Jenkins Maven エージェントイメージは以下を設定します。

JAVA_TOOL_OPTIONS="-XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap -Dsun.zip.disableMemoryMapping=true"
注記

JDK 11 では UseCGroupMemoryLimitForHeap オプションが削除されました。-XX:+UseContainerSupport を代わりに使用します。

この設定は、追加オプションが要求されないことを保証する訳ではなく、有用な開始点になることを意図しています。

8.4.3. Pod 内でのメモリー要求および制限の検索

Pod 内からメモリー要求および制限を動的に検出するアプリケーションでは Downward API を使用する必要があります。

手順

  1. MEMORY_REQUESTMEMORY_LIMIT スタンザを追加するように Pod を設定します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: test
      spec:
        containers:
        - name: test
          image: fedora:latest
          command:
          - sleep
          - "3600"
          env:
          - name: MEMORY_REQUEST 1
            valueFrom:
              resourceFieldRef:
                containerName: test
                resource: requests.memory
          - name: MEMORY_LIMIT 2
            valueFrom:
              resourceFieldRef:
                containerName: test
                resource: limits.memory
          resources:
            requests:
              memory: 384Mi
            limits:
              memory: 512Mi
      1
      このスタンザを追加して、アプリケーションメモリーの要求値を見つけます。
      2
      このスタンザを追加して、アプリケーションメモリーの制限値を見つけます。
    2. 以下のコマンドを実行して Pod を作成します。

      $ oc create -f <file-name>.yaml

検証

  1. リモートシェルを使用して Pod にアクセスします。

    $ oc rsh test
  2. 要求された値が適用されていることを確認します。

    $ env | grep MEMORY | sort

    出力例

    MEMORY_LIMIT=536870912
    MEMORY_REQUEST=402653184

注記

メモリー制限値は、/sys/fs/cgroup/memory/memory.limit_in_bytes ファイルによってコンテナー内から読み取ることもできます。

8.4.4. OOM の強制終了ポリシーについて

OpenShift Container Platform は、コンテナーのすべてのプロセスのメモリー使用量の合計がメモリー制限を超えるか、ノードのメモリーを使い切られるなどの深刻な状態が生じる場合にコンテナーのプロセスを強制終了できます。

プロセスが OOM (Out of Memory) によって強制終了される場合、コンテナーがすぐに終了する場合があります。コンテナーの PID 1 プロセスが SIGKILL を受信する場合、コンテナーはすぐに終了します。それ以外の場合、コンテナーの動作は他のプロセスの動作に依存します。

たとえば、コンテナーのプロセスは、SIGKILL シグナルを受信したことを示すコード 137 で終了します。

コンテナーがすぐに終了しない場合、OOM による強制終了は以下のように検出できます。

  1. リモートシェルを使用して Pod にアクセスします。

    # oc rsh test
  2. 以下のコマンドを実行して、/sys/fs/cgroup/memory/memory.oom_control で現在の OOM kill カウントを表示します。

    $ grep '^oom_kill ' /sys/fs/cgroup/memory/memory.oom_control

    出力例

    oom_kill 0

  3. 以下のコマンドを実行して、Out Of Memory (OOM) による強制終了を促します。

    $ sed -e '' </dev/zero

    出力例

    Killed

  4. 以下のコマンドを実行して、sed コマンドの終了ステータスを表示します。

    $ echo $?

    出力例

    137

    137 コードは、コンテナーのプロセスが、SIGKILL シグナルを受信したことを示すコード 137 で終了していることを示唆します。

  5. 以下のコマンドを実行して、/sys/fs/cgroup/memory/memory.oom_control の OOM kill カウンターの増分を表示します。

    $ grep '^oom_kill ' /sys/fs/cgroup/memory/memory.oom_control

    出力例

    oom_kill 1

    Pod の 1 つ以上のプロセスが OOM で強制終了され、Pod がこれに続いて終了する場合 (即時であるかどうかは問わない)、フェーズは Failed、理由は OOMKilled になります。OOM で強制終了された Pod は restartPolicy の値によって再起動する場合があります。再起動されない場合は、レプリケーションコントローラーなどのコントローラーが Pod の失敗したステータスを認識し、古い Pod に置き換わる新規 Pod を作成します。

    以下のコマンドを使用して Pod のステータスを取得します。

    $ oc get pod test

    出力例

    NAME      READY     STATUS      RESTARTS   AGE
    test      0/1       OOMKilled   0          1m

    • Pod が再起動されていない場合は、以下のコマンドを実行して Pod を表示します。

      $ oc get pod test -o yaml

      出力例

      ...
      status:
        containerStatuses:
        - name: test
          ready: false
          restartCount: 0
          state:
            terminated:
              exitCode: 137
              reason: OOMKilled
        phase: Failed

    • 再起動した場合は、以下のコマンドを実行して Pod を表示します。

      $ oc get pod test -o yaml

      出力例

      ...
      status:
        containerStatuses:
        - name: test
          ready: true
          restartCount: 1
          lastState:
            terminated:
              exitCode: 137
              reason: OOMKilled
          state:
            running:
        phase: Running

8.4.5. Pod エビクションについて

OpenShift Container Platform は、ノードのメモリーが使い切られると、そのノードから Pod をエビクトする場合があります。メモリー消費の度合いによって、エビクションは正常に行われる場合もあれば、そうでない場合もあります。正常なエビクションは、各コンテナーのメインプロセス (PID 1) が SIGTERM シグナルを受信してから、プロセスがすでに終了していない場合は後になって SIGKILL シグナルを受信することを意味します。正常ではないエビクションは各コンテナーのメインプロセスが SIGKILL シグナルを即時に受信することを示します。

エビクトされた Pod のフェーズは Failed になり、理由は Evicted になります。この場合、restartPolicy の値に関係なく再起動されません。ただし、レプリケーションコントローラーなどのコントローラーは Pod の失敗したステータスを認識し、古い Pod に置き換わる新規 Pod を作成します。

$ oc get pod test

出力例

NAME      READY     STATUS    RESTARTS   AGE
test      0/1       Evicted   0          1m

$ oc get pod test -o yaml

出力例

...
status:
  message: 'Pod The node was low on resource: [MemoryPressure].'
  phase: Failed
  reason: Evicted

8.5. オーバーコミットされたノード上に Pod を配置するためのクラスターの設定

オーバーコミット とは、コンテナーの計算リソース要求と制限の合計が、そのシステムで利用できるリソースを超えた状態のことです。オーバーコミットの使用は、容量に対して保証されたパフォーマンスのトレードオフが許容可能である開発環境において必要になる場合があります。

コンテナーは、コンピュートリソース要求および制限を指定することができます。要求はコンテナーのスケジューリングに使用され、最小限のサービス保証を提供します。制限は、ノード上で消費できるコンピュートリソースの量を制限します。

スケジューラーは、クラスター内のすべてのノードにおけるコンピュートリソース使用の最適化を試行します。これは Pod のコンピュートリソース要求とノードの利用可能な容量を考慮に入れて Pod を特定のノードに配置します。

OpenShift Container Platform 管理者は、オーバーコミットのレベルを制御し、ノード上のコンテナーの密度を管理できるようになりました。クラスターレベルのオーバーコミットを ClusterResourceOverride Operator を使用して設定し、開発者用のコンテナーに設定された要求と制限の比率について上書きすることができます。ノードのオーバーコミット および プロジェクトのメモリーと CPU の制限とデフォルト を組み合わせてリソースの制限と要求を調整し、必要なレベルのオーバーコミットを達成できます。

注記

OpenShift Container Platform では、クラスターレベルのオーバーコミットを有効にする必要があります。ノードのオーバーコミットはデフォルトで有効にされています。ノードのオーバーコミットの無効化 を参照してください。

8.5.1. リソース要求とオーバーコミット

各コンピュートリソースについて、コンテナーはリソース要求および制限を指定できます。スケジューリングの決定は要求に基づいて行われ、ノードに要求される値を満たす十分な容量があることが確認されます。コンテナーが制限を指定するものの、要求を省略する場合、要求はデフォルトで制限値に設定されます。コンテナーは、ノードの指定される制限を超えることはできません。

制限の実施方法は、コンピュートリソースのタイプによって異なります。コンテナーが要求または制限を指定しない場合、コンテナーはリソース保証のない状態でノードにスケジュールされます。実際に、コンテナーはローカルの最も低い優先順位で利用できる指定リソースを消費できます。リソースが不足する状態では、リソース要求を指定しないコンテナーに最低レベルの quality of service が設定されます。

スケジューリングは要求されるリソースに基づいて行われる一方で、クォータおよびハード制限はリソース制限のことを指しており、これは要求されるリソースよりも高い値に設定できます。要求と制限の間の差異は、オーバーコミットのレベルを定めるものとなります。たとえば、コンテナーに 1Gi のメモリー要求と 2Gi のメモリー制限が指定される場合、コンテナーのスケジューリングはノードで 1Gi を利用可能とする要求に基づいて行われますが、2Gi まで使用することができます。そのため、この場合のオーバーコミットは 200% になります。

8.5.2. Cluster Resource Override Operator を使用したクラスターレベルのオーバーコミット

Cluster Resource Override Operator は、クラスター内のすべてのノードでオーバーコミットのレベルを制御し、コンテナーの密度を管理できる受付 Webhook です。Operator は、特定のプロジェクトのノードが定義されたメモリーおよび CPU 制限を超える場合について制御します。

以下のセクションで説明されているように、OpenShift Container Platform コンソールまたは CLI を使用して Cluster Resource Override Operator をインストールする必要があります。インストール時に、以下の例のように、オーバーコミットのレベルを設定する ClusterResourceOverride カスタムリソース (CR) を作成します。

apiVersion: operator.autoscaling.openshift.io/v1
kind: ClusterResourceOverride
metadata:
    name: cluster 1
spec:
  podResourceOverride:
    spec:
      memoryRequestToLimitPercent: 50 2
      cpuRequestToLimitPercent: 25 3
      limitCPUToMemoryPercent: 200 4
# ...
1
名前は cluster でなければなりません。
2
オプション: コンテナーのメモリー制限が指定されているか、デフォルトに設定されている場合、メモリー要求は制限のパーセンテージ (1-100) に対して上書きされます。デフォルトは 50 です。
3
オプション: コンテナーの CPU 制限が指定されているか、デフォルトに設定されている場合、CPU 要求は、1-100 までの制限のパーセンテージに対応して上書きされます。デフォルトは 25 です。
4
オプション: コンテナーのメモリー制限が指定されているか、デフォルトに設定されている場合、CPU 制限は、指定されている場合にメモリーのパーセンテージに対して上書きされます。1Gi の RAM の 100 パーセントでのスケーリングは、1 CPU コアに等しくなります。これは、CPU 要求を上書きする前に処理されます (設定されている場合)。デフォルトは 200 です。
注記

Cluster Resource Override Operator の上書きは、制限がコンテナーに設定されていない場合は影響を与えません。個別プロジェクトごとのデフォルト制限を使用して LimitRange オブジェクトを作成するか、Pod 仕様で制限を設定し、上書きが適用されるようにします。

設定時に、以下のラベルを各プロジェクトの namespace オブジェクトに適用し、上書きをプロジェクトごとに有効にできます。

apiVersion: v1
kind: Namespace
metadata:

# ...

  labels:
    clusterresourceoverrides.admission.autoscaling.openshift.io/enabled: "true"

# ...

Operator は ClusterResourceOverride CR の有無を監視し、ClusterResourceOverride 受付 Webhook が Operator と同じ namespace にインストールされるようにします。

8.5.2.1. Web コンソールを使用した Cluster Resource Override Operator のインストール

クラスターでオーバーコミットを制御できるように、OpenShift Container Platform Web コンソールを使用して Cluster Resource Override Operator をインストールできます。

前提条件

  • 制限がコンテナーに設定されていない場合、Cluster Resource Override Operator は影響を与えません。LimitRange オブジェクトを使用してプロジェクトのデフォルト制限を指定するか、Pod 仕様で制限を設定して上書きが適用されるようにする必要があります。

手順

OpenShift Container Platform Web コンソールを使用して Cluster Resource Override Operator をインストールするには、以下を実行します。

  1. OpenShift Container Platform Web コンソールで、HomeProjects に移動します。

    1. Create Project をクリックします。
    2. clusterresourceoverride-operator をプロジェクトの名前として指定します。
    3. Create をクリックします。
  2. OperatorsOperatorHub に移動します。

    1. 利用可能な Operator のリストから ClusterResourceOverride Operator を選択し、Install をクリックします。
    2. Install Operator ページで、A specific Namespace on the clusterInstallation Mode について選択されていることを確認します。
    3. clusterresourceoverride-operatorInstalled Namespace について選択されていることを確認します。
    4. Update Channel および Approval Strategy を選択します。
    5. Install をクリックします。
  3. Installed Operators ページで、ClusterResourceOverride をクリックします。

    1. ClusterResourceOverride Operator 詳細ページで、Create ClusterResourceOverride をクリックします。
    2. Create ClusterResourceOverride ページで、YAML view をクリックして、YAML テンプレートを編集し、必要に応じてオーバーコミット値を設定します。

      apiVersion: operator.autoscaling.openshift.io/v1
      kind: ClusterResourceOverride
      metadata:
        name: cluster 1
      spec:
        podResourceOverride:
          spec:
            memoryRequestToLimitPercent: 50 2
            cpuRequestToLimitPercent: 25 3
            limitCPUToMemoryPercent: 200 4
      # ...
      1
      名前は cluster でなければなりません。
      2
      オプション: コンテナーメモリーの制限を上書きするためのパーセンテージが使用される場合は、これを 1-100 までの値で指定します。デフォルトは 50 です。
      3
      オプション: コンテナー CPU の制限を上書きするためのパーセンテージが使用される場合は、これを 1-100 までの値で指定します。デフォルトは 25 です。
      4
      オプション: コンテナーメモリーの制限を上書きするためのパーセンテージが使用される場合は、これを指定します。1Gi の RAM の 100 パーセントでのスケーリングは、1 CPU コアに等しくなります。これは、CPU 要求を上書きする前に処理されます (設定されている場合)。デフォルトは 200 です。
    3. Create をクリックします。
  4. クラスターカスタムリソースのステータスをチェックして、受付 Webhook の現在の状態を確認します。

    1. ClusterResourceOverride Operator ページで、cluster をクリックします。
    2. ClusterResourceOverride Details ページで、YAML をクリックします。Webhook の呼び出し時に、mutatingWebhookConfigurationRef セクションが表示されます。

      apiVersion: operator.autoscaling.openshift.io/v1
      kind: ClusterResourceOverride
      metadata:
        annotations:
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"operator.autoscaling.openshift.io/v1","kind":"ClusterResourceOverride","metadata":{"annotations":{},"name":"cluster"},"spec":{"podResourceOverride":{"spec":{"cpuRequestToLimitPercent":25,"limitCPUToMemoryPercent":200,"memoryRequestToLimitPercent":50}}}}
        creationTimestamp: "2019-12-18T22:35:02Z"
        generation: 1
        name: cluster
        resourceVersion: "127622"
        selfLink: /apis/operator.autoscaling.openshift.io/v1/clusterresourceoverrides/cluster
        uid: 978fc959-1717-4bd1-97d0-ae00ee111e8d
      spec:
        podResourceOverride:
          spec:
            cpuRequestToLimitPercent: 25
            limitCPUToMemoryPercent: 200
            memoryRequestToLimitPercent: 50
      status:
      
      # ...
      
          mutatingWebhookConfigurationRef: 1
            apiVersion: admissionregistration.k8s.io/v1
            kind: MutatingWebhookConfiguration
            name: clusterresourceoverrides.admission.autoscaling.openshift.io
            resourceVersion: "127621"
            uid: 98b3b8ae-d5ce-462b-8ab5-a729ea8f38f3
      
      # ...
      1
      ClusterResourceOverride 受付 Webhook への参照。
8.5.2.2. CLI を使用した Cluster Resource Override Operator のインストール

OpenShift Container Platform CLI を使用して Cluster Resource Override Operator をインストールし、クラスターでのオーバーコミットを制御できます。

前提条件

  • 制限がコンテナーに設定されていない場合、Cluster Resource Override Operator は影響を与えません。LimitRange オブジェクトを使用してプロジェクトのデフォルト制限を指定するか、Pod 仕様で制限を設定して上書きが適用されるようにする必要があります。

手順

CLI を使用して Cluster Resource Override Operator をインストールするには、以下を実行します。

  1. Cluster Resource Override の namespace を作成します。

    1. Cluster Resource Override Operator の Namespace オブジェクト YAML ファイル (cro-namespace.yaml など) を作成します。

      apiVersion: v1
      kind: Namespace
      metadata:
        name: clusterresourceoverride-operator
    2. namespace を作成します。

      $ oc create -f <file-name>.yaml

      以下に例を示します。

      $ oc create -f cro-namespace.yaml
  2. Operator グループを作成します。

    1. Cluster Resource Override Operator の OperatorGroup オブジェクトの YAML ファイル (cro-og.yaml など) を作成します。

      apiVersion: operators.coreos.com/v1
      kind: OperatorGroup
      metadata:
        name: clusterresourceoverride-operator
        namespace: clusterresourceoverride-operator
      spec:
        targetNamespaces:
          - clusterresourceoverride-operator
    2. Operator グループを作成します。

      $ oc create -f <file-name>.yaml

      以下に例を示します。

      $ oc create -f cro-og.yaml
  3. サブスクリプションを作成します。

    1. Cluster Resource Override Operator の Subscription オブジェクト YAML ファイル (cro-sub.yaml など) を作成します。

      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: clusterresourceoverride
        namespace: clusterresourceoverride-operator
      spec:
        channel: "4.14"
        name: clusterresourceoverride
        source: redhat-operators
        sourceNamespace: openshift-marketplace
    2. サブスクリプションを作成します。

      $ oc create -f <file-name>.yaml

      以下に例を示します。

      $ oc create -f cro-sub.yaml
  4. ClusterResourceOverride カスタムリソース (CR) オブジェクトを clusterresourceoverride-operator namespace に作成します。

    1. clusterresourceoverride-operator namespace に切り替えます。

      $ oc project clusterresourceoverride-operator
    2. Cluster Resource Override Operator の ClusterResourceOverride オブジェクト YAML ファイル (cro-cr.yaml など) を作成します。

      apiVersion: operator.autoscaling.openshift.io/v1
      kind: ClusterResourceOverride
      metadata:
          name: cluster 1
      spec:
        podResourceOverride:
          spec:
            memoryRequestToLimitPercent: 50 2
            cpuRequestToLimitPercent: 25 3
            limitCPUToMemoryPercent: 200 4
      1
      名前は cluster でなければなりません。
      2
      オプション: コンテナーメモリーの制限を上書きするためのパーセンテージが使用される場合は、これを 1-100 までの値で指定します。デフォルトは 50 です。
      3
      オプション: コンテナー CPU の制限を上書きするためのパーセンテージが使用される場合は、これを 1-100 までの値で指定します。デフォルトは 25 です。
      4
      オプション: コンテナーメモリーの制限を上書きするためのパーセンテージが使用される場合は、これを指定します。1Gi の RAM の 100 パーセントでのスケーリングは、1 CPU コアに等しくなります。これは、CPU 要求を上書きする前に処理されます (設定されている場合)。デフォルトは 200 です。
    3. ClusterResourceOverride オブジェクトを作成します。

      $ oc create -f <file-name>.yaml

      以下に例を示します。

      $ oc create -f cro-cr.yaml
  5. クラスターカスタムリソースのステータスをチェックして、受付 Webhook の現在の状態を確認します。

    $ oc get clusterresourceoverride cluster -n clusterresourceoverride-operator -o yaml

    Webhook の呼び出し時に、mutatingWebhookConfigurationRef セクションが表示されます。

    出力例

    apiVersion: operator.autoscaling.openshift.io/v1
    kind: ClusterResourceOverride
    metadata:
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"operator.autoscaling.openshift.io/v1","kind":"ClusterResourceOverride","metadata":{"annotations":{},"name":"cluster"},"spec":{"podResourceOverride":{"spec":{"cpuRequestToLimitPercent":25,"limitCPUToMemoryPercent":200,"memoryRequestToLimitPercent":50}}}}
      creationTimestamp: "2019-12-18T22:35:02Z"
      generation: 1
      name: cluster
      resourceVersion: "127622"
      selfLink: /apis/operator.autoscaling.openshift.io/v1/clusterresourceoverrides/cluster
      uid: 978fc959-1717-4bd1-97d0-ae00ee111e8d
    spec:
      podResourceOverride:
        spec:
          cpuRequestToLimitPercent: 25
          limitCPUToMemoryPercent: 200
          memoryRequestToLimitPercent: 50
    status:
    
    # ...
    
        mutatingWebhookConfigurationRef: 1
          apiVersion: admissionregistration.k8s.io/v1
          kind: MutatingWebhookConfiguration
          name: clusterresourceoverrides.admission.autoscaling.openshift.io
          resourceVersion: "127621"
          uid: 98b3b8ae-d5ce-462b-8ab5-a729ea8f38f3
    
    # ...

    1
    ClusterResourceOverride 受付 Webhook への参照。
8.5.2.3. クラスターレベルのオーバーコミットの設定

Cluster Resource Override Operator には、Operator がオーバーコミットを制御する必要のある各プロジェクトの ClusterResourceOverride カスタムリソース (CR) およびラベルが必要です。

前提条件

  • 制限がコンテナーに設定されていない場合、Cluster Resource Override Operator は影響を与えません。LimitRange オブジェクトを使用してプロジェクトのデフォルト制限を指定するか、Pod 仕様で制限を設定して上書きが適用されるようにする必要があります。

手順

クラスターレベルのオーバーコミットを変更するには、以下を実行します。

  1. ClusterResourceOverride CR を編集します。

    apiVersion: operator.autoscaling.openshift.io/v1
    kind: ClusterResourceOverride
    metadata:
        name: cluster
    spec:
      podResourceOverride:
        spec:
          memoryRequestToLimitPercent: 50 1
          cpuRequestToLimitPercent: 25 2
          limitCPUToMemoryPercent: 200 3
    # ...
    1
    オプション: コンテナーメモリーの制限を上書きするためのパーセンテージが使用される場合は、これを 1-100 までの値で指定します。デフォルトは 50 です。
    2
    オプション: コンテナー CPU の制限を上書きするためのパーセンテージが使用される場合は、これを 1-100 までの値で指定します。デフォルトは 25 です。
    3
    オプション: コンテナーメモリーの制限を上書きするためのパーセンテージが使用される場合は、これを指定します。1Gi の RAM の 100 パーセントでのスケーリングは、1 CPU コアに等しくなります。これは、CPU 要求を上書きする前に処理されます (設定されている場合)。デフォルトは 200 です。
  2. 以下のラベルが Cluster Resource Override Operator がオーバーコミットを制御する必要のある各プロジェクトの namespace オブジェクトに追加されていることを確認します。

    apiVersion: v1
    kind: Namespace
    metadata:
    
    # ...
    
      labels:
        clusterresourceoverrides.admission.autoscaling.openshift.io/enabled: "true" 1
    
    # ...
    1
    このラベルを各プロジェクトに追加します。

8.5.3. ノードレベルのオーバーコミット

quality of service (QOS) 保証、CPU 制限、またはリソースの予約など、特定ノードでオーバーコミットを制御するさまざまな方法を使用できます。特定のノードおよび特定のプロジェクトのオーバーコミットを無効にすることもできます。

8.5.3.1. コンピュートリソースとコンテナーについて

コンピュートリソースに関するノードで実施される動作は、リソースタイプによって異なります。

8.5.3.1.1. コンテナーの CPU 要求について

コンテナーには要求する CPU の量が保証され、さらにコンテナーで指定される任意の制限までノードで利用可能な CPU を消費できます。複数のコンテナーが追加の CPU の使用を試行する場合、CPU 時間が各コンテナーで要求される CPU の量に基づいて分配されます。

たとえば、あるコンテナーが 500m の CPU 時間を要求し、別のコンテナーが 250m の CPU 時間を要求した場合、ノードで利用可能な追加の CPU 時間は 2:1 の比率でコンテナー間で分配されます。コンテナーが制限を指定している場合、指定した制限を超えて CPU を使用しないようにスロットリングされます。CPU 要求は、Linux カーネルの CFS 共有サポートを使用して適用されます。デフォルトで、CPU 制限は、Linux カーネルの CFS クォータサポートを使用して 100ms の測定間隔で適用されます。 ただし、これは無効にすることができます。

8.5.3.1.2. コンテナーのメモリー要求について

コンテナーには要求するメモリー量が保証されます。コンテナーは要求したよりも多くのメモリーを使用できますが、いったん要求した量を超えた場合には、ノードのメモリーが不足している状態では強制終了される可能性があります。コンテナーが要求した量よりも少ないメモリーを使用する場合、システムタスクやデーモンがノードのリソース予約で確保されている分よりも多くのメモリーを必要としない限りそれが強制終了されることはありません。コンテナーがメモリーの制限を指定する場合、その制限量を超えると即時に強制終了されます。

8.5.3.2. オーバーコミットメントと quality of service クラスについて

ノードは、要求を指定しない Pod がスケジュールされている場合やノードのすべての Pod での制限の合計が利用可能なマシンの容量を超える場合に オーバーコミット されます。

オーバーコミットされる環境では、ノード上の Pod がいずれかの時点で利用可能なコンピュートリソースよりも多くの量の使用を試行することができます。これが生じると、ノードはそれぞれの Pod に優先順位を指定する必要があります。この決定を行うために使用される機能は、Quality of Service (QoS) クラスと呼ばれます。

Pod は、優先度の高い順に 3 つの QoS クラスの 1 つとして指定されます。

表8.19 Quality of Service クラス
優先順位クラス名説明

1 (最高)

Guaranteed

制限およびオプションの要求がすべてのリソースについて設定されている場合 (0 と等しくない) でそれらの値が等しい場合、Pod は Guaranteed として分類されます。

2

Burstable

制限およびオプションの要求がすべてのリソースについて設定されている場合 (0 と等しくない) でそれらの値が等しくない場合、Pod は Burstable として分類されます。

3 (最低)

BestEffort

要求および制限がリソースのいずれについても設定されない場合、Pod は BestEffort として分類されます。

メモリーは圧縮できないリソースであるため、メモリー不足の状態では、最も優先順位の低いコンテナーが最初に強制終了されます。

  • Guaranteed コンテナーは優先順位が最も高いコンテナーとして見なされ、保証されます。 強制終了されるのは、これらのコンテナーで制限を超えるか、システムがメモリー不足の状態にあるものの、エビクトできる優先順位の低いコンテナーが他にない場合のみです。
  • システム不足の状態にある Burstable コンテナーは、制限を超過し、BestEffort コンテナーが他に存在しない場合に強制終了される可能性があります。
  • BestEffort コンテナーは優先順位の最も低いコンテナーとして処理されます。これらのコンテナーのプロセスは、システムがメモリー不足になると最初に強制終了されます。
8.5.3.2.1. Quality of Service (QoS) 層でのメモリーの予約方法について

qos-reserved パラメーターを使用して、特定の QoS レベルの Pod で予約されるメモリーのパーセンテージを指定することができます。この機能は、最も低い OoS クラスの Pod が高い QoS クラスの Pod で要求されるリソースを使用できないようにするために要求されたリソースの予約を試行します。

OpenShift Container Platform は、以下のように qos-reserved パラメーターを使用します。

  • qos-reserved=memory=100% の値は、Burstable および BestEffort QoS クラスが、これらより高い QoS クラスで要求されたメモリーを消費するのを防ぎます。これにより、Guaranteed および Burstable ワークロードのメモリーリソースの保証レベルを上げることが優先され、BestEffort および Burstable ワークロードでの OOM が発生するリスクが高まります。
  • qos-reserved=memory=50% の値は、Burstable および BestEffort QoS クラスがこれらより高い QoS クラスによって要求されるメモリーの半分を消費することを許可します。
  • qos-reserved=memory=0% の値は、Burstable および BestEffort QoS クラスがノードの割り当て可能分を完全に消費することを許可しますが (利用可能な場合)、これにより、Guaranteed ワークロードが要求したメモリーにアクセスできなくなるリスクが高まります。この状況により、この機能は無効にされています。
8.5.3.3. swap メモリーと QOS について

Quality of Service (QOS) 保証を維持するため、swap はノード上でデフォルトで無効にすることができます。そうしない場合、ノードの物理リソースがオーバーサブスクライブし、Pod の配置時の Kubernetes スケジューラーによるリソース保証が影響を受ける可能性があります。

たとえば、2 つの Guaranteed Pod がメモリー制限に達した場合、それぞれのコンテナーが swap メモリーを使用し始める可能性があります。十分な swap 領域がない場合には、pod のプロセスはシステムのオーバーサブスクライブのために終了する可能性があります。

swap を無効にしないと、ノードが MemoryPressure にあることを認識しなくなり、Pod がスケジューリング要求に対応するメモリーを受け取れなくなります。結果として、追加の Pod がノードに配置され、メモリー不足の状態が加速し、最終的にはシステムの Out Of Memory (OOM) イベントが発生するリスクが高まります。

重要

swap が有効にされている場合、利用可能なメモリーに関するリソース不足の処理 (out of resource handling) のエビクションしきい値は予期どおりに機能しなくなります。メモリー不足の状態の場合に Pod をノードからエビクトし、Pod を不足状態にない別のノードで再スケジューリングできるようにリソース不足の処理 (out of resource handling) を利用できるようにします。

8.5.3.4. ノードのオーバーコミットについて

オーバーコミット環境では、最適なシステム動作を提供できるようにノードを適切に設定する必要があります。

ノードが起動すると、メモリー管理用のカーネルの調整可能なフラグが適切に設定されます。カーネルは、物理メモリーが不足しない限り、メモリーの割り当てに失敗するこはありません。

この動作を確認するため、OpenShift Container Platform は、vm.overcommit_memory パラメーターを 1 に設定し、デフォルトのオペレーティングシステムの設定を上書きすることで、常にメモリーをオーバーコミットするようにカーネルを設定します。

また、OpenShift Container Platform は vm.panic_on_oom パラメーターを 0 に設定することで、メモリーが不足したときでもカーネルがパニックにならないようにします。0 の設定は、Out of Memory (OOM) 状態のときに oom_killer を呼び出すようカーネルに指示します。これにより、優先順位に基づいてプロセスを強制終了します。

現在の設定は、ノードに以下のコマンドを実行して表示できます。

$ sysctl -a |grep commit

出力例

#...
vm.overcommit_memory = 0
#...

$ sysctl -a |grep panic

出力例

#...
vm.panic_on_oom = 0
#...

注記

上記のフラグはノード上にすでに設定されているはずであるため、追加のアクションは不要です。

各ノードに対して以下の設定を実行することもできます。

  • CPU CFS クォータを使用した CPU 制限の無効化または実行
  • システムプロセスのリソース予約
  • Quality of Service (QoS) 層でのメモリー予約
8.5.3.5. CPU CFS クォータの使用による CPU 制限の無効化または実行

デフォルトで、ノードは Linux カーネルの Completely Fair Scheduler (CFS) クォータのサポートを使用して、指定された CPU 制限を実行します。

CPU 制限の適用を無効にする場合、それがノードに与える影響を理解しておくことが重要になります。

  • コンテナーに CPU 要求がある場合、これは Linux カーネルの CFS 共有によって引き続き適用されます。
  • コンテナーに CPU 要求がなく、CPU 制限がある場合は、CPU 要求はデフォルトで指定される CPU 制限に設定され、Linux カーネルの CFS 共有によって適用されます。
  • コンテナーに CPU 要求と制限の両方がある場合、CPU 要求は Linux カーネルの CFS 共有によって適用され、CPU 制限はノードに影響を与えません。

前提条件

  • 次のコマンドを入力して、設定するノードタイプの静的な MachineConfigPool CRD に関連付けられたラベルを取得します。

    $ oc edit machineconfigpool <name>

    以下に例を示します。

    $ oc edit machineconfigpool worker

    出力例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      creationTimestamp: "2022-11-16T15:34:25Z"
      generation: 4
      labels:
        pools.operator.machineconfiguration.openshift.io/worker: "" 1
      name: worker

    1
    Labels の下にラベルが表示されます。
    ヒント

    ラベルが存在しない場合は、次のようなキー/値のペアを追加します。

    $ oc label machineconfigpool worker custom-kubelet=small-pods

手順

  1. 設定変更のためのカスタムリソース (CR) を作成します。

    CPU 制限を無効化する設定例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: disable-cpu-units 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 2
      kubeletConfig:
        cpuCfsQuota: false 3

    1
    CR に名前を割り当てます。
    2
    マシン設定プールからラベルを指定します。
    3
    cpuCfsQuota パラメーターを false に設定します。
  2. 以下のコマンドを実行して CR を作成します。

    $ oc create -f <file_name>.yaml
8.5.3.6. システムリソースのリソース予約

より信頼できるスケジューリングを実現し、ノードリソースのオーバーコミットメントを最小化するために、各ノードでは、クラスターが機能できるようノードで実行する必要のあるシステムデーモン用にそのリソースの一部を予約することができます。とくに、メモリーなどの圧縮できないリソースのリソースを予約することが推奨されます。

手順

Pod 以外のプロセスのリソースを明示的に予約するには、スケジューリングで利用可能なリソースを指定することにより、ノードリソースを割り当てます。詳細は、ノードのリソースの割り当てを参照してください。

8.5.3.7. ノードのオーバーコミットの無効化

有効にされているオーバーコミットを、各ノードで無効にできます。

手順

ノード内のオーバーコミットを無効にするには、そのノード上で以下のコマンドを実行します。

$ sysctl -w vm.overcommit_memory=0

8.5.4. プロジェクトレベルの制限

オーバーコミットを制御するには、プロジェクトごとのリソース制限の範囲を設定し、オーバーコミットが超過できないプロジェクトのメモリーおよび CPU 制限およびデフォルト値を指定できます。

プロジェクトレベルのリソース制限の詳細は、関連情報を参照してください。

または、特定のプロジェクトのオーバーコミットを無効にすることもできます。

8.5.4.1. プロジェクトでのオーバーコミットメントの無効化

有効にされているオーバーコミットメントをプロジェクトごとに無効にすることができます。たとえば、インフラストラクチャーコンポーネントはオーバーコミットメントから独立して設定できます。

手順

プロジェクト内のオーバーコミットメントを無効にするには、以下の手順を実行します。

  1. namespace オブジェクトファイルを作成または編集します。
  2. 以下のアノテーションを追加します。

    apiVersion: v1
    kind: Namespace
    metadata:
      annotations:
        quota.openshift.io/cluster-resource-override-enabled: "false" 1
    # ...
    1
    このアノテーションを false に設定すると、この namespace のオーバーコミットが無効になります。

8.5.5. 関連情報

8.6. ノードでの Linux cgroup バージョンの設定

OpenShift Container Platform 4.14 以降、OpenShift Container Platform はクラスター内で Linux コントロールグループバージョン 2 (cgroup v2) を使用します。OpenShift Container Platform 4.13 以前で cgroup v1 を使用している場合、OpenShift Container Platform 4.14 に移行しても、cgroup 設定はバージョン 2 に自動的に更新されません。OpenShift Container Platform 4.14 の新規インストールでは、デフォルトで cgroup v2 が使用されます。ただし、インストール時に Linux コントロールグループバージョン 1 (cgroup v1) を有効にできます。

cgroup v2 は、Linux cgroup API の現行バージョンです。cgroup v2 では、統一された階層、安全なサブツリー委譲、Pressure Stall Information 等の新機能、および強化されたリソース管理および分離など、cgroup v1 に対していくつかの改善が行われています。ただし、cgroup v2 には、cgroup v1 とは異なる CPU、メモリー、および I/O 管理特性があります。したがって、一部のワークロードでは、cgroup v2 を実行するクラスター上のメモリーまたは CPU 使用率にわずかな違いが発生する可能性があります。

必要に応じて、cgroup v1 と cgroup v2 の間で変更できます。OpenShift Container Platform で cgroup v1 を有効にすると、クラスター内のすべての cgroup v2 コントローラーと階層が無効になります。

注記
  • cgroup ファイルシステムに依存するサードパーティーの監視およびセキュリティーエージェントを実行している場合は、エージェントを cgroup v2 をサポートするバージョンに更新します。
  • cgroup v2 を設定し、Pod とコンテナーを監視するスタンドアロンデーモンセットとして cAdvisor を実行している場合は、cAdvisor を v0.43.0 以降に更新します。
  • Java アプリケーションをデプロイする場合は、次のパッケージなど、cgroup v2 を完全にサポートするバージョンを使用してください。

    • OpenJDK/HotSpot: jdk8u372、11.0.16、15 以降
    • NodeJs 20.3.0 以降
    • IBM Semeru ランタイム: jdk8u345-b01、11.0.16.0、17.0.4.0、18.0.2.0 以降
    • IBM SDK Java Technology Edition バージョン (IBM Java): 8.0.7.15 以降

8.6.1. Linux cgroup の設定

node.config オブジェクトを編集して、Linux コントロールグループバージョン 1 (cgroup v1) または Linux コントロールグループバージョン 2 (cgroup v2) を有効にできます。デフォルトは cgroup v2 です。

注記

Telco では、cgroups v2 サポートがないため、低レイテンシー、リアルタイム、および Data Plane Development Kit (DPDK)ワークロードに PerformanceProfile を使用するクラスターは自動的に cgroups v1 に戻ります。PerformanceProfile を使用している場合は、cgroup v2 を有効にすることはできません。

前提条件

  • OpenShift Container Platform クラスター (バージョン 4.12 以降) が実行中。
  • 管理者権限を持つユーザーとしてクラスターにログインしている。

手順

  1. ノードで cgroup v1 を有効にします。

    1. node.config オブジェクトを編集します。

      $ oc edit nodes.config/cluster
    2. spec.cgroupMode パラメーターを編集します。

      node.config オブジェクトの例

      apiVersion: config.openshift.io/v2
      kind: Node
      metadata:
        annotations:
          include.release.openshift.io/ibm-cloud-managed: "true"
          include.release.openshift.io/self-managed-high-availability: "true"
          include.release.openshift.io/single-node-developer: "true"
          release.openshift.io/create-only: "true"
        creationTimestamp: "2022-07-08T16:02:51Z"
        generation: 1
        name: cluster
        ownerReferences:
        - apiVersion: config.openshift.io/v2
          kind: ClusterVersion
          name: version
          uid: 36282574-bf9f-409e-a6cd-3032939293eb
        resourceVersion: "1865"
        uid: 0c0f7a4c-4307-4187-b591-6155695ac85b
      spec:
        cgroupMode: "v1" 1
      ...

      1
      v1 を指定すると、cgroup v1 または cgroup v2 の v2 が有効になります。

検証

  1. マシン設定をチェックして、新しいマシン設定が追加されたことを確認します。

    $ oc get mc

    出力例

    NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
    00-master                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    00-worker                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    97-master-generated-kubelet                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-worker-generated-kubelet                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-ssh                                                                                 3.2.0             40m
    99-worker-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-worker-ssh                                                                                 3.2.0             40m
    rendered-master-23d4317815a5f854bd3553d689cfe2e9   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             10s 1
    rendered-master-23e785de7587df95a4b517e0647e5ab7   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    rendered-worker-5d596d9293ca3ea80c896a1191735bb1   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    rendered-worker-dcc7f1b92892d34db74d6832bcc9ccd4   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             10s

    1
    予想どおり、新しいマシン設定が作成されます。
  2. 新しい kernelArguments が新しいマシン設定に追加されたことを確認します。

    $ oc describe mc <name>

    cgroup v2 の出力例

    apiVersion: machineconfiguration.openshift.io/v2
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker
      name: 05-worker-kernelarg-selinuxpermissive
    spec:
      kernelArguments:
        systemd_unified_cgroup_hierarchy=1 1
        cgroup_no_v1="all" 2
        psi=1 3

    1
    systemd で cgroup v2 を有効にします。
    2
    cgroup v1 を無効にします。
    3
    Linux Pressure Stall Information (PSI) 機能を有効にします。

    cgroup v1 の出力例

    apiVersion: machineconfiguration.openshift.io/v2
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker
      name: 05-worker-kernelarg-selinuxpermissive
    spec:
      kernelArguments:
        systemd.unified_cgroup_hierarchy=0 1
        systemd.legacy_systemd_cgroup_controller=1 2

    1
    cgroup v2 を無効にします。
    2
    systemd で cgroup v1 を有効にします。
  3. ノードをチェックして、ノードのスケジューリングが無効になっていることを確認します。これは、変更が適用されていることを示しています。

    $ oc get nodes

    出力例

    NAME                                       STATUS                     ROLES    AGE   VERSION
    ci-ln-fm1qnwt-72292-99kt6-master-0         Ready,SchedulingDisabled   master   58m   v1.27.3
    ci-ln-fm1qnwt-72292-99kt6-master-1         Ready                      master   58m   v1.27.3
    ci-ln-fm1qnwt-72292-99kt6-master-2         Ready                      master   58m   v1.27.3
    ci-ln-fm1qnwt-72292-99kt6-worker-a-h5gt4   Ready,SchedulingDisabled   worker   48m   v1.27.3
    ci-ln-fm1qnwt-72292-99kt6-worker-b-7vtmd   Ready                      worker   48m   v1.27.3
    ci-ln-fm1qnwt-72292-99kt6-worker-c-rhzkv   Ready                      worker   48m   v1.27.3

  4. ノードが Ready 状態に戻ったら、そのノードのデバッグセッションを開始します。

    $ oc debug node/<node_name>
  5. /host をデバッグシェル内のルートディレクトリーとして設定します。

    sh-4.4# chroot /host
  6. sys/fs/cgroup/cgroup2fs または sys/fs/cgroup/tmpfs ファイルがノードに存在することを確認します。

    $ stat -c %T -f /sys/fs/cgroup

    cgroup v2 の出力例

    cgroup2fs

    cgroup v1 の出力例

    tmpfs

8.7. フィーチャーゲートを使用した機能の有効化

管理者は、フィーチャーゲートを使用して、デフォルトの機能セットに含まれていない機能を有効にすることができます。

8.7.1. フィーチャーゲートについて

FeatureGate カスタムリソース (CR) を使用して、クラスター内の特定の機能セットを有効にすることができます。機能セットは、デフォルトで有効にされない OpenShift Container Platform 機能のコレクションです。

FeatureGate CR を使用して、以下の機能セットをアクティブにすることができます。

  • TechPreviewNoUpgrade.この機能セットは、現在のテクノロジープレビュー機能のサブセットです。この機能セットを使用すると、テストクラスターでこれらのテクノロジープレビュー機能を有効にすることができます。そこでは、これらの機能を完全にテストできますが、運用クラスターでは機能を無効にしたままにできます。

    警告

    クラスターで TechPreviewNoUpgrade 機能セットを有効にすると、元に戻すことができず、マイナーバージョンの更新が妨げられます。本番クラスターでは、この機能セットを有効にしないでください。

    この機能セットにより、以下のテクノロジープレビュー機能が有効になります。

    • 外部クラウドプロバイダー。vSphere、AWS、Azure、GCP 上にあるクラスターの外部クラウドプロバイダーのサポートを有効にします。OpenStack のサポートは GA です。これは内部機能であり、ほとんどのユーザーは操作する必要はありません。(ExternalCloudProvider)
    • OpenShift Builds の共有リソース CSI ドライバー。Container Storage Interface (CSI) を有効にします。(CSIDriverSharedResource)
    • ノード上のスワップメモリー。ノードごとに OpenShift Container Platform ワークロードのスワップメモリーの使用を有効にします。(NodeSwap)
    • OpenStack Machine API プロバイダー。このゲートは効果がなく、今後のリリースでこの機能セットから削除される予定です。(MachineAPIProviderOpenStack)
    • Insights Operator。InsightsDataGather CRD を有効にし、ユーザーがいくつかの Insights データ収集オプションを設定できるようにします。この機能セットにより、DataGather CRD も有効になり、ユーザーがオンデマンドで Insights データ収集を実行できるようになります。(InsightsConfigAPI)
    • Retroactive デフォルトストレージクラス。PVC 作成時にデフォルトのストレージクラスがない場合に、OpenShift Container Platform は PVC に対してデフォルトのストレージクラスを遡及的に割り当てることができます。(RetroactiveDefaultStorageClass)
    • 動的リソース割り当て API。Pod とコンテナー間でリソースを要求および共有するための新しい API が有効になります。これは内部機能であり、ほとんどのユーザーは操作する必要はありません。(DynamicResourceAllocation)
    • Pod セキュリティーアドミッションの適用。Pod セキュリティーアドミッションの制限付き強制モードを有効にします。警告をログに記録するだけでなく、Pod のセキュリティー基準に違反している場合、Pod は拒否されます。(OpenShiftPodSecurityAdmission)
    • StatefulSet Pod の可用性アップグレードの制限。ユーザーは、更新中に使用できないステートフルセット Pod の最大数を定義できるため、アプリケーションのダウンタイムが削減されます。(MaxUnavailableStatefulSet)
    • 管理ネットワークポリシーとベースライン管理ネットワークポリシー。OVN-Kubernetes CNI プラグインを実行しているクラスターで、Network Policy V2 API に含まれる AdminNetworkPolicy リソースと BaselineAdminNetworkPolicy リソースを有効にします。クラスター管理者は、namespace が作成される前に、クラスター範囲のポリシーと保護措置をクラスター全体に適用できます。ネットワーク管理者は、ユーザーが上書きできないネットワークトラフィック制御を強制することで、クラスターを保護できます。ネットワーク管理者は、必要に応じて、クラスター内のユーザーが上書きできる任意のベースラインネットワークトラフィック制御を強制できます。現在、これらの API はクラスター内トラフィックのポリシーの表現のみをサポートしています。(AdminNetworkPolicy)
    • MatchConditions は、この Webhook にリクエストを送信するために満たす必要がある条件のリストです。Match Conditions は、ルール、namespaceSelector、および objectSelector ですでに一致しているリクエストをフィルター処理します。matchConditions の空のリストは、すべてのリクエストに一致します。(admissionWebhookMatchConditions)
    • ゲートウェイ API。OpenShift Container Platform Gateway API を有効にするには、ServiceMeshControlPlane リソース (gateGatewayAPI) の techPreview.gatewayAPI 仕様で、enabled フィールドの値を true に設定します。
    • sigstoreImageVerification
    • gcpLabelsTags
    • vSphereStaticIPs
    • routeExternalCertificate
    • automatedEtcdBackup

TechPreviewNoUpgrade フィーチャーゲートによってアクティブ化される機能の詳細は、次のトピックを参照してください。

8.7.2. インストール時の機能セットの有効化

クラスターをデプロイする前に install-config.yaml ファイルを編集することで、クラスター内のすべてのノードの機能セットを有効にすることができます。

前提条件

  • install-config.yaml ファイルがある。

手順

  1. featureSet パラメーターを使用して、有効にする機能セットの名前 (TechPreviewNoUpgrade など) を指定します。

    警告

    クラスターで TechPreviewNoUpgrade 機能セットを有効にすると、元に戻すことができず、マイナーバージョンの更新が妨げられます。本番クラスターでは、この機能セットを有効にしないでください。

    機能セットが有効になっている install-config.yaml ファイルのサンプル

    compute:
    - hyperthreading: Enabled
      name: worker
      platform:
        aws:
          rootVolume:
            iops: 2000
            size: 500
            type: io1
          metadataService:
            authentication: Optional
          type: c5.4xlarge
          zones:
          - us-west-2c
      replicas: 3
    featureSet: TechPreviewNoUpgrade

  2. ファイルを保存し、インストールプログラムを使用してクラスターをデプロイメントするときに参照します。

検証

ノードが準備完了状態に戻った後、ノード上の kubelet.conf ファイルを確認することで、フィーチャーゲートが有効になっていることを確認できます。

  1. Web コンソールの Administrator パースペクティブで、ComputeNodes に移動します。
  2. ノードを選択します。
  3. Node details ページで Terminal をクリックします。
  4. ターミナルウィンドウで、root ディレクトリーを /host に切り替えます。

    sh-4.2# chroot /host
  5. kubelet.conf ファイルを表示します。

    sh-4.2# cat /etc/kubernetes/kubelet.conf

    出力例

    # ...
    featureGates:
      InsightsOperatorPullingSCA: true,
      LegacyNodeRoleBehavior: false
    # ...

    true として一覧表示されている機能は、クラスターで有効になっています。

    注記

    一覧表示される機能は、OpenShift Container Platform のバージョンによって異なります。

8.7.3. Web コンソールで機能セットの有効化

FeatureGate カスタムリソース (CR) を編集して、OpenShift Container Platform Web コンソールを使用してクラスター内のすべてのノードの機能セットを有効にすることができます。

手順

機能セットを有効にするには、以下を実行します。

  1. OpenShift Container Platform Web コンソールで、AdministrationCustom Resource Definitions ページに切り替えます。
  2. Custom Resource Definitions ページで、FeatureGate をクリックします。
  3. Custom Resource Definition Details ページで、Instances タブをクリックします。
  4. cluster フィーチャーゲートをクリックし、YAML タブをクリックします。
  5. cluster インスタンスを編集して特定の機能セットを追加します。

    警告

    クラスターで TechPreviewNoUpgrade 機能セットを有効にすると、元に戻すことができず、マイナーバージョンの更新が妨げられます。本番クラスターでは、この機能セットを有効にしないでください。

    フィーチャーゲートカスタムリソースのサンプル

    apiVersion: config.openshift.io/v1
    kind: FeatureGate
    metadata:
      name: cluster 1
    # ...
    spec:
      featureSet: TechPreviewNoUpgrade 2

    1
    FeatureGate CR の名前は cluster である必要があります。
    2
    有効にする機能セットを追加します。
    • TechPreviewNoUpgrade は、特定のテクノロジープレビュー機能を有効にします。

    変更を保存すると、新規マシン設定が作成され、マシン設定プールが更新され、変更が適用されている間に各ノードのスケジューリングが無効になります。

検証

ノードが準備完了状態に戻った後、ノード上の kubelet.conf ファイルを確認することで、フィーチャーゲートが有効になっていることを確認できます。

  1. Web コンソールの Administrator パースペクティブで、ComputeNodes に移動します。
  2. ノードを選択します。
  3. Node details ページで Terminal をクリックします。
  4. ターミナルウィンドウで、root ディレクトリーを /host に切り替えます。

    sh-4.2# chroot /host
  5. kubelet.conf ファイルを表示します。

    sh-4.2# cat /etc/kubernetes/kubelet.conf

    出力例

    # ...
    featureGates:
      InsightsOperatorPullingSCA: true,
      LegacyNodeRoleBehavior: false
    # ...

    true として一覧表示されている機能は、クラスターで有効になっています。

    注記

    一覧表示される機能は、OpenShift Container Platform のバージョンによって異なります。

8.7.4. CLI を使用した機能セットの有効化

FeatureGate カスタムリソース (CR) を編集し、OpenShift CLI (oc) を使用してクラスター内のすべてのノードの機能セットを有効にすることができます。

前提条件

  • OpenShift CLI (oc) がインストールされている。

手順

機能セットを有効にするには、以下を実行します。

  1. cluster という名前の FeatureGate CR を編集します。

    $ oc edit featuregate cluster
    警告

    クラスターで TechPreviewNoUpgrade 機能セットを有効にすると、元に戻すことができず、マイナーバージョンの更新が妨げられます。本番クラスターでは、この機能セットを有効にしないでください。

    FeatureGate カスタムリソースのサンプル

    apiVersion: config.openshift.io/v1
    kind: FeatureGate
    metadata:
      name: cluster 1
    # ...
    spec:
      featureSet: TechPreviewNoUpgrade 2

    1
    FeatureGate CR の名前は cluster である必要があります。
    2
    有効にする機能セットを追加します。
    • TechPreviewNoUpgrade は、特定のテクノロジープレビュー機能を有効にします。

    変更を保存すると、新規マシン設定が作成され、マシン設定プールが更新され、変更が適用されている間に各ノードのスケジューリングが無効になります。

検証

ノードが準備完了状態に戻った後、ノード上の kubelet.conf ファイルを確認することで、フィーチャーゲートが有効になっていることを確認できます。

  1. Web コンソールの Administrator パースペクティブで、ComputeNodes に移動します。
  2. ノードを選択します。
  3. Node details ページで Terminal をクリックします。
  4. ターミナルウィンドウで、root ディレクトリーを /host に切り替えます。

    sh-4.2# chroot /host
  5. kubelet.conf ファイルを表示します。

    sh-4.2# cat /etc/kubernetes/kubelet.conf

    出力例

    # ...
    featureGates:
      InsightsOperatorPullingSCA: true,
      LegacyNodeRoleBehavior: false
    # ...

    true として一覧表示されている機能は、クラスターで有効になっています。

    注記

    一覧表示される機能は、OpenShift Container Platform のバージョンによって異なります。

8.8. ワーカーレイテンシープロファイルを使用したレイテンシーの高い環境でのクラスターの安定性の向上

クラスター管理者が遅延テストを実行してプラットフォームを検証した際に、遅延が大きい場合でも安定性を確保するために、クラスターの動作を調整する必要性が判明することがあります。クラスター管理者が変更する必要があるのは、ファイルに記録されている 1 つのパラメーターだけです。このパラメーターは、監視プロセスがステータスを読み取り、クラスターの健全性を解釈する方法に影響を与える 4 つのパラメーターを制御するものです。1 つのパラメーターのみを変更し、サポートしやすく簡単な方法でクラスターをチューニングできます。

Kubelet プロセスは、クラスターの健全性を監視する上での出発点です。Kubelet は、OpenShift Container Platform クラスター内のすべてのノードのステータス値を設定します。Kubernetes コントローラーマネージャー (kube controller) は、デフォルトで 10 秒ごとにステータス値を読み取ります。ノードのステータス値を読み取ることができない場合、設定期間が経過すると、kube controller とそのノードとの接続が失われます。デフォルトの動作は次のとおりです。

  1. コントロールプレーン上のノードコントローラーが、ノードの健全性を Unhealthy に更新し、ノードの Ready 状態を `Unknown` とマークします。
  2. この操作に応じて、スケジューラーはそのノードへの Pod のスケジューリングを停止します。
  3. ノードライフサイクルコントローラーが、NoExecute effect を持つ node.kubernetes.io/unreachable taint をノードに追加し、デフォルトでノード上のすべての Pod を 5 分後にエビクトするようにスケジュールします。

この動作は、ネットワークが遅延の問題を起こしやすい場合、特にネットワークエッジにノードがある場合に問題が発生する可能性があります。場合によっては、ネットワークの遅延が原因で、Kubernetes コントローラーマネージャーが正常なノードから更新を受信できないことがあります。Kubelet は、ノードが正常であっても、ノードから Pod を削除します。

この問題を回避するには、ワーカーレイテンシープロファイル を使用して、Kubelet と Kubernetes コントローラーマネージャーがアクションを実行する前にステータスの更新を待機する頻度を調整できます。これらの調整により、コントロールプレーンとワーカーノード間のネットワーク遅延が最適でない場合に、クラスターが適切に動作するようになります。

これらのワーカーレイテンシープロファイルには、3 つのパラメーターセットが含まれています。パラメーターは、遅延の増加に対するクラスターの反応を制御するように、慎重に調整された値で事前定義されています。試験により手作業で最良の値を見つける必要はありません。

クラスターのインストール時、またはクラスターネットワークのレイテンシーの増加に気付いたときはいつでも、ワーカーレイテンシープロファイルを設定できます。

8.8.1. ワーカーレイテンシープロファイルについて

ワーカーレイテンシープロファイルは、4 つの異なるカテゴリーからなる慎重に調整されたパラメーターです。これらの値を実装する 4 つのパラメーターは、node-status-update-frequencynode-monitor-grace-perioddefault-not-ready-toleration-seconds、および default-unreachable-toleration-seconds です。これらのパラメーターにより、遅延の問題に対するクラスターの反応を制御できる値を使用できます。手作業で最適な値を決定する必要はありません。

重要

これらのパラメーターの手動設定はサポートされていません。パラメーター設定が正しくないと、クラスターの安定性に悪影響が及びます。

すべてのワーカーレイテンシープロファイルは、次のパラメーターを設定します。

node-status-update-frequency
kubelet がノードのステータスを API サーバーにポストする頻度を指定します。
node-monitor-grace-period
Kubernetes コントローラーマネージャーが、ノードを異常とマークし、node.kubernetes.io/not-ready または node.kubernetes.io/unreachable taint をノードに追加する前に、kubelet からの更新を待機する時間を秒単位で指定します。
default-not-ready-toleration-seconds
ノードを異常とマークした後、Kube API Server Operator がそのノードから Pod を削除するまでに待機する時間を秒単位で指定します。
default-unreachable-toleration-seconds
ノードを到達不能とマークした後、Kube API Server Operator がそのノードから Pod を削除するまでに待機する時間を秒単位で指定します。

次の Operator は、ワーカーレイテンシープロファイルの変更を監視し、それに応じて対応します。

  • Machine Config Operator (MCO) は、ワーカーノードの node-status-update-frequency パラメーターを更新します。
  • Kubernetes コントローラーマネージャーは、コントロールプレーンノードの node-monitor-grace-period パラメーターを更新します。
  • Kubernetes API Server Operator は、コントロールプレーンノードの default-not-ready-toleration-seconds および default-unreachable-toleration-seconds パラメーターを更新します。

ほとんどの場合はデフォルト設定が機能しますが、OpenShift Container Platform は、ネットワークで通常よりも高いレイテンシーが発生している状況に対して、他に 2 つのワーカーレイテンシープロファイルを提供します。次のセクションでは、3 つのワーカーレイテンシープロファイルを説明します。

デフォルトのワーカーレイテンシープロファイル

Default プロファイルを使用すると、各 Kubelet が 10 秒ごとにステータスを更新します (node-status-update-frequency)。Kube Controller Manager は、Kubelet のステータスを 5 秒ごとにチェックします (node-monitor-grace-period)。

Kubernetes コントローラーマネージャーは、Kubelet が異常であると判断するまでに、Kubelet からのステータス更新を 40 秒待機します。ステータスが提供されない場合、Kubernetes コントローラーマネージャーは、ノードに node.kubernetes.io/not-ready または node.kubernetes.io/unreachable taint のマークを付け、そのノードの Pod を削除します。

そのノードの Pod に NoExecute taint がある場合、その Pod は tolerationSeconds に従って実行されます。Pod に taint がない場合、その Pod は 300 秒以内に削除されます (Kube API Serverdefault-not-ready-toleration-seconds および default-unreachable-toleration-seconds 設定)。

プロファイルコンポーネントパラメーター

デフォルト

kubelet

node-status-update-frequency

10s

Kubelet コントローラーマネージャー

node-monitor-grace-period

40s

Kubernetes API Server Operator

default-not-ready-toleration-seconds

300s

Kubernetes API Server Operator

default-unreachable-toleration-seconds

300s

中規模のワーカーレイテンシープロファイル

ネットワークレイテンシーが通常の場合、MediumUpdateAverageReaction プロファイルを使用します。

MediumUpdateAverageReaction プロファイルは、kubelet の更新の頻度を 20 秒に減らし、Kubernetes コントローラーマネージャーがそれらの更新を待機する期間を 2 分に変更します。そのノード上の Pod の Pod 排除期間は 60 秒に短縮されます。Pod に tolerationSeconds パラメーターがある場合、エビクションはそのパラメーターで指定された期間待機します。

Kubernetes コントローラーマネージャーは、ノードが異常であると判断するまでに 2 分間待機します。別の 1 分間でエビクションプロセスが開始されます。

プロファイルコンポーネントパラメーター

MediumUpdateAverageReaction

kubelet

node-status-update-frequency

20s

Kubelet コントローラーマネージャー

node-monitor-grace-period

2m

Kubernetes API Server Operator

default-not-ready-toleration-seconds

60s

Kubernetes API Server Operator

default-unreachable-toleration-seconds

60s

ワーカーの低レイテンシープロファイル

ネットワーク遅延が非常に高い場合は、LowUpdateSlowReaction プロファイルを使用します。

LowUpdateSlowReaction プロファイルは、kubelet の更新頻度を 1 分に減らし、Kubernetes コントローラーマネージャーがそれらの更新を待機する時間を 5 分に変更します。そのノード上の Pod の Pod 排除期間は 60 秒に短縮されます。Pod に tolerationSeconds パラメーターがある場合、エビクションはそのパラメーターで指定された期間待機します。

Kubernetes コントローラーマネージャーは、ノードが異常であると判断するまでに 5 分間待機します。別の 1 分間でエビクションプロセスが開始されます。

プロファイルコンポーネントパラメーター

LowUpdateSlowReaction

kubelet

node-status-update-frequency

1m

Kubelet コントローラーマネージャー

node-monitor-grace-period

5m

Kubernetes API Server Operator

default-not-ready-toleration-seconds

60s

Kubernetes API Server Operator

default-unreachable-toleration-seconds

60s

8.8.2. ワーカーレイテンシープロファイルの使用と変更

ネットワークの遅延に対処するためにワーカー遅延プロファイルを変更するには、node.config オブジェクトを編集してプロファイルの名前を追加します。遅延が増加または減少したときに、いつでもプロファイルを変更できます。

ワーカーレイテンシープロファイルは、一度に 1 つずつ移行する必要があります。たとえば、Default プロファイルから LowUpdateSlowReaction ワーカーレイテンシープロファイルに直接移行することはできません。まず Default ワーカーレイテンシープロファイルから MediumUpdateAverageReaction プロファイルに移行し、次に LowUpdateSlowReaction プロファイルに移行する必要があります。同様に、Default プロファイルに戻る場合は、まずロープロファイルからミディアムプロファイルに移行し、次に Default に移行する必要があります。

注記

OpenShift Container Platform クラスターのインストール時にワーカーレイテンシープロファイルを設定することもできます。

手順

デフォルトのワーカーレイテンシープロファイルから移動するには、以下を実行します。

  1. 中規模のワーカーのレイテンシープロファイルに移動します。

    1. node.config オブジェクトを編集します。

      $ oc edit nodes.config/cluster
    2. spec.workerLatencyProfile: MediumUpdateAverageReaction を追加します。

      node.config オブジェクトの例

      apiVersion: config.openshift.io/v1
      kind: Node
      metadata:
        annotations:
          include.release.openshift.io/ibm-cloud-managed: "true"
          include.release.openshift.io/self-managed-high-availability: "true"
          include.release.openshift.io/single-node-developer: "true"
          release.openshift.io/create-only: "true"
        creationTimestamp: "2022-07-08T16:02:51Z"
        generation: 1
        name: cluster
        ownerReferences:
        - apiVersion: config.openshift.io/v1
          kind: ClusterVersion
          name: version
          uid: 36282574-bf9f-409e-a6cd-3032939293eb
        resourceVersion: "1865"
        uid: 0c0f7a4c-4307-4187-b591-6155695ac85b
      spec:
        workerLatencyProfile: MediumUpdateAverageReaction 1
      
      # ...

      1
      中規模のワーカーレイテンシーポリシーを指定します。

      変更が適用されると、各ワーカーノードでのスケジューリングは無効になります。

  2. 必要に応じて、ワーカーのレイテンシーが低いプロファイルに移動します。

    1. node.config オブジェクトを編集します。

      $ oc edit nodes.config/cluster
    2. spec.workerLatencyProfile の値を LowUpdateSlowReaction に変更します。

      node.config オブジェクトの例

      apiVersion: config.openshift.io/v1
      kind: Node
      metadata:
        annotations:
          include.release.openshift.io/ibm-cloud-managed: "true"
          include.release.openshift.io/self-managed-high-availability: "true"
          include.release.openshift.io/single-node-developer: "true"
          release.openshift.io/create-only: "true"
        creationTimestamp: "2022-07-08T16:02:51Z"
        generation: 1
        name: cluster
        ownerReferences:
        - apiVersion: config.openshift.io/v1
          kind: ClusterVersion
          name: version
          uid: 36282574-bf9f-409e-a6cd-3032939293eb
        resourceVersion: "1865"
        uid: 0c0f7a4c-4307-4187-b591-6155695ac85b
      spec:
        workerLatencyProfile: LowUpdateSlowReaction 1
      
      # ...

      1
      低ワーカーレイテンシーポリシーの使用を指定します。

変更が適用されると、各ワーカーノードでのスケジューリングは無効になります。

検証

  • 全ノードが Ready 状態に戻ると、以下のコマンドを使用して Kubernetes Controller Manager を確認し、これが適用されていることを確認できます。

    $ oc get KubeControllerManager -o yaml | grep -i workerlatency -A 5 -B 5

    出力例

    # ...
        - lastTransitionTime: "2022-07-11T19:47:10Z"
          reason: ProfileUpdated
          status: "False"
          type: WorkerLatencyProfileProgressing
        - lastTransitionTime: "2022-07-11T19:47:10Z" 1
          message: all static pod revision(s) have updated latency profile
          reason: ProfileUpdated
          status: "True"
          type: WorkerLatencyProfileComplete
        - lastTransitionTime: "2022-07-11T19:20:11Z"
          reason: AsExpected
          status: "False"
          type: WorkerLatencyProfileDegraded
        - lastTransitionTime: "2022-07-11T19:20:36Z"
          status: "False"
    # ...

    1
    プロファイルが適用され、アクティブであることを指定します。

ミディアムプロファイルからデフォルト、またはデフォルトからミディアムに変更する場合、node.config オブジェクトを編集し、spec.workerLatencyProfile パラメーターを適切な値に設定します。

第9章 ネットワークエッジ上にあるリモートワーカーノード

9.1. ネットワークエッジでのリモートワーカーノードの使用

ネットワークエッジにあるノードで OpenShift Container Platform クラスターを設定できます。このトピックでは、リモートワーカーノード と呼ばれます。リモートワーカーノードを含む通常のクラスターは、オンプレミスのマスターとワーカーノードを、クラスターに接続する他の場所にあるワーカーノードと統合します。このトピックは、リモートワーカーノードの使用のベストプラクティスに関するガイダンスを提供することを目的としており、特定の設定に関する詳細情報は含まれません。

リモートワーカーノードでのデプロイメントパターンの使用に関しては、さまざまな業界 (通信、小売、製造、政府など) で複数のユースケースがあります。たとえば、リモートワーカーノードを Kubernetes ゾーン に結合することで、プロジェクトとワークロードを分離して分離できます。

ただし、リモートワーカーノードを使用すると、高いレイテンシーの発生や、ネットワーク接続が断続的に失われるなどの問題が発生する可能性があります。リモートワーカーノードを含むクラスターの課題には、以下のようなものがあります。

  • ネットワーク分離: OpenShift Container Platform コントロールプレーンとリモートワーカーノードは、相互に通信できる必要があります。コントロールプレーンとリモートワーカーノードの間に距離があるため、ネットワークの問題が発生すると、この通信が妨げられる可能性があります。OpenShift Container Platform がネットワークの分離にどのように対応するか、およびクラスターへの影響を軽減する方法は、リモートワーカーノードを使用したネットワークの分離 を参照してください。
  • 停電: コントロールプレーンとリモートワーカーノードは別々の場所にあるため、リモートの場所での停電、またはそれぞれの場所からの任意の場所での停電により、クラスターに悪影響を及ぼす可能性があります。ノードの電力損失に OpenShift Container Platform がどのように対応するか、およびクラスターへの影響を軽減する方法は、リモートワーカーノードの電力損失 を参照してください。
  • 急激な高レイテンシーまたは一時的なスループットの低下: ネットワークの場合と同様に、クラスターとリモートワーカーノード間のネットワーク状態の変更は、クラスターに悪影響を及ぼす可能性があります。OpenShift Container Platform は、レイテンシーの問題に対するクラスターの反応を制御できる複数の ワーカーレイテンシープロファイル を提供します。

リモートワーカーノードを含むクラスターを計画する場合には、以下の制限に注意してください。

  • OpenShift Container Platform は、オンプレミスクラスターが使用するクラウドプロバイダー以外のクラウドプロバイダーを使用するリモートワーカーノードをサポートしません。
  • ワークロードを 1 つの Kubernetes ゾーンから別の Kubernetes ゾーンに移動すると、(特定のタイプのメモリーが異なるゾーンで利用できないなどの) システムや環境に関する課題により、問題が発生する可能性があります。
  • プロキシーおよびファイアウォールでは、このドキュメントでは扱われていない追加的制限が出てくる可能性があります。このような制限に対処する方法は、ファイアウォールの設定 など、関連する OpenShift Container Platform ドキュメントを参照してください。
  • コントロールプレーンとネットワークエッジノード間の L2/L3 レベルのネットワーク接続を設定および維持する必要があります。

9.1.1. リモートワーカーノードの追加

リモートワーカーノードをクラスターに追加するには、追加の考慮事項がいくつかあります。

  • コントロールプレーンとすべてのリモートワーカーノードの間でトラフィックをルーティングするには、ルートまたはデフォルトゲートウェイが配置されていることを確認する必要があります。
  • Ingress VIP をコントロールプレーンに配置する必要があります。
  • user-provisioned infrastructure (UPI) を使用してリモートワーカーノードを追加することは、他のワーカーノードを追加することと同じです。
  • インストール時にインストーラーがプロビジョニングしたクラスターにリモートワーカーノードを追加するには、インストール前に install-config.yaml ファイルで各ワーカーノードのサブネットを指定します。DHCP サーバーに追加の設定は必要ありません。リモートワーカーノードはローカルプロビジョニングネットワークにアクセスできないため、仮想メディアを使用する必要があります。
  • プロビジョニングネットワークでデプロイされたインストーラーでプロビジョニングされたクラスターにリモートワーカーノードを追加するには、仮想メディアを使用してノードを追加するように、install-config.yaml ファイルで virtualMediaViaExternalNetwork フラグが true に設定されていることを確認します。リモートワーカーノードは、ローカルプロビジョニングネットワークにアクセスできません。PXE ではなく、仮想メディアを使用してデプロイする必要があります。さらに、DHCP サーバー内のリモートワーカーノードの各グループとコントロールプレーンノードの各サブネットを指定します。

9.1.2. リモートワーカーノードによるネットワーク分離

すべてのノードは、10 秒ごとに OpenShift Container Platform クラスターの Kubernetes Controller Manager Operator (kube コントローラー) にハートビートを送信します。クラスターがノードからハートビートを受信しない場合、OpenShift Container Platform は複数のデフォルトメカニズムを使用して応答します。

OpenShift Container Platform は、ネットワークパーティションやその他の中断に対して回復性を持たせるように設計されています。ソフトウェアのアップグレードの中断、ネットワーク分割、ルーティングの問題など、より一般的な中断の一部を軽減することができます。軽減策には、リモートワーカーノードの Pod が正しい CPU およびメモリーリソースの量を要求すること、適切なレプリケーションポリシーの設定、ゾーン間の冗長性の使用、ワークロードでの Pod の Disruption Budget の使用などが含まれます。

設定した期間後に kube コントローラーのノードとの接続が解除された場合、コントロールプレーンのノードコントローラーはノードの正常性を Unhealthy に更新し、ノードの Ready 状態を Unknown とマークします。この操作に応じて、スケジューラーはそのノードへの Pod のスケジューリングを停止します。オンプレミスノードコントローラーは、effect が NoExecutenode.kubernetes.io/unreachable taint をノードに追加し、デフォルトで 5 分後に、エビクション用にノード上で Pod をスケジュールします。

Deployment オブジェクト、または StatefulSet オブジェクトなどのワークロードコントローラーが、正常でないノードの Pod にトラフィックを転送し、他のノードがクラスターに到達できる場合、OpenShift Container Platform はトラフィックをノードの Pod から遠ざけます。クラスターに到達できないノードは、新しいトラフィックルーティングでは更新されません。その結果、それらのノードのワークロードは、正常でないノードに到達しようとします。

以下の方法で接続損失の影響を軽減できます。

  • デーモンセットを使用した taint を容認する Pod の作成
  • ノードがダウンした場合に自動的に再起動する静的 Pod の使用
  • Kubernetes ゾーンを使用した Pod エビクションの制御
  • Pod のエビクションを遅延または回避するための Pod toleration の構成
  • ノードを正常でないとマークするタイミングを制御するように kubelet を設定します。

リモートワーカーノードを含むクラスターでこれらのオブジェクトを使用する方法の詳細は、リモートワーカーノードの戦略について を参照してください。

9.1.3. リモートワーカーノードの電源損失

リモートワーカーノードの電源がなくなったり、強制的な再起動を行う場合、OpenShift Container Platform は複数のデフォルトメカニズムを使用して応答します。

設定した期間後に Kubernetes Controller Manager Operator (kube コントローラー) のノードとの接続が解除された場合、コントロールプレーンはノードの正常性を Unhealthy に更新し、ノードの Ready 状態を Unknown とマークします。この操作に応じて、スケジューラーはそのノードへの Pod のスケジューリングを停止します。オンプレミスノードコントローラーは、effect が NoExecutenode.kubernetes.io/unreachable taint をノードに追加し、デフォルトで 5 分後に、エビクション用にノード上で Pod をスケジュールします。

ノードでは、ノードが電源を回復し、コントロールプレーンに再接続する際に、Pod を再起動する必要があります。

注記

再起動時に Pod をすぐに再起動する必要がある場合は、静的 Pod を使用します。

ノードの再起動後に kubelet も再起動し、ノードにスケジュールされた Pod の再起動を試行します。コントロールプレーンへの接続にデフォルトの 5 分よりも長い時間がかかる場合、コントロールプレーンはノードの正常性を更新して node.kubernetes.io/unreachable taint を削除することができません。ノードで、kubelet は実行中の Pod をすべて終了します。これらの条件がクリアされると、スケジューラーはそのノードへの Pod のスケジューリングを開始できます。

以下の方法で、電源損失の影響を軽減できます。

  • デーモンセットを使用した taint を容認する Pod の作成
  • ノードを使用して自動的に再起動する静的 Pod の使用
  • Pod のエビクションを遅延または回避するための Pod toleration の構成
  • ノードコントローラーがノードを正常でないとマークするタイミングを制御するための kubelet の設定

リモートワーカーノードを含むクラスターでこれらのオブジェクトを使用する方法の詳細は、リモートワーカーノードの戦略について を参照してください。

9.1.4. リモートワーカーへのレイテンシーの急上昇またはスループットの一時的な低下

クラスター管理者が遅延テストを実行してプラットフォームを検証した際に、遅延が大きい場合でも安定性を確保するために、クラスターの動作を調整する必要性が判明することがあります。クラスター管理者が変更する必要があるのは、ファイルに記録されている 1 つのパラメーターだけです。このパラメーターは、監視プロセスがステータスを読み取り、クラスターの健全性を解釈する方法に影響を与える 4 つのパラメーターを制御するものです。1 つのパラメーターのみを変更し、サポートしやすく簡単な方法でクラスターをチューニングできます。

Kubelet プロセスは、クラスターの健全性を監視する上での出発点です。Kubelet は、OpenShift Container Platform クラスター内のすべてのノードのステータス値を設定します。Kubernetes コントローラーマネージャー (kube controller) は、デフォルトで 10 秒ごとにステータス値を読み取ります。ノードのステータス値を読み取ることができない場合、設定期間が経過すると、kube controller とそのノードとの接続が失われます。デフォルトの動作は次のとおりです。

  1. コントロールプレーン上のノードコントローラーが、ノードの健全性を Unhealthy に更新し、ノードの Ready 状態を `Unknown` とマークします。
  2. この操作に応じて、スケジューラーはそのノードへの Pod のスケジューリングを停止します。
  3. ノードライフサイクルコントローラーが、NoExecute effect を持つ node.kubernetes.io/unreachable taint をノードに追加し、デフォルトでノード上のすべての Pod を 5 分後にエビクトするようにスケジュールします。

この動作は、ネットワークが遅延の問題を起こしやすい場合、特にネットワークエッジにノードがある場合に問題が発生する可能性があります。場合によっては、ネットワークの遅延が原因で、Kubernetes コントローラーマネージャーが正常なノードから更新を受信できないことがあります。Kubelet は、ノードが正常であっても、ノードから Pod を削除します。

この問題を回避するには、ワーカーレイテンシープロファイル を使用して、Kubelet と Kubernetes コントローラーマネージャーがアクションを実行する前にステータスの更新を待機する頻度を調整できます。これらの調整により、コントロールプレーンとワーカーノード間のネットワーク遅延が最適でない場合に、クラスターが適切に動作するようになります。

これらのワーカーレイテンシープロファイルには、3 つのパラメーターセットが含まれています。パラメーターは、遅延の増加に対するクラスターの反応を制御するように、慎重に調整された値で事前定義されています。試験により手作業で最良の値を見つける必要はありません。

クラスターのインストール時、またはクラスターネットワークのレイテンシーの増加に気付いたときはいつでも、ワーカーレイテンシープロファイルを設定できます。

9.1.5. リモートワーカーノードストラテジー

リモートワーカーノードを使用する場合は、アプリケーションを実行するために使用するオブジェクトを考慮してください。

ネットワークの問題や電源の損失時に必要とされる動作に基づいて、デーモンセットまたは静的 Pod を使用することが推奨されます。さらに、Kubernetes ゾーンおよび toleration を使用して、コントロールプレーンがリモートワーカーノードに到達できない場合に Pod エビクションを制御したり、回避したりできます。

デーモンセット
デーモンセットは、以下の理由により、リモートワーカーノードでの Pod の管理に最適な方法です。
  • デーモンセットは通常、動作の再スケジュールを必要としません。ノードがクラスターから切断される場合、ノードの Pod は実行を継続できます。OpenShift Container Platform はデーモンセット Pod の状態を変更せず、Pod を最後に報告された状態のままにします。たとえば、デーモンセット Pod が Running 状態の際にノードが通信を停止する場合、Pod は実行し続けますが、これは OpenShift Container Platform によって実行されていることが想定されます。
  • デーモンセット Pod はデフォルトで、tolerationSeconds 値のない node.kubernetes.io/unreachable taint および node.kubernetes.io/not-ready taint の NoExecute toleration で作成されます。これらのデフォルト値により、コントロールプレーンがノードに到達できなくても、デーモンセット Pod がエビクトされることはありません。以下に例を示します。

    デフォルトでデーモンセット Pod に toleration を追加

      tolerations:
        - key: node.kubernetes.io/not-ready
          operator: Exists
          effect: NoExecute
        - key: node.kubernetes.io/unreachable
          operator: Exists
          effect: NoExecute
        - key: node.kubernetes.io/disk-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/memory-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/pid-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/unschedulable
          operator: Exists
          effect: NoSchedule

  • デーモンセットは、ワークロードが一致するワーカーノードで実行されるように、ラベルを使用することができます。
  • OpenShift Container Platform サービスエンドポイントを使用してデーモンセット Pod の負荷を分散できます。
注記

デーモンセットは、OpenShift Container Platform がノードに到達できない場合、ノードの再起動後に Pod をスケジュールしません。

静的 Pod
ノードの再起動時に Pod を再起動する必要がある場合 (電源が切れた場合など)、静的な Pod を考慮してください。ノードの kubelet は、ノードの再起動時に静的 Pod を自動的に再起動します。
注記

静的 Pod はシークレットおよび設定マップを使用できません。

Kubernetes ゾーン
Kubernetes ゾーン は、速度を落としたり、または場合によっては Pod エビクションを完全に停止したりすることができます。

コントロールプレーンがノードに到達できない場合、デフォルトでノードコントローラーは node.kubernetes.io/unreachable taint を適用し、1 秒あたり 0.1 ノードのレートで Pod をエビクトします。ただし、Kubernetes ゾーンを使用するクラスターでは、Pod エビクションの動作が変更されます。

ゾーンのすべてのノードに False または UnknownReady 状態が見られる、ゾーンが完全に中断された状態の場合、コントロールプレーンは node.kubernetes.io/unreachable taint をそのゾーンのノードに適用しません。

(ノードの 55% 超が False または Unknown 状態である) 部分的に中断されたゾーンの場合、Pod のエビクションレートは 1 秒あたり 0.01 ノードに低減されます。50 未満の小規模なクラスターにあるノードに taint は付けられません。これらの動作を有効にするには、クラスターに 4 つ以上のゾーンが必要です。

ノード仕様に topology.kubernetes.io/region ラベルを適用して、ノードを特定のゾーンに割り当てます。

Kubernetes ゾーンのノードラベルの例

kind: Node
apiVersion: v1
metadata:
  labels:
    topology.kubernetes.io/region=east

KubeletConfig オブジェクト

kubelet が各ノードの状態をチェックする時間を調整することができます。

オンプレミスノードコントローラーがノードを Unhealthy または Unreachable 状態にマークするタイミングに影響を与える間隔を設定するには、node-status-update-frequency および node-status-report-frequency パラメーターが含まれる KubeletConfig オブジェクトを作成します。

各ノードの kubelet は node-status-update-frequency 設定で定義されたノードのステータスを判別し、node-status-report-frequency 設定に基づいてそのステータスをクラスターに報告します。デフォルトで、kubelet は 10 秒ごとに Pod のステータスを判別し、毎分ごとにステータスを報告します。ただし、ノードの状態が変更されると、kubelet は変更をクラスターに即時に報告します。OpenShift Container Platform は、Node Lease フィーチャーゲートが有効にされている場合にのみ、node-status-report-frequency 設定を使用します。これは OpenShift Container Platform クラスターのデフォルト状態です。Node Lease フィーチャーゲートが無効になっている場合、ノードは node-status-update-frequency 設定に基づいてノードのステータスを報告します。

kubelet 設定の例

apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
  name: disable-cpu-units
spec:
  machineConfigPoolSelector:
    matchLabels:
      machineconfiguration.openshift.io/role: worker 1
  kubeletConfig:
    node-status-update-frequency: 2
      - "10s"
    node-status-report-frequency: 3
      - "1m"

1
MachineConfig オブジェクトのラベルを使用して、この KubeletConfig オブジェクトが適用されるノードタイプを指定します。
2
kubelet がこの MachineConfig オブジェクトに関連付けられたノードのステータスをチェックする頻度を指定します。デフォルト値は 10s です。このデフォルト値を変更すると、node-status-report-frequency の値は同じ値に変更されます。
3
kubelet がこの MachineConfig オブジェクトに関連付けられたノードのステータスを報告する頻度を指定します。デフォルト値は 1m です。

node-status-update-frequency パラメーターは、node-monitor-grace-period パラメーターと連携して機能します。

  • node-monitor-grace-period パラメーターは、コントローラーマネージャーがハートビートを受信しない場合に、この MachineConfig オブジェクトに関連付けられたノードが Unhealthy とマークされた後に、OpenShift Container Platform が待機する時間を指定します。この待機時間後も、ノード上のワークロードは引き続き実行されます。node-monitor-grace-period の期限が切れた後にリモートワーカーノードがクラスターに再度加わる場合、Pod は実行を継続します。新規 Pod をノードにスケジュールできます。node-monitor-grace-period の間隔は 40s です。node-status-update-frequency の値は、node-monitor-grace-period の値よりも低い値である必要があります。
注記

node-monitor-grace-period パラメーターを変更することはサポートされていません。

Tolerations
オンプレミスノードコントローラーが、effect が NoExecutenode.kubernetes.io/unreachable taint を到達できないノードに追加する場合、Pod toleration を使用して effect を軽減することができます。

effect が NoExecute の taint は、ノードですでに実行中の Pod に以下のような影響を及ぼします。

  • taint を容認しない Pod は、エビクションのキューに置かれます。
  • toleration の仕様に tolerationSeconds 値を指定せずに taint を容認する Pod は、永久にバインドされたままになります。
  • 指定された tolerationSeconds 値で taint を容認する Pod は、指定された期間バインドされます。時間が経過すると、Pod はエビクションのキューに置かれます。
注記

許容範囲が明示的に設定されていない限り、Kubernetes は tolerationSeconds=300 を使用して、node.kubernetes.io/not-ready および node.kubernetes.io/unreachable に対する許容範囲を自動的に追加します。これは、これらの taint のいずれかが検出された場合、Pod は 5 分間バインドされたままになることを意味します。

effect が NoExecutenode.kubernetes.io/unreachable taint および node.kubernetes.io/not-ready taint で Pod の toleration を設定し、Pod のエビクションを遅延したり回避したりできます。

Pod 仕様での toleration の例

...
tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute" 1
- key: "node.kubernetes.io/not-ready"
  operator: "Exists"
  effect: "NoExecute" 2
  tolerationSeconds: 600 3
...

1
tolerationSeconds のない NoExecute effect により、コントロールプレーンがノードに到達する場合は Pod が永続的に残ります。
2
tolerationSeconds: 600 の NoExecute effect により、コントロールプレーンがノードに Unhealthy のマークを付ける場合に Pod が 10 分間そのまま残ります。
3
独自の tolerationSeconds 値を指定できます。
OpenShift Container Platform オブジェクトの他のタイプ
レプリカセット、デプロイメント、およびレプリケーションコントローラーを使用できます。スケジューラーは、ノードが 5 分間切断された後、これらの Pod を他のノードに再スケジュールできます。他のノードへの再スケジュールは、管理者が特定数の Pod を確実に実行し、アクセスできるようにする REST API などの一部のワークロードにとって有益です。
注記

リモートワーカーノードを使用する際に、リモートワーカーノードが特定の機能用に予約されることが意図されている場合、異なるノードでの Pod の再スケジュールは許容されない可能性があります。

ステートフルセット は、停止時に再起動されません。Pod は、コントロールプレーンが Pod の終了を認識できるまで、terminating 状態のままになります。

同じタイプの永続ストレージにアクセスできないノードにスケジュールしないようにするため、OpenShift Container Platform では、ネットワークの分離時に永続ボリュームを必要とする Pod を他のゾーンに移行することはできません。

関連情報

第10章 シングルノード OpenShift クラスター用のワーカーノード

10.1. 単一ノードの OpenShift クラスターへのワーカーノードの追加

単一ノードの OpenShift クラスターは、単一ホストへのデプロイメントのホスト前提条件を減らします。これは、制約のある環境またはネットワークエッジでのデプロイメントに役立ちます。ただし、通信やネットワークエッジのシナリオなどでは、クラスターに容量を追加する必要がある場合があります。これらのシナリオでは、ワーカーノードを単一ノードクラスターに追加できます。

注記

マルチノードクラスターとは異なり、ワーカーノードを追加した後でも、デフォルトではすべての ingress トラフィックが単一のコントロールプレーンノードにルーティングされます。

単一ノードクラスターにワーカーノードを追加するには、いくつかの方法があります。Red Hat OpenShift Cluster Manager を使用するか、Assisted Installer REST API を直接使用して、クラスターにワーカーノードを手動で追加できます。

重要

ワーカーノードを追加してもクラスターコントロールプレーンは拡張されず、クラスターに高可用性は提供されません。単一ノードの OpenShift クラスターの場合、高可用性は別のサイトにフェイルオーバーすることによって処理されます。単一ノードの OpenShift クラスターにワーカーノードを追加する場合は、テスト済みの最大 2 つのワーカーノードを推奨します。推奨されるワーカーノードの数を超えると、クラスター障害など、パフォーマンスが全体的に低下する可能性があります。

注記

ワーカーノードを追加するには、OpenShift Cluster Manager へのアクセス権が必要です。この方法は、エージェントベースのインストーラーを使用して切断された環境にクラスターをインストールする場合にはサポートされません。

10.1.1. 単一ノードの OpenShift ワーカーノードをインストールするための要件

単一ノードの OpenShift ワーカーノードをインストールするには、次の要件に対応する必要があります。

  • 管理ホスト: ISO を準備し、インストールを監視するためのコンピューターが必要です。
  • 実稼働環境グレードサーバー: 単一ノードの OpenShift ワーカーノードをインストールするには、OpenShift Container Platform サービスと実稼働環境ワークロードを実行するのに十分なリソースを備えたサーバーが必要です。

    表10.1 最小リソース要件
    プロファイル仮想 CPUメモリーストレージ

    最低限

    2 vCPU コア

    8GB の RAM

    100GB

    注記

    1 vCPU は、同時マルチスレッド (SMT) またはハイパースレッディングが有効にされていない場合に 1 つの物理コアと同等です。有効にした場合には、次の式を使用して対応する比率を計算します。

    (コアあたりのスレッド数×コア) × ソケット= vCPU

    仮想メディアを使用して起動する場合は、サーバーには Baseboard Management Controller (BMC) が必要です。

  • ネットワーク: ワーカーノードサーバーは、ルーティング可能なネットワークに接続されていない場合、インターネットまたはローカルレジストリーにアクセスできる必要があります。ワーカーノードサーバーには、DHCP 予約または静的 IP アドレスが必要であり、単一ノードの OpenShift クラスター Kubernetes API、ingress ルート、およびクラスターノードのドメイン名にアクセスできる必要があります。単一ノードの OpenShift クラスターの次の完全修飾ドメイン名 (FQDN) のそれぞれに IP アドレスを解決するように DNS を設定する必要があります。

    表10.2 必要な DNS レコード
    使用法FQDN説明

    Kubernetes API

    api.<cluster_name>.<base_domain>

    DNS A/AAAA または CNAME レコードを追加します。このレコードは、クラスター外のクライアントで解決できる必要があります。

    内部 API

    api-int.<cluster_name>.<base_domain>

    ISO を手動で作成する場合は、DNS A/AAAA または CNAME レコードを追加します。このレコードは、クラスター内のノードによって解決できる必要があります。

    Ingress ルート

    *.apps.<cluster_name>.<base_domain>

    ノードをターゲットにするワイルドカード DNS A/AAAA または CNAME レコードを追加します。このレコードは、クラスター外のクライアントで解決できる必要があります。

    永続的な IP アドレスがない場合、apiserveretcd の間の通信で失敗する可能性があります。

10.1.2. Assisted Installer および OpenShift Cluster Manager を使用したワーカーノードの追加

Assisted Installer を使用して、Red Hat OpenShift Cluster Manager で作成された単一ノードの OpenShift クラスターにワーカーノードを追加できます。

重要

単一ノードの OpenShift クラスターへのワーカーノードの追加は、OpenShift Container Platform バージョン 4.11 以降を実行しているクラスターに対してのみサポートされます。

前提条件

  • Assisted Installer を使用してインストールされた単一ノードの OpenShift クラスターにアクセスできる。
  • OpenShift CLI (oc) がインストールされている。
  • cluster-admin 権限を持つユーザーとしてログインしている。
  • ワーカーノードを追加するクラスターに必要なすべての DNS レコードが存在することを確認してください。

手順

  1. OpenShift Cluster Manager にログインし、ワーカーノードを追加する単一ノードクラスターをクリックします。
  2. Add hosts をクリックし、新しいワーカーノードの検出 ISO をダウンロードして、必要に応じて SSH 公開キーを追加し、クラスター全体のプロキシー設定を設定します。
  3. 検出 ISO を使用してターゲットホストを起動し、ホストがコンソールで検出されるまで待ちます。ホストが検出されたら、インストールを開始します。
  4. インストールが進行するにつれて、インストールはワーカーノードの保留中の証明書署名要求 (CSR) を生成します。プロンプトが表示されたら、保留中の CSR を承認してインストールを完了します。

    ワーカーノードが正常にインストールされると、クラスター Web コンソールにワーカーノードとして一覧表示されます。

重要

新しいワーカーノードは、元のクラスターと同じ方法を使用して暗号化されます。

10.1.3. Assisted Installer API を使用したワーカーノードの追加

Assisted Installer REST API を使用して、単一ノードの OpenShift クラスターにワーカーノードを追加できます。ワーカーノードを追加する前に、OpenShift Cluster Manager にログインし、API に対して認証する必要があります。

10.1.3.1. Assisted Installer REST API に対する認証

Assisted Installer REST API を使用する前に、生成した JSON Web トークン (JWT) を使用して API に対して認証する必要があります。

前提条件

  • クラスター作成権限を持つユーザーで OpenShift Cluster Manager にログインする。
  • jq をインストールします。

手順

  1. OpenShift Cluster Manager にログインし、API トークンをコピーします。
  2. 次のコマンドを実行して、コピーした API トークンを使用して $OFFLINE_TOKEN 変数を設定します。

    $ export OFFLINE_TOKEN=<copied_api_token>
  3. 以前に設定した $OFFLINE_TOKEN 変数を使用して、$JWT_TOKEN 変数を設定します。

    $ export JWT_TOKEN=$(
      curl \
      --silent \
      --header "Accept: application/json" \
      --header "Content-Type: application/x-www-form-urlencoded" \
      --data-urlencode "grant_type=refresh_token" \
      --data-urlencode "client_id=cloud-services" \
      --data-urlencode "refresh_token=${OFFLINE_TOKEN}" \
      "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token" \
      | jq --raw-output ".access_token"
    )
    注記

    JWT トークンは 15 分間のみ有効です。

検証

  • オプション: 次のコマンドを実行して、API にアクセスできることを確認します。

    $ curl -s https://api.openshift.com/api/assisted-install/v2/component-versions -H "Authorization: Bearer ${JWT_TOKEN}" | jq

    出力例

    {
        "release_tag": "v2.5.1",
        "versions":
        {
            "assisted-installer": "registry.redhat.io/rhai-tech-preview/assisted-installer-rhel8:v1.0.0-175",
            "assisted-installer-controller": "registry.redhat.io/rhai-tech-preview/assisted-installer-reporter-rhel8:v1.0.0-223",
            "assisted-installer-service": "quay.io/app-sre/assisted-service:ac87f93",
            "discovery-agent": "registry.redhat.io/rhai-tech-preview/assisted-installer-agent-rhel8:v1.0.0-156"
        }
    }

10.1.3.2. Assisted Installer REST API を使用したワーカーノードの追加

Assisted Installer REST API を使用して、クラスターにワーカーノードを追加できます。

前提条件

  • OpenShift Cluster Manager CLI (ocm) をインストールしている。
  • クラスター作成権限を持つユーザーで OpenShift Cluster Manager にログインする。
  • jq をインストールします。
  • ワーカーノードを追加するクラスターに必要なすべての DNS レコードが存在することを確認してください。

手順

  1. Assisted Installer REST API に対して認証し、セッションの JSON Web トークン (JWT) を生成します。生成された JWT トークンは 15 分間のみ有効です。
  2. 次のコマンドを実行して、$API_URL 変数を設定します。

    $ export API_URL=<api_url> 1
    1
    <api_url> を Assisted Installer API の URL に置き換えます (例: https://api.openshift.com)。
  3. 次のコマンドを実行して、単一ノードの OpenShift クラスターをインポートします。

    1. $OPENSHIFT_CLUSTER_ID 変数を設定します。クラスターにログインし、次のコマンドを実行します。

      $ export OPENSHIFT_CLUSTER_ID=$(oc get clusterversion -o jsonpath='{.items[].spec.clusterID}')
    2. クラスターのインポートに使用される $CLUSTER_REQUEST 変数を設定します。

      $ export CLUSTER_REQUEST=$(jq --null-input --arg openshift_cluster_id "$OPENSHIFT_CLUSTER_ID" '{
        "api_vip_dnsname": "<api_vip>", 1
        "openshift_cluster_id": $openshift_cluster_id,
        "name": "<openshift_cluster_name>" 2
      }')
      1
      <api_vip> をクラスターの API サーバーのホスト名に置き換えます。これは、API サーバーの DNS ドメイン、またはワーカーノードが到達できる単一ノードの IP アドレスになります。たとえば、api.compute-1.example.com です。
      2
      <openshift_cluster_name> をクラスターのプレーンテキスト名に置き換えます。クラスター名は、Day 1 クラスターのインストール中に設定されたクラスター名と一致する必要があります。
    3. クラスターをインポートし、$CLUSTER_ID 変数を設定します。以下のコマンドを実行します。

      $ CLUSTER_ID=$(curl "$API_URL/api/assisted-install/v2/clusters/import" -H "Authorization: Bearer ${JWT_TOKEN}" -H 'accept: application/json' -H 'Content-Type: application/json' \
        -d "$CLUSTER_REQUEST" | tee /dev/stderr | jq -r '.id')
  4. 次のコマンドを実行して、クラスターの InfraEnv リソースを生成し、$INFRA_ENV_ID 変数を設定します。

    1. console.redhat.com の Red Hat OpenShift Cluster Manager からプルシークレットファイルをダウンロードします。
    2. $INFRA_ENV_REQUEST 変数を設定します。

      export INFRA_ENV_REQUEST=$(jq --null-input \
          --slurpfile pull_secret <path_to_pull_secret_file> \1
          --arg ssh_pub_key "$(cat <path_to_ssh_pub_key>)" \2
          --arg cluster_id "$CLUSTER_ID" '{
        "name": "<infraenv_name>", 3
        "pull_secret": $pull_secret[0] | tojson,
        "cluster_id": $cluster_id,
        "ssh_authorized_key": $ssh_pub_key,
        "image_type": "<iso_image_type>" 4
      }')
      1
      <path_to_pull_secret_file> を、console.redhat.com の Red Hat OpenShift Cluster Manager からダウンロードしたプルシークレットを含むローカルファイルへのパスに置き換えます。
      2
      <path_to_ssh_pub_key> を、ホストへのアクセスに必要な公開 SSH キーへのパスに置き換えます。この値を設定しないと、検出モードでホストにアクセスできません。
      3
      <infraenv_name>InfraEnv リソースのプレーンテキスト名に置き換えます。
      4
      <iso_image_type>full-iso または minimal-iso のいずれかの ISO イメージタイプに置き換えます。
    3. $INFRA_ENV_REQUEST/v2/infra-envs API に送信し、$INFRA_ENV_ID 変数を設定します。

      $ INFRA_ENV_ID=$(curl "$API_URL/api/assisted-install/v2/infra-envs" -H "Authorization: Bearer ${JWT_TOKEN}" -H 'accept: application/json' -H 'Content-Type: application/json' -d "$INFRA_ENV_REQUEST" | tee /dev/stderr | jq -r '.id')
  5. 次のコマンドを実行して、クラスターワーカーノードの検出 ISO の URL を取得します。

    $ curl -s "$API_URL/api/assisted-install/v2/infra-envs/$INFRA_ENV_ID" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r '.download_url'

    出力例

    https://api.openshift.com/api/assisted-images/images/41b91e72-c33e-42ee-b80f-b5c5bbf6431a?arch=x86_64&image_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTYwMjYzNzEsInN1YiI6IjQxYjkxZTcyLWMzM2UtNDJlZS1iODBmLWI1YzViYmY2NDMxYSJ9.1EX_VGaMNejMhrAvVRBS7PDPIQtbOOc8LtG8OukE1a4&type=minimal-iso&version=$VERSION

  6. ISO をダウンロードします。

    $ curl -L -s '<iso_url>' --output rhcos-live-minimal.iso 1
    1
    <iso_url> を前の手順の ISO の URL に置き換えます。
  7. ダウンロードした rhcos-live-minimal.iso から新しいワーカーホストを起動します。
  8. インストールされていない クラスター内のホストのリストを取得します。新しいホストが表示されるまで、次のコマンドを実行し続けます。

    $ curl -s "$API_URL/api/assisted-install/v2/clusters/$CLUSTER_ID" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r '.hosts[] | select(.status != "installed").id'

    出力例

    2294ba03-c264-4f11-ac08-2f1bb2f8c296

  9. 新しいワーカーノードの $HOST_ID 変数を設定します。次に例を示します。

    $ HOST_ID=<host_id> 1
    1
    <host_id> を前の手順のホスト ID に置き換えます。
  10. 以下のコマンドを実行して、ホストがインストールできる状態であることを確認します。

    注記

    完全な jq 式を含むコマンド全体をコピーしてください。

    $ curl -s $API_URL/api/assisted-install/v2/clusters/$CLUSTER_ID -H "Authorization: Bearer ${JWT_TOKEN}" | jq '
    def host_name($host):
        if (.suggested_hostname // "") == "" then
            if (.inventory // "") == "" then
                "Unknown hostname, please wait"
            else
                .inventory | fromjson | .hostname
            end
        else
            .suggested_hostname
        end;
    
    def is_notable($validation):
        ["failure", "pending", "error"] | any(. == $validation.status);
    
    def notable_validations($validations_info):
        [
            $validations_info // "{}"
            | fromjson
            | to_entries[].value[]
            | select(is_notable(.))
        ];
    
    {
        "Hosts validations": {
            "Hosts": [
                .hosts[]
                | select(.status != "installed")
                | {
                    "id": .id,
                    "name": host_name(.),
                    "status": .status,
                    "notable_validations": notable_validations(.validations_info)
                }
            ]
        },
        "Cluster validations info": {
            "notable_validations": notable_validations(.validations_info)
        }
    }
    ' -r

    出力例

    {
      "Hosts validations": {
        "Hosts": [
          {
            "id": "97ec378c-3568-460c-bc22-df54534ff08f",
            "name": "localhost.localdomain",
            "status": "insufficient",
            "notable_validations": [
              {
                "id": "ntp-synced",
                "status": "failure",
                "message": "Host couldn't synchronize with any NTP server"
              },
              {
                "id": "api-domain-name-resolved-correctly",
                "status": "error",
                "message": "Parse error for domain name resolutions result"
              },
              {
                "id": "api-int-domain-name-resolved-correctly",
                "status": "error",
                "message": "Parse error for domain name resolutions result"
              },
              {
                "id": "apps-domain-name-resolved-correctly",
                "status": "error",
                "message": "Parse error for domain name resolutions result"
              }
            ]
          }
        ]
      },
      "Cluster validations info": {
        "notable_validations": []
      }
    }

  11. 前のコマンドでホストの準備ができていることが示されたら、次のコマンドを実行し、/v2/infra-envs/{infra_env_id}/hosts/{host_id}/actions/install API を使用してインストールを開始します。

    $ curl -X POST -s "$API_URL/api/assisted-install/v2/infra-envs/$INFRA_ENV_ID/hosts/$HOST_ID/actions/install"  -H "Authorization: Bearer ${JWT_TOKEN}"
  12. インストールが進行するにつれて、インストールはワーカーノードの保留中の証明書署名要求 (CSR) を生成します。

    重要

    インストールを完了するには、CSR を承認する必要があります。

    次の API 呼び出しを実行し続けて、クラスターのインストールを監視します。

    $ curl -s "$API_URL/api/assisted-install/v2/clusters/$CLUSTER_ID" -H "Authorization: Bearer ${JWT_TOKEN}" | jq '{
        "Cluster day-2 hosts":
            [
                .hosts[]
                | select(.status != "installed")
                | {id, requested_hostname, status, status_info, progress, status_updated_at, updated_at, infra_env_id, cluster_id, created_at}
            ]
    }'

    出力例

    {
      "Cluster day-2 hosts": [
        {
          "id": "a1c52dde-3432-4f59-b2ae-0a530c851480",
          "requested_hostname": "control-plane-1",
          "status": "added-to-existing-cluster",
          "status_info": "Host has rebooted and no further updates will be posted. Please check console for progress and to possibly approve pending CSRs",
          "progress": {
            "current_stage": "Done",
            "installation_percentage": 100,
            "stage_started_at": "2022-07-08T10:56:20.476Z",
            "stage_updated_at": "2022-07-08T10:56:20.476Z"
          },
          "status_updated_at": "2022-07-08T10:56:20.476Z",
          "updated_at": "2022-07-08T10:57:15.306369Z",
          "infra_env_id": "b74ec0c3-d5b5-4717-a866-5b6854791bd3",
          "cluster_id": "8f721322-419d-4eed-aa5b-61b50ea586ae",
          "created_at": "2022-07-06T22:54:57.161614Z"
        }
      ]
    }

  13. オプション: 次のコマンドを実行して、クラスターのすべてのイベントを表示します。

    $ curl -s "$API_URL/api/assisted-install/v2/events?cluster_id=$CLUSTER_ID" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -c '.[] | {severity, message, event_time, host_id}'

    出力例

    {"severity":"info","message":"Host compute-0: updated status from insufficient to known (Host is ready to be installed)","event_time":"2022-07-08T11:21:46.346Z","host_id":"9d7b3b44-1125-4ad0-9b14-76550087b445"}
    {"severity":"info","message":"Host compute-0: updated status from known to installing (Installation is in progress)","event_time":"2022-07-08T11:28:28.647Z","host_id":"9d7b3b44-1125-4ad0-9b14-76550087b445"}
    {"severity":"info","message":"Host compute-0: updated status from installing to installing-in-progress (Starting installation)","event_time":"2022-07-08T11:28:52.068Z","host_id":"9d7b3b44-1125-4ad0-9b14-76550087b445"}
    {"severity":"info","message":"Uploaded logs for host compute-0 cluster 8f721322-419d-4eed-aa5b-61b50ea586ae","event_time":"2022-07-08T11:29:47.802Z","host_id":"9d7b3b44-1125-4ad0-9b14-76550087b445"}
    {"severity":"info","message":"Host compute-0: updated status from installing-in-progress to added-to-existing-cluster (Host has rebooted and no further updates will be posted. Please check console for progress and to possibly approve pending CSRs)","event_time":"2022-07-08T11:29:48.259Z","host_id":"9d7b3b44-1125-4ad0-9b14-76550087b445"}
    {"severity":"info","message":"Host: compute-0, reached installation stage Rebooting","event_time":"2022-07-08T11:29:48.261Z","host_id":"9d7b3b44-1125-4ad0-9b14-76550087b445"}

  14. クラスターにログインし、保留中の CSR を承認してインストールを完了します。

検証

  • 新しいワーカーノードが Ready のステータスで、クラスターに正常に追加されたことを確認します。

    $ oc get nodes

    出力例

    NAME                           STATUS   ROLES           AGE   VERSION
    control-plane-1.example.com    Ready    master,worker   56m   v1.27.3
    compute-1.example.com          Ready    worker          11m   v1.27.3

10.1.4. 単一ノードの OpenShift クラスターへのワーカーノードの手動での追加

Red Hat Enterprise Linux CoreOS (RHCOS) ISO からワーカーノードを起動し、クラスターの worker.ign ファイルを使用して新しいワーカーノードをクラスターに参加させることにより、単一ノードの OpenShift クラスターにワーカーノードを手動で追加できます。

前提条件

  • ベアメタルに単一ノードの OpenShift クラスターをインストールします。
  • OpenShift CLI (oc) がインストールされている。
  • cluster-admin 権限を持つユーザーとしてログインしている。
  • ワーカーノードを追加するクラスターに必要なすべての DNS レコードが存在することを確認してください。

手順

  1. OpenShift Container Platform バージョンを設定します。

    $ OCP_VERSION=<ocp_version> 1
    1
    <ocp_version> を現在のバージョン (latest-4.14 など) に置き換えます。
  2. ホストアーキテクチャーを設定します。

    $ ARCH=<architecture> 1
    1
    <architecture> をターゲットホストアーキテクチャー (aarch64x86_64 など) に置き換えます。
  3. 次のコマンドを実行して、実行中の単一ノードクラスターから worker.ign データを取得します。

    $ oc extract -n openshift-machine-api secret/worker-user-data-managed --keys=userData --to=- > worker.ign
  4. ネットワークからアクセスできる Web サーバーで worker.ign ファイルをホストします。
  5. OpenShift Container Platform インストーラーをダウンロードし、以下のコマンドを入力して使用できるようにします。

    $ curl -k https://mirror.openshift.com/pub/openshift-v4/clients/ocp/$OCP_VERSION/openshift-install-linux.tar.gz > openshift-install-linux.tar.gz
    $ tar zxvf openshift-install-linux.tar.gz
    $ chmod +x openshift-install
  6. RHCOS ISO URL を取得します。

    $ ISO_URL=$(./openshift-install coreos print-stream-json | grep location | grep $ARCH | grep iso | cut -d\" -f4)
  7. RHCOS ISO をダウンロードします。

    $ curl -L $ISO_URL -o rhcos-live.iso
  8. RHCOS ISO とホストされている worker.ign ファイルを使用して、ワーカーノードをインストールします。

    1. RHCOS ISO と任意のインストール方法を使用して、ターゲットホストを起動します。
    2. ターゲットホストが RHCOS ISO から起動したら、ターゲットホストでコンソールを開きます。
    3. ローカルネットワークで DHCP が有効になっていない場合は、RHCOS インストールを実行する前に、新しいホスト名で Ignition ファイルを作成し、ワーカーノードの静的 IP アドレスを設定する必要があります。以下の手順を実行します。

      1. 静的 IP を使用してワーカーホストネットワーク接続を設定します。ターゲットホストコンソールで次のコマンドを実行します。

        $ nmcli con mod <network_interface> ipv4.method manual /
        ipv4.addresses <static_ip> ipv4.gateway <network_gateway> ipv4.dns <dns_server> /
        802-3-ethernet.mtu 9000

        ここでは、以下のようになります。

        <static_ip>
        ホストの静的 IP アドレスと CIDR です (例: 10.1.101.50/24)。
        <network_gateway>
        ネットワークゲートウェイです (例: 10.1.101.1)。
      2. 変更したネットワークインターフェイスを有効にします。

        $ nmcli con up <network_interface>
      3. 新しい Ignition ファイル new-worker.ign を作成します。このファイルには、元の worker.ign への参照と、coreos-installer プログラムが新しいワーカーホストの /etc/hostname ファイルに入力するために使用する追加の命令を含めます。以下に例を示します。

        {
          "ignition":{
            "version":"3.2.0",
            "config":{
              "merge":[
                {
                  "source":"<hosted_worker_ign_file>" 1
                }
              ]
            }
          },
          "storage":{
            "files":[
              {
                "path":"/etc/hostname",
                "contents":{
                  "source":"data:,<new_fqdn>" 2
                },
                "mode":420,
                "overwrite":true,
                "path":"/etc/hostname"
              }
            ]
          }
        }
        1
        <hosted_worker_ign_file> は、元の worker.ign ファイルのローカルでアクセス可能な URL です。たとえば、http://webserver.example.com/worker.ign です。
        2
        <new_fqdn> は、ワーカーノードに設定した新しい FQDN です。たとえば、new-worker.example.com です。
      4. ネットワークからアクセスできる Web サーバーで new-worker.ign ファイルをホストします。
      5. 次の coreos-installer コマンドを実行して、ignition-url とハードディスクの詳細を渡します。

        $ sudo coreos-installer install --copy-network /
        --ignition-url=<new_worker_ign_file> <hard_disk> --insecure-ignition

        ここでは、以下のようになります。

        <new_worker_ign_file>
        ホストされている new-worker.ign ファイルのローカルでアクセス可能な URL です (例: http://webserver.example.com/new-worker.ign)。
        <hard_disk>
        RHCOS をインストールするハードディスクです (例: /dev/sda)。
    4. DHCP が有効になっているネットワークでは、静的 IP を設定する必要はありません。ターゲットホストコンソールから次の coreos-installer コマンドを実行して、システムをインストールします。

      $ coreos-installer install --ignition-url=<hosted_worker_ign_file> <hard_disk>
    5. DHCP を手動で有効にするには、次の NMStateConfig CR を単一ノードの OpenShift クラスターに適用します。

      apiVersion: agent-install.openshift.io/v1
      kind: NMStateConfig
      metadata:
        name: nmstateconfig-dhcp
        namespace: example-sno
        labels:
          nmstate_config_cluster_name: <nmstate_config_cluster_label>
      spec:
        config:
          interfaces:
            - name: eth0
              type: ethernet
              state: up
              ipv4:
                enabled: true
                dhcp: true
              ipv6:
                enabled: false
        interfaces:
          - name: "eth0"
            macAddress: "AA:BB:CC:DD:EE:11"
      重要

      単一ノードの OpenShift が静的 IP アドレスでデプロイされた場合に、静的 IP アドレスを使用してワーカーノードを正常にデプロイし、動的 IP アドレスを使用してワーカーノードを追加するには、NMStateConfig CR が必要です。クラスターネットワーク DHCP は、これらのネットワーク設定を新しいワーカーノードに自動的に設定しません。

  9. インストールが進行するにつれて、インストールはワーカーノードの保留中の証明書署名要求 (CSR) を生成します。プロンプトが表示されたら、保留中の CSR を承認してインストールを完了します。
  10. インストールが完了したら、ホストを再起動します。ホストは、新しいワーカーノードとしてクラスターに参加します。

検証

  • 新しいワーカーノードが Ready のステータスで、クラスターに正常に追加されたことを確認します。

    $ oc get nodes

    出力例

    NAME                           STATUS   ROLES           AGE   VERSION
    control-plane-1.example.com    Ready    master,worker   56m   v1.27.3
    compute-1.example.com          Ready    worker          11m   v1.27.3

10.1.5. マシンの証明書署名要求の承認

マシンをクラスターに追加する際に、追加したそれぞれのマシンに対して 2 つの保留状態の証明書署名要求 (CSR) が生成されます。これらの CSR が承認されていることを確認するか、必要な場合はそれらを承認してください。最初にクライアント要求を承認し、次にサーバー要求を承認する必要があります。

前提条件

  • マシンがクラスターに追加されています。

手順

  1. クラスターがマシンを認識していることを確認します。

    $ oc get nodes

    出力例

    NAME      STATUS    ROLES   AGE  VERSION
    master-0  Ready     master  63m  v1.27.3
    master-1  Ready     master  63m  v1.27.3
    master-2  Ready     master  64m  v1.27.3

    出力には作成したすべてのマシンがリスト表示されます。

    注記

    上記の出力には、一部の CSR が承認されるまで、ワーカーノード (ワーカーノードとも呼ばれる) が含まれない場合があります。

  2. 保留中の証明書署名要求 (CSR) を確認し、クラスターに追加したそれぞれのマシンのクライアントおよびサーバー要求に Pending または Approved ステータスが表示されていることを確認します。

    $ oc get csr

    出力例

    NAME        AGE     REQUESTOR                                                                   CONDITION
    csr-8b2br   15m     system:serviceaccount:openshift-machine-config-operator:node-bootstrapper   Pending
    csr-8vnps   15m     system:serviceaccount:openshift-machine-config-operator:node-bootstrapper   Pending
    ...

    この例では、2 つのマシンがクラスターに参加しています。このリストにはさらに多くの承認された CSR が表示される可能性があります。

  3. 追加したマシンの保留中の CSR すべてが Pending ステータスになった後に CSR が承認されない場合には、クラスターマシンの CSR を承認します。

    注記

    CSR のローテーションは自動的に実行されるため、クラスターにマシンを追加後 1 時間以内に CSR を承認してください。1 時間以内に承認しない場合には、証明書のローテーションが行われ、各ノードに 3 つ以上の証明書が存在するようになります。これらの証明書すべてを承認する必要があります。クライアントの CSR が承認された後に、Kubelet は提供証明書のセカンダリー CSR を作成します。これには、手動の承認が必要になります。次に、後続の提供証明書の更新要求は、Kubelet が同じパラメーターを持つ新規証明書を要求する場合に machine-approver によって自動的に承認されます。

    注記

    ベアメタルおよび他の user-provisioned infrastructure などのマシン API ではないプラットフォームで実行されているクラスターの場合、kubelet 提供証明書要求 (CSR) を自動的に承認する方法を実装する必要があります。要求が承認されない場合、API サーバーが kubelet に接続する際に提供証明書が必須であるため、oc execoc rsh、および oc logs コマンドは正常に実行できません。Kubelet エンドポイントにアクセスする操作には、この証明書の承認が必要です。この方法は新規 CSR の有無を監視し、CSR が system:node または system:admin グループの node-bootstrapper サービスアカウントによって提出されていることを確認し、ノードのアイデンティティーを確認します。

    • それらを個別に承認するには、それぞれの有効な CSR に以下のコマンドを実行します。

      $ oc adm certificate approve <csr_name> 1
      1
      <csr_name> は、現行の CSR のリストからの CSR の名前です。
    • すべての保留中の CSR を承認するには、以下のコマンドを実行します。

      $ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs --no-run-if-empty oc adm certificate approve
      注記

      一部の Operator は、一部の CSR が承認されるまで利用できない可能性があります。

  4. クライアント要求が承認されたら、クラスターに追加した各マシンのサーバー要求を確認する必要があります。

    $ oc get csr

    出力例

    NAME        AGE     REQUESTOR                                                                   CONDITION
    csr-bfd72   5m26s   system:node:ip-10-0-50-126.us-east-2.compute.internal                       Pending
    csr-c57lv   5m26s   system:node:ip-10-0-95-157.us-east-2.compute.internal                       Pending
    ...

  5. 残りの CSR が承認されず、それらが Pending ステータスにある場合、クラスターマシンの CSR を承認します。

    • それらを個別に承認するには、それぞれの有効な CSR に以下のコマンドを実行します。

      $ oc adm certificate approve <csr_name> 1
      1
      <csr_name> は、現行の CSR のリストからの CSR の名前です。
    • すべての保留中の CSR を承認するには、以下のコマンドを実行します。

      $ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs oc adm certificate approve
  6. すべてのクライアントおよびサーバーの CSR が承認された後に、マシンのステータスが Ready になります。以下のコマンドを実行して、これを確認します。

    $ oc get nodes

    出力例

    NAME      STATUS    ROLES   AGE  VERSION
    master-0  Ready     master  73m  v1.27.3
    master-1  Ready     master  73m  v1.27.3
    master-2  Ready     master  74m  v1.27.3
    worker-0  Ready     worker  11m  v1.27.3
    worker-1  Ready     worker  11m  v1.27.3

    注記

    サーバー CSR の承認後にマシンが Ready ステータスに移行するまでに数分の時間がかかる場合があります。

関連情報

第11章 ノードメトリクスダッシュボード

ノードメトリクスダッシュボードは、Pod スケーリングの潜在的な問題を特定するのに役立つ視覚的な分析ダッシュボードです。

11.1. ノードメトリクスダッシュボードについて

ノードメトリクスダッシュボードを使用すると、管理チームとサポートチームのメンバーは、スケーリング問題の診断とトラブルシューティングに使用されるスケーリング制限など、Pod のスケーリングに関連するメトリクスを監視できます。特に、ダッシュボードを通じて表示される視覚的分析を使用して、ノードをまたいだワークロード分散を監視できます。これらの分析から得られる詳細情報は、CRI-O および Kubelet システムコンポーネントの正常性を判断し、過剰または不均衡なリソース消費とシステムの不安定性の潜在的な原因を特定するのに役立ちます。

ダッシュボードには、次のカテゴリーに分類された視覚的分析ウィジェットが表示されます。

Critical
システムの不安定性や非効率性を引き起こす可能性のあるノードの問題を特定するのに役立つ視覚化が含まれています
Outliers
実行時間が 95 パーセンタイルの範囲外に該当するプロセスを可視化するヒストグラムが含まれています
Average durations
システムコンポーネントが操作を処理するのにかかる時間の変化を追跡するのに役立ちます
Number of operations
実行中の操作数の変化を可視化して把握できるようにします。これは、システムの負荷バランスと効率を判断するのに役立ちます。

11.2. ノードメトリクスダッシュボードへのアクセス

Administrator パースペクティブから、ノードメトリクスダッシュボードにアクセスできます。

手順

  1. Observe メニューオプションを展開し、Dashboards を選択します。
  2. Dashboard フィルターで、Node cluster を選択します。
注記

Critical カテゴリーに可視化されたデータが表示されない場合、重大な異常は検出されていません。ダッシュボードは意図したとおりに機能しています。

11.3. 最適なノードリソースの使用状況を示すメトリクスを特定する

ノードメトリクスダッシュボードは、CriticalOutliersAverage durationsNumber of Operations の 4 つのカテゴリーに編成されています。Critical カテゴリーのメトリクスは、最適なノードリソースの使用状況を示すのに役立ちます。これらのメトリクスには以下が含まれます。

  • 過去 1 日間で最多の OOM キルが発生した上位 3 つのコンテナー
  • 過去 1 時間のイメージプル失敗率
  • システム予約メモリー使用率が 80% を超えるノード
  • Kubelet システム予約メモリー使用率が 50% を超えるノード
  • CRI-O システム予約メモリー使用率が 50% を超えるノード
  • システム予約 CPU 使用率が 80% を超えるノード
  • Kubelet システム予約 CPU 使用率が 50% を超えるノード
  • CRI-O システム予約 CPU 使用率が 50% を超えるノード

11.3.1. 過去 1 日間で最多の OOM キルが発生した上位 3 つのコンテナー

過去 1 日間で最多の OOM キルが発生した上位 3 つのコンテナー のクエリーでは、前日に最も多くの Out-Of-Memory (OOM) キルが発生した上位 3 つのコンテナーに関する詳細を取得します。

デフォルトクエリーの例

topk(3, sum(increase(container_runtime_crio_containers_oom_count_total[1d])) by (name))

OOM キルが発生すると、システムはメモリー不足により一部のプロセスを強制的に終了します。OOM キルが頻繁に発生すると、ノードの機能だけでなく、Kubernetes エコシステム全体の機能も阻害される可能性があります。OOM キルが頻繁に発生するコンテナーは、必要以上に多くのメモリーを消費している可能性があり、これによりシステムが不安定になります。

このメトリックを使用して、OOM キルが頻繁に発生しているコンテナーを特定し、これらのコンテナーがメモリーを過剰に消費している原因を調査します。必要に応じてリソース割り当てを調整し、メモリー使用量に基づきコンテナーサイズを変更することを検討してください。OutliersAverage durationsNumber of operations カテゴリーのメトリクスを確認して、ノードの正常性と安定性に関する詳細情報を得ることもできます。

11.3.2. 過去 1 時間のイメージプル失敗率

過去 1 時間のイメージプル失敗率 のクエリーでは、失敗したイメージプルの合計数を、成功したイメージプルと失敗したイメージプルの合計数で割って失敗率を算出します。

デフォルトクエリーの例

rate(container_runtime_crio_image_pulls_failure_total[1h]) / (rate(container_runtime_crio_image_pulls_success_total[1h]) + rate(container_runtime_crio_image_pulls_failure_total[1h]))

イメージプルの失敗率を理解することは、ノードの正常性を維持するために重要です。失敗率が高い場合は、ネットワークの問題、ストレージの問題、設定ミス、または Pod 密度や新しいコンテナーのデプロイメントを阻害する可能性があるその他の問題を示唆している場合があります。

このクエリーの結果が高い場合は、ネットワーク接続、リモートリポジトリーの可用性、ノードストレージ、イメージ参照の正確性などの考えられる原因を調査します。また、OutliersAverage durationsNumber of operations カテゴリーのメトリクスを確認して、さらに詳細な情報を得ることができます。

11.3.3. システム予約メモリー使用率が 80% を超えるノード

システム予約メモリー使用率が 80% を超えるノード のクエリーでは、各ノードで使用されているシステム予約メモリーの割合が計算されます。この計算では、Resident Set Size (RSS) の合計を、割り当て可能なメモリーから差し引かれたノードの合計メモリー容量で割ります。RSS は、メインメモリー (RAM) に保持される、プロセスが占有するシステムメモリーの部分です。結果の値がしきい値である 80% 以上の場合、ノードにフラグが追加されます。

デフォルトクエリーの例

sum by (node) (container_memory_rss{id="/system.slice"}) / sum by (node) (kube_node_status_capacity{resource="memory"} - kube_node_status_allocatable{resource="memory"}) * 100 >= 80

システム予約メモリーは、システムデーモンおよび Kubernetes システムデーモンの実行に利用されるため、Kubernetes ノードにとって非常に重要です。システム予約メモリー使用率が 80% を超える場合は、システムと Kubernetes デーモンがメモリーを過剰に消費していることを示し、ノードが不安定になって実行中の Pod のパフォーマンスが影響を受ける可能性があることを示唆しています。過剰なメモリー消費は、メモリーを解放するために重要なシステムプロセスを終了させる Out-of-Memory (OOM) キラーを引き起こす可能性があります。

このメトリックによりノードにフラグが追加された場合は、メモリーを過剰に消費しているシステムまたは Kubernetes プロセスを特定し、状況を緩和するための適切なアクションを実行します。これらのアクションには、重要ではないプロセスのスケールバック、メモリー使用量を削減するためのプログラム設定の最適化、メモリー容量がより大きいハードウェアへのノードシステムのアップグレードなどが含まれる場合があります。また、OutliersAverage durationsNumber of operations カテゴリーのメトリクスを確認して、ノードのパフォーマンスに関する詳細情報を得ることもできます。

11.3.4. Kubelet システム予約メモリー使用率が 50% を超えるノード

Kubelet システム予約メモリー使用率が 50% を超えるノード のクエリーでは、Kubelet のシステム予約メモリー使用率が 50% を超えているノードが示されます。このクエリーでは、Kubelet プロセス自体がノード上で消費しているメモリーを調べます。

デフォルトクエリーの例

sum by (node) (container_memory_rss{id="/system.slice/kubelet.service"}) / sum by (node) (kube_node_status_capacity{resource="memory"} - kube_node_status_allocatable{resource="memory"}) * 100 >= 50

このクエリーは、ノード操作の安定性と効率性に影響を与える可能性のある、ノード内のメモリー逼迫状況を特定するのに役立ちます。Kubelet のメモリー使用率がシステム予約メモリーの 50% を常に超えている場合は、システム予約設定が適切に設定されておらず、ノードが不安定になるリスクが高いことを示しています。

このメトリックが強調表示されている場合は、設定ポリシーを確認し、システム予約設定または Kubelet のリソース制限設定を調整することを検討してください。さらに、Kubelet のメモリー使用率が予約システムメモリー合計の 50% を常に超える場合は、OutliersAverage durationsNumber of operations カテゴリーのメトリクスを調べて、正確な診断のために詳細情報を得ることもできます。

11.3.5. CRI-O システム予約メモリー使用率が 50% を超えるノード

CRI-O システム予約メモリー使用率が 50% を超えるノード のクエリーでは、CRI-O システム用に予約されたメモリーの使用率が 50% 以上のノードをすべて計算します。この場合、メモリー使用率は、RAM に保持される CRI-O システムのメモリーに含まれる Resident Set Size (RSS) によって定義されます。

デフォルトクエリーの例

sum by (node) (container_memory_rss{id="/system.slice/crio.service"}) / sum by (node) (kube_node_status_capacity{resource="memory"} - kube_node_status_allocatable{resource="memory"}) * 100 >= 50

このクエリーは、各ノード上の CRI-O システム用に予約されているメモリーのステータスを監視するのに役立ちます。使用率が高い場合は、利用可能なリソースが不足しており、パフォーマンス上の問題が発生する可能性があることを示唆していることもあります。CRI-O システム用に予約されているメモリーが推奨された制限である 50% を超える場合は、システム予約メモリーの半分がノード上の CRI-O によって使用されていることを示しています。

メモリーの割り当てと使用状況を確認し、ノードが不安定になる可能性を回避するためにメモリーリソースを移動または増やす必要があるかどうかを評価します。また、OutliersAverage durationsNumber of operations カテゴリーのメトリクスを調べて、さらに詳細な情報を得ることもできます。

11.3.6. システム予約 CPU 使用率が 80% を超えるノード

システム予約 CPU 使用率が 80% を超えるノード のクエリーは、システム予約 CPU の使用率が 80% を超えているノードを特定します。このクエリーは、システムで予約された容量に焦点を当てて、過去 5 分間の CPU 使用率を計算し、それをノードで利用可能な CPU リソースと比較します。比率が 80% を超える場合、ノードの結果がメトリックに表示されます。

デフォルトクエリーの例

sum by (node) (rate(container_cpu_usage_seconds_total{id="/system.slice"}[5m]) * 100) / sum by (node) (kube_node_status_capacity{resource="cpu"} - kube_node_status_allocatable{resource="cpu"}) >= 80

このクエリーは、リソースの枯渇につながる可能性のある、システム予約 CPU 使用率の重大なレベルを示します。システム予約 CPU 使用率が高いと、システムプロセス (Kubelet や CRI-O を含む) がノード上のリソースを適切に管理できなくなる可能性があります。このクエリーは、過剰なシステムプロセスや CPU 割り当ての設定ミスを示唆している可能性があります。

考えられる是正措置には、他のノードとのワークロードバランスの再調整や、ノードに割り当てられる CPU リソースの増加が含まれます。システムの CPU 使用率が高くなる原因を調査し、OutliersAverage durationsNumber of operations カテゴリーの該当メトリクスでノードの動作に関する詳細情報を確認します。

11.3.7. Kubelet システム予約 CPU 使用率が 50% を超えるノード

Kubelet システム予約 CPU 使用率が 50% を超えるノード のクエリーでは、Kubelet システムが現在使用しているシステム予約 CPU の割合を計算します。

デフォルトクエリーの例

sum by (node) (rate(container_cpu_usage_seconds_total{id="/system.slice/kubelet.service"}[5m]) * 100) / sum by (node) (kube_node_status_capacity{resource="cpu"} - kube_node_status_allocatable{resource="cpu"}) >= 50

Kubelet は、システムで予約された CPU を独自の操作と重要なシステムサービスの実行に使用します。ノードの正常性を確保するには、システムの予約 CPU 使用率がしきい値である 50% を超えないようにすることが重要です。この制限を超えると、Kubelet の使用率または負荷が高くなっている可能性があり、その場合はノードの安定性だけでなく、Kubernetes クラスター全体のパフォーマンスに影響を与える可能性があります。

このメトリックにノードが表示されている場合、Kubelet とシステム全体に高い負荷がかかっています。クラスター内の他のノード間で負荷を分散することにより、特定のノードのオーバーロードを軽減できます。OutliersAverage durationsNumber of operations カテゴリーの他のクエリーメトリクスを確認して詳細を把握し、必要な是正措置を講じます。

11.3.8. CRI-O システム予約 CPU 使用率が 50% を超えるノード

CRI-O システム予約 CPU 使用率が 50% を超えるノード のクエリーは、過去 5 分間で CRI-O システム予約 CPU の使用率が 50% を超えたノードを特定します。このクエリーは、使用しているコンテナーランタイムである CRI-O による CPU リソースの消費をノードごとに監視します。

デフォルトクエリーの例

sum by (node) (rate(container_cpu_usage_seconds_total{id="/system.slice/crio.service"}[5m]) * 100) / sum by (node) (kube_node_status_capacity{resource="cpu"} - kube_node_status_allocatable{resource="cpu"}) >= 50

このクエリーにより、Pod のパフォーマンスに悪影響を与える可能性がある異常な開始時間を迅速に特定できます。このクエリーで高い値が返された場合、Pod の開始時間が通常より遅く、kubelet、Pod 設定、またはリソースに潜在的な問題があることが示唆されます。

Pod 設定と割り当てられたリソースを確認して、詳細を調査します。それらがシステムの機能と一致していることを確認してください。引き続き開始時間として高い値が示される場合は、ダッシュボード上で他のカテゴリーのメトリクスパネルを調査して、システムコンポーネントの状態を確認してください。

11.4. ダッシュボードクエリーのカスタマイズ

ノードメトリクスダッシュボードをビルドする際に使用されるデフォルトのクエリーをカスタマイズできます。

手順

  1. メトリックを選択し、Inspect をクリックしてデータに移動します。このページには、クエリー結果を展開した視覚要素、データの分析に使用された Prometheus クエリー、クエリーで使用されたデータサブセットなど、メトリックの詳細が表示されます。
  2. クエリーパラメーターに必要な変更を加えます。
  3. オプション: Add query をクリックして、データに対して追加のクエリーを実行します。
  4. Run query をクリックして、指定したパラメーターを使用してクエリーを再実行します。

Legal Notice

Copyright © 2024 Red Hat, Inc.

OpenShift documentation is licensed under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0).

Modified versions must remove all Red Hat trademarks.

Portions adapted from https://github.com/kubernetes-incubator/service-catalog/ with modifications by Red Hat.

Red Hat, Red Hat Enterprise Linux, the Red Hat logo, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.

Linux® is the registered trademark of Linus Torvalds in the United States and other countries.

Java® is a registered trademark of Oracle and/or its affiliates.

XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.

MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.

Node.js® is an official trademark of Joyent. Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.

The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation’s permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.

All other trademarks are the property of their respective owners.

Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.