ノード

OpenShift Container Platform 4.10

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

Red Hat OpenShift Documentation Team

概要

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

第1章 ノードの概要

1.1. ノードについて

ノードは、Kubernetes クラスター内の仮想マシンまたはベアメタルマシンです。ワーカーノードは、Pod としてグループ化されたアプリケーションコンテナーをホストします。コントロールプレーンノードは、Kubernetes クラスターを制御するために必要なサービスを実行します。OpenShift Container Platform では、コントロールプレーンノードには、OpenShift ContainerPlatform クラスターを管理するための 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 ContainerPlatform クラスター内のノードに関する情報を取得できます。

管理操作

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

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

エンハンスメント操作

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

1.2. Pod について

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

読み取り操作

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

管理操作

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

エンハンスメント操作

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

操作ユーザー詳細情報

Horizontal Pod Autoscaler を作成して使用。

開発者

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

Custom Metrics Autoscaler:: カスタムメトリクスオートスケーラーは、CPU やメモリーに基づくだけではないカスタムメトリクスに基づき、デプロイメント、ステートフルセット、カスタムリソース、またはジョブの Pod 数を自動的に増減できます。詳細は、Custom Metrics Autoscaler Operator の概要 を参照してください。

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

管理者および開発者

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

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

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

Administrator

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

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

Administrator

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

1.3. コンテナーについて

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

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

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

ノード、Pod、およびコンテナーで特定のタスクを実行する以外に、OpenShift Container Platform クラスター全体を操作して、クラスターの効率とアプリケーション 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%、ないしはレプリカ数に等しい値は許可されますが、これによりノードがドレイン (解放) されないようにブロックされる可能性があります。

以下を実行して、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.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 がボリュームの所有権とパーミッションをチェックおよび管理する方法を制御します。
  • ランタイムクラスを使用して、ボリュームの SELinux 再ラベル付けをスキップします。

詳細については、OpenShift でファイル数の多いパーシステントボリュームを使用している場合、Pod が起動に失敗したり、準備完了状態になるまでに時間がかかりすぎたりする理由 を参照してください。

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

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

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

注記

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

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 Horizontal Pod Autoscaler の追加

    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) を使用して、プロジェクトの DeploymentDeployment ConfigStatefulSetJobDaemonSetReplicaSet、または 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 は、それらの Pod 内のコンテナーの履歴および現在の CPU とメモリーの使用状況を自動的に計算し、このデータを使用して、最適化されたリソース制限および要求を判別し、これらの Pod が常時効率的に動作していることを確認することができます。たとえば、VPA は使用している量よりも多くのリソースを要求する Pod のリソースを減らし、十分なリソースを要求していない Pod のリソースを増やします。

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

注記

デフォルトで、ワークロードオブジェクトは、VPA が Pod を自動的に削除できるようにするためにレプリカを 2 つ以上指定する必要があります。この最小値よりも少ないレプリカを指定するワークロードオブジェクトは削除されません。これらの Pod を手動で削除すると、ワークロードオブジェクトが Pod を再デプロイします。VPA は推奨内容に基づいて新規 Pod を更新します。この最小値は、Changing the VPA minimum value に示されるように 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 をクリックします。
  5. VPA Operator コンポーネントをリスト表示して、インストールを確認します。

    1. WorkloadsPods に移動します。
    2. ドロップダウンメニューから openshift-vertical-pod-autoscaler プロジェクトを選択し、4 つの Pod が実行されていることを確認します。
    3. WorkloadsDeploymentsに移動し、4 つの デプロイメントが実行されていることを確認します。
  6. オプション:以下のコマンドを使用して、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 を更新します。この最小値は、Changing the VPA minimum value に示されるように 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 がなければなりません。

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 がなければなりません。

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 がなければなりません。

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.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"
      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 に設定します。
    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. 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/service-account-token。サービスアカウントトークンを使用します。
  • kubernetes.io/basic-auth。Basic 認証で使用します。
  • 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.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.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. 設定マップの作成および使用

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

2.7.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 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.7.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.7.3. CLI を使用して設定マップを作成する

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

手順

  • 設定マップの作成

    $ oc create configmap <configmap_name> [options]

2.7.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 description の出力にはキーの名前とそのサイズのみが表示されます。

前提条件

  • 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.7.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.7.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.7.4. ユースケース: Pod で設定マップを使用する

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

2.7.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.7.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.7.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.8. Pod で外部リソースにアクセスするためのデバイスプラグインの使用

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

2.8.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 reseting 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.8.1.1. デバイスプラグインのデプロイ方法

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

2.8.2. デバイスマネージャーについて

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

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

重要

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

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

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

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

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

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

2.8.3. デバイスマネージャーの有効化

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

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

  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
      デバイスマネージャーに必要なラベル。

手順

  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. デバイスマネージャーを作成します。

    $ oc create -f devicemgr.yaml

    出力例

    kubeletconfig.machineconfiguration.openshift.io/devicemgr created

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

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

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

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

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

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

2.9.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.9.1.2. Pod の優先順位名

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

2.9.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.9.2.1. プリエンプションを実行しない優先順位クラス (テクノロジープレビュー)

プリエンプションポリシーが Never に設定された Pod は優先順位の低い Pod よりも前のスケジューリングキューに置かれますが、他の Pod のプリエンプションを実行することはできません。スケジュールを待機しているプリエンプションを実行しない Pod は、十分なリソースが解放され、これがスケジュールされるまでスケジュールキュー内に留まります。他の Pod などのプリエンプションを実行しない Pod はスケジューラーのバックオフの対象になります。つまり、スケジューラーがこれらの Pod のスケジュールの試行に成功しない場合、低頻度で再試行されるため、優先順位の低い他の Pod をそれらの Pod よりも前にスケジュールできます。

プリエンプションを実行しない Pod については、他の優先順位の高い Pod が依然としてプリエンプションを実行できます。

2.9.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.9.2.3. プリエンプションが実行された Pod の正常な終了

Pod のプリエンプションの実行中、スケジューラーは Pod の正常な終了期間が期限切れになるのを待機します。その後、Pod は機能を完了し、終了します。Pod がこの期間後も終了しない場合、スケジューラーは Pod を強制終了します。 この正常な終了期間により、スケジューラーによる Pod のプリエンプションの実行時と保留中の Pod のノードへのスケジュール時に時間差が出ます。

この時間差を最小限にするには、優先順位の低い Pod の正常な終了期間を短く設定します。

2.9.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.10. ノードセレクターの使用による特定ノードへの Pod の配置

ノードセレクター は、キーと値のペアのマップを指定します。ルールは、ノード上のカスタムラベルと Pod で指定されたセレクターを使用して定義されます。

Pod がノードで実行する要件を満たすには、Pod はノードのラベルとして示されるキーと値のペアを持っている必要があります。

同じ Pod 設定でノードのアフィニティーとノードセレクターを使用している場合、以下の重要な考慮事項を参照してください。

2.10.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.23.0

  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 に直接追加することはできません。

第3章 Custom Metrics Autoscaler Operator を使用した Pod の自動スケーリング

3.1. Custom Metrics Autoscaler Operator の概要

開発者は、Red Hat OpenShift の Custom Metrics Autoscaler Operator を使用して、OpenShift Container Platform が CPU またはメモリーのみに基づくものではないカスタメトリクスに基づきデプロイメント、ステートフルセット、カスタムリソース、またはジョブの Pod 数を自動的に増減する方法を指定できます。

ustom Metrics Autoscaler Operator は、Kubernetes Event Driven Autoscaler (KEDA) に基づくオプションの Operator であり、Pod メトリクス以外の追加のメトリクスソースを使用してワークロードをスケーリングできます。

カスタムメトリクスオートスケーラーは現在、Prometheus、CPU、メモリー、および Apache Kafka メトリクスのみをサポートしています。

カスタムメトリックオートスケーラー Operator は、特定のアプリケーションからのカスタムの外部メトリックに基づいて、Pod をスケールアップおよびスケールダウンします。他のアプリケーションは引き続き他のスケーリング方法を使用します。スケーラーとも呼ばれる トリガー を設定します。これは、カスタムメトリックオートスケーラーがスケーリング方法を決定するために使用するイベントとメトリックのソースです。カスタムメトリックオートスケーラーはメトリック API を使用して、外部メトリックを OpenShift Container Platform が使用できる形式に変換します。カスタムメトリックオートスケーラーは、実際のスケーリングを実行する Horizontal Pod Autoscaler (HPA) を作成します。

カスタムメトリクスオートスケーラーを使用するには、スケーリングメタデータを定義するカスタムリソース (CR) である ScaledObject または ScaledJob オブジェクトを作成します。スケーリングするデプロイメントまたはジョブ、スケーリングするメトリックのソース (トリガー)、許可される最小および最大レプリカ数などのその他のパラメーターを指定します。

注記

スケーリングするワークロードごとに、スケーリングされたオブジェクトまたはスケーリングされたジョブを 1 つだけ作成できます。また、スケーリングされたオブジェクトまたはスケーリングされたジョブと Horizontal Pod Autoscaler (HPA) を同じワークロードで使用することはできません。

カスタムメトリクスオートスケーラーは、HPA とは異なり、ゼロにスケーリングできます。カスタムメトリクスオートスケーラー CR の minReplicaCount 値を 0 に設定すると、カスタムメトリクスオートスケーラーはワークロードを 1 レプリカから 0 レプリカにスケールダウンするか、0 レプリカから 1 にスケールアップします。これは、アクティベーションフェーズ として知られています。1 つのレプリカにスケールアップした後、HPA はスケーリングを制御します。これは スケーリングフェーズ として知られています。

一部のトリガーにより、クラスターメトリクスオートスケーラーによってスケーリングされるレプリカの数を変更できます。いずれの場合も、アクティベーションフェーズを設定するパラメーターは、activation で始まる同じフレーズを常に使用します。たとえば、threshold パラメーターがスケーリングを設定する場合、activationThreshold はアクティベーションを設定します。アクティベーションフェーズとスケーリングフェーズを設定すると、スケーリングポリシーの柔軟性が向上します。たとえば、アクティベーションフェーズをより高く設定することで、メトリクスが特に低い場合にスケールアップまたはスケールダウンを防ぐことができます。

それぞれ異なる決定を行う場合は、スケーリングの値よりもアクティベーションの値が優先されます。たとえば、threshold10 に設定されていて、activationThreshold50 である場合にメトリクスが 40 を報告した場合、スケーラーはアクティブにならず、HPA が 4 つのインスタンスを必要とする場合でも Pod はゼロにスケーリングされます。

カスタムリソース内の Pod の数を確認するか、Custom Metrics Autoscaler Operator ログで次のようなメッセージを確認することで、自動スケーリングが行われたことを確認できます。

Successfully set ScaleTarget replica count
Successfully updated ScaleTarget

必要に応じて、ワークロードオブジェクトの自動スケーリングを一時停止できます。たとえば、クラスターのメンテナンスを実行する前に自動スケーリングを一時停止できます。

3.2. 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.2.1. サポート対象バージョン

以下の表は、各 OpenShift Container Platform バージョンの Custom Metrics Autoscaler Operator バージョンを定義しています。

バージョンOpenShift Container Platform バージョン一般公開

2.10.1-267

4.13

一般公開

2.10.1-267

4.12

一般公開

2.10.1-267

4.11

一般公開

2.10.1-267

4.10

一般公開

3.2.2. 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.2.2.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.2.3. 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.2.3.1. 新機能および拡張機能

3.2.3.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.2.3.1.2. パフォーマンスメトリクス

Prometheus Query Language (PromQL) を使用して、Custom Metrics Autoscaler Operator でメトリクスのクエリーを行えるようになりました。

3.2.3.1.3. スケーリングされたオブジェクトのカスタムメトリクス自動スケーリングの一時停止

必要に応じてスケーリングされたオブジェクトの自動スケーリングを一時停止し、準備ができたら再開できるようになりました。

3.2.3.1.4. スケーリングされたオブジェクトのレプリカフォールバック

スケーリングされたオブジェクトがソースからメトリクスを取得できなかった場合に、フォールバックするレプリカの数を指定できるようになりました。

3.2.3.1.5. スケーリングされたオブジェクトのカスタマイズ可能な HPA 命名

スケーリングされたオブジェクトで、水平 Pod オートスケーラーのカスタム名を指定できるようになりました。

3.2.3.1.6. アクティブ化およびスケーリングのしきい値

水平 Pod オートスケーラー (HPA) は 0 レプリカへの、または 0 レプリカからのスケーリングができないため、Custom Metrics Autoscaler Operator がそのスケーリングを実行し、その後 HPA がスケーリングを実行します。レプリカの数に基づき HPA が自動スケーリングを引き継ぐタイミングを指定できるようになりました。これにより、スケーリングポリシーの柔軟性が向上します。

3.2.4. 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.2.4.1. 新機能および拡張機能

3.2.4.1.1. Operator のアップグレードサポート

以前の Custom Metrics Autoscaler Operator バージョンからアップグレードできるようになりました。Operator のアップグレードについて、詳しくは「関連情報'の「Operator の更新チャネルの変更」を参照してください。

3.2.4.1.2. must-gather サポート

OpenShift Container Platform must-gather ツールを使用して、Custom Metrics Autoscaler Operator およびそのコンポーネントについてのデータを収集できるようになりました。現時点で、Custom Metrics Autoscaler で must-gather ツールを使用するプロセスは、他の Operator とは異なります。詳細は、「関連情報」の「デバッグデータの収集」を参照してください。

3.2.5. 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.2.5.1. 新機能および拡張機能

3.2.5.1.1. 監査ロギング

Custom Metrics Autoscaler Operator とその関連コンポーネントの監査ログを収集して表示できるようになりました。監査ログは、システムに影響を与えた一連のアクティビティーを個別のユーザー、管理者その他システムのコンポーネント別に記述したセキュリティー関連の時系列のレコードです。

3.2.5.1.2. Apache Kafka メトリクスに基づくアプリケーションのスケーリング

KEDA Apache kafka トリガー/スケーラーを使用して、Apache Kafka トピックに基づいてデプロイメントをスケーリングできるようになりました。

3.2.5.1.3. CPU メトリクスに基づくアプリケーションのスケーリング

KEDA CPU トリガー/スケーラーを使用して、CPU メトリクスに基づいてデプロイメントをスケーリングできるようになりました。

3.2.5.1.4. メモリーメトリクスに基づくアプリケーションのスケーリング

KEDA メモリートリガー/スケーラーを使用して、メモリーメトリクスに基づいてデプロイメントをスケーリングできるようになりました。

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

手順

  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
        metricsServer:
          logLevel: '0' 4
          auditConfig: 5
            logFormat: "json"
            logOutputVolumeClaim: "persistentVolumeClaimName"
            policy:
              rules:
              - level: Metadata
              omitStages: "RequestReceived"
              omitManagedFields: false
            lifetime:
              maxAge: "2"
              maxBackup: "1"
              maxSize: "50"
        serviceAccount: {}
      1
      カスタムオートスケーラーが監視する namespace を指定します。コンマ区切りのリストに名前を入力します。すべての namespace を監視するには、省略するか空に設定します。デフォルトは空です。
      2
      Custom Metrics Autoscaler Operator ログメッセージの詳細レベルを指定します。許可される値は debuginfoerror です。デフォルトは info です。
      3
      Custom Metrics Autoscaler Operator ログメッセージのログ形式を指定します。許可される値は console または json です。デフォルトは コンソール です。
      4
      Custom Metrics Autoscaler Metrics Server のログレベルを指定します。許可される値は、info の場合は 0 で、debug の場合は 4 です。デフォルトは 0 です。
      5
      Custom Metrics Autoscaler Operator の監査ログをアクティブにして、使用する監査ポリシーを指定します (「監査ログの設定」セクションを参照)。
    5. Create をクリックして、KEDAController を作成します。

3.4. カスタムメトリックオートスケーラートリガーについて

スケーラーとも呼ばれるトリガーは、Custom Metrics Autoscaler Operator が Pod をスケーリングするために使用するメトリックを提供します。

カスタムメトリクスオートスケーラーは現在、Prometheus、CPU、メモリー、および Apache Kafka トリガーのみをサポートしています。

以下のセクションで説明するように、ScaledObject または ScaledJob カスタムリソースを使用して、特定のオブジェクトのトリガーを設定します。

3.4.1. Prometheus トリガーについて

Prometheus メトリクスに基づいて Pod をスケーリングできます。このメトリクスは、インストール済みの OpenShift Container Platform モニタリングまたは外部 Prometheus サーバーをメトリクスソースとして使用できます。OpenShift Container Platform モニタリングをメトリクスのソースとして使用するために必要な設定は、「関連情報」を参照してください。

注記

カスタムメトリクスオートスケーラーがスケーリングしているアプリケーションから Prometheus がメトリクスを収集している場合は、カスタムリソースで最小レプリカ数を 0 に設定しないでください。アプリケーション Pod がない場合、カスタムメトリックオートスケーラーにはスケールするメトリックがありません。

Prometheus ターゲットを使用したスケーリングされたオブジェクトの例

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)、または TLS 認証 (tls) をサポートしています。以下のセクションで説明するように、トリガー認証で特定の認証パラメーターを設定します。必要に応じて、シークレットを使用することもできます。
8
オプション: X-Scope-OrgID ヘッダーを Prometheus のマルチテナント Cortex または Mimir ストレージに渡します。このパラメーターは、Prometheus が返す必要のあるデータを示すために、マルチテナント Prometheus ストレージでのみ必要です。
9
オプション: Prometheus ターゲットが失われた場合のトリガーの処理方法を指定します。
  • true の場合、Prometheus ターゲットが失われても、トリガーは動作し続けます。これがデフォルトの動作です。
  • false の場合、Prometheus ターゲットが失われると、トリガーはエラーを返します。
10
オプション: 証明書チェックをスキップするかどうかを指定します。たとえば、Prometheus エンドポイントで自己署名証明書を使用する場合は、チェックをスキップできます。
  • true の場合、証明書チェックが実行されます。
  • false の場合、証明書チェックは実行されません。これがデフォルトの動作です。

3.4.1.1. Configuring the custom metrics autoscaler to use OpenShift Container Platform monitoring

カスタムメトリクスオートスケーラーが使用するメトリクスのソースとして、インストール済みの OpenShift Container Platform Prometheus モニタリングを使用できます。ただし、実行する必要がある追加の設定がいくつかあります。

注記

これらの手順は、外部 Prometheus ソースには必要ありません。

このセクションで説明するように、次のタスクを実行する必要があります。

  • トークンを取得するためのサービスアカウントを作成します。
  • ロールを作成します。
  • そのロールをサービスアカウントに追加します。
  • Prometheus が使用するトリガー認証オブジェクトでトークンを参照します。

前提条件

  • OpenShift Container Platform モニタリングをインストールしている必要がある。
  • ユーザー定義のワークロードのモニタリングを、OpenShift Container Platform モニタリングで有効にする必要がある (ユーザー定義のワークロードモニタリング設定マップの作成 セクションで説明)。
  • Custom Metrics Autoscaler Operator をインストールしている必要がある。

手順

  1. スケーリングするオブジェクトを含むプロジェクトに変更します。

    $ oc project my-project
  2. クラスターにサービスアカウントがない場合は、次のコマンドを使用してサービスアカウントを作成します。

    $ oc create serviceaccount <service_account>

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

    <service_account>
    サービスアカウントの名前を指定します。
  3. 次のコマンドを使用して、サービスアカウントに割り当てられたトークンを見つけます。

    $ oc describe serviceaccount <service_account>

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

    <service_account>
    サービスアカウントの名前を指定します。

    出力例

    Name:                thanos
    Namespace:           my-project
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  thanos-dockercfg-nnwgj
    Mountable secrets:   thanos-dockercfg-nnwgj
    Tokens:              thanos-token-9g4n5 1
    Events:              <none>

    1
    トリガー認証でこのトークンを使用します。
  4. サービスアカウントトークンを使用してトリガー認証を作成します。

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

      apiVersion: keda.sh/v1alpha1
      kind: TriggerAuthentication
      metadata:
        name: keda-trigger-auth-prometheus
      spec:
        secretTargetRef: 1
        - parameter: bearerToken 2
          name: thanos-token-9g4n5 3
          key: token 4
        - parameter: ca
          name: thanos-token-9g4n5
          key: ca.crt
      1
      このオブジェクトが承認にシークレットを使用することを指定します。
      2
      トークンを使用して提供する認証パラメーターを指定します。
      3
      使用するトークンの名前を指定します。
      4
      指定されたパラメーターで使用するトークン内のキーを指定します。
    2. CR オブジェクトを作成します。

      $ oc create -f <file-name>.yaml
  5. 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
  6. 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 ターゲットを使用してスケーリングされたオブジェクトの例

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
      containerName: api 4

1
トリガータイプとして CPU を指定します。
2
使用するメトリックのタイプ (Utilization または AverageValue のいずれか) を指定します。
3
スケーリングをトリガーする値を指定します。引用符で囲まれた文字列値として指定する必要があります。
  • Utilization を使用する場合、ターゲット値は、関連する全 Pod のリソースメトリクスの平均値であり、Pod のリソースの要求値に占めるパーセンテージとして表されます。
  • AverageValue を使用する場合、ターゲット値は、関連する全 Pod のメトリクスの平均値です。
4
オプション: Pod 全体ではなく、そのコンテナーのみのメモリー使用率に基づいて、スケーリングする個々のコンテナーを指定します。この例では、api という名前のコンテナーのみがスケーリングされます。

3.4.3. メモリートリガーについて

メモリーメトリクスに基づいて Pod をスケーリングできます。このトリガーは、クラスターメトリクスをメトリクスのソースとして使用します。

カスタムメトリクスオートスケーラーは、オブジェクトに関連付けられた Pod をスケーリングして、指定されたメモリー使用率を維持します。オートスケーラーは、すべての Pod で指定のメモリー使用率を維持するために、最小数と最大数の間でレプリカ数を増減します。メモリートリガーは、Pod 全体のメモリー使用率を考慮します。Pod に複数のコンテナーがある場合、メモリー使用率はすべてのコンテナーの合計になります。

注記
  • このトリガーは、ScaledJob カスタムリソースでは使用できません。
  • メモリートリガーを使用してオブジェクトをスケーリングすると、複数のトリガーを使用している場合でも、オブジェクトは 0 にスケーリングされません。

メモリーターゲットを使用してスケーリングされたオブジェクトの例

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 ターゲットを使用してスケーリングされたオブジェクトの例

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

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 のみが考慮されます。引用符で囲まれた文字列値として指定する必要があります。デフォルトでは、すべてのパーティションが考慮されます。

3.5. カスタムメトリクスオートスケーラートリガー認証について

トリガー認証を使用すると、関連付けられたコンテナーで使用できるスケーリングされたオブジェクトまたはスケーリングされたジョブに認証情報を含めることができます。トリガー認証を使用して、OpenShift Container Platform シークレット、プラットフォームネイティブの Pod 認証メカニズム、環境変数などを渡すことができます。

スケーリングするオブジェクトと同じ namespace に TriggerAuthentication オブジェクトを定義します。そのトリガー認証は、その namespace 内のオブジェクトによってのみ使用できます。

または、複数の namespace のオブジェクト間で認証情報を共有するには、すべての namespace で使用できる ClusterTriggerAuthentication オブジェクトを作成できます。

トリガー認証とクラスタートリガー認証は同じ設定を使用します。ただし、クラスタートリガー認証では、スケーリングされたオブジェクトの認証参照に追加の kind パラメーターが必要です。

シークレットを使用したトリガー認証の例

kind: TriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata:
  name: secret-triggerauthentication
  namespace: my-namespace 1
spec:
  secretTargetRef: 2
  - parameter: user-name 3
    name: my-secret 4
    key: USER_NAME 5
  - parameter: password
    name: my-secret
    key: USER_PASSWORD

1
スケーリングするオブジェクトの namespace を指定します。
2
このトリガー認証が承認にシークレットを使用することを指定します。
3
シークレットを使用して提供する認証パラメーターを指定します。
4
使用するシークレットの名前を指定します。
5
指定されたパラメーターで使用するシークレットのキーを指定します。

シークレットを使用したクラスタートリガー認証の例

kind: ClusterTriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata: 1
  name: secret-cluster-triggerauthentication
spec:
  secretTargetRef: 2
  - parameter: user-name 3
    name: secret-name 4
    key: USER_NAME 5
  - parameter: user-password
    name: secret-name
    key: USER_PASSWORD

1
クラスタートリガー認証では namespace が使用されないことに注意してください。
2
このトリガー認証が承認にシークレットを使用することを指定します。
3
シークレットを使用して提供する認証パラメーターを指定します。
4
使用するシークレットの名前を指定します。
5
指定されたパラメーターで使用するシークレットのキーを指定します。

トークンを使用したトリガー認証の例

kind: TriggerAuthentication
apiVersion: keda.sh/v1alpha1
metadata:
  name: token-triggerauthentication
  namespace: my-namespace 1
spec:
  secretTargetRef: 2
  - parameter: bearerToken 3
    name: my-token-2vzfq 4
    key: token 5
  - parameter: ca
    name: my-token-2vzfq
    key: ca.crt

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 を指定します。サポートされている値は、noneazureaws-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 <file-name>.yaml
  2. ScaledObject 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:
      - authenticationRef:
        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: 1
            name: prom-triggerauthentication
          metadata:
            name: prom-triggerauthentication
          type: object
        - authenticationRef: 2
            name: prom-cluster-triggerauthentication
            kind: ClusterTriggerAuthentication
          metadata:
            name: prom-cluster-triggerauthentication
          type: object

    1
    オプション: トリガー認証を指定します。
    2
    オプション: クラスタートリガー認証を指定します。kind: ClusterTriggerAuthentication パラメーターを含める必要があります。
    注記

    namespace トリガー認証とクラスタートリガー認証の両方を指定する必要はありません。

  3. オブジェクトを作成します。以下に例を示します。

    $ oc apply -f <file-name>

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.26","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 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
        metadata:
          name: prom-triggerauthentication
        type: object
      - authenticationRef: 18
          name: prom-cluster-triggerauthentication
        metadata:
          name: prom-cluster-triggerauthentication
        type: object

    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
    オプション: カスタムメトリックオートスケーラートリガー認証の作成のセクションで説明されているように、トリガー認証を指定します。
    18
    オプション: カスタムメトリックオートスケーラートリガー認証の作成のセクションで説明されているように、クラスタートリガー認証を指定します。
    注記

    namespace トリガー認証とクラスタートリガー認証の両方を指定する必要はありません。

  2. カスタムメトリックオートスケーラーを作成します。

    $ oc create -f <file-name>.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-triggerauthentication
        metadata:
          name: prom-triggerauthentication
         type: object
      - authenticationRef: 15
          name: prom-cluster-triggerauthentication
        metadata:
          name: prom-cluster-triggerauthentication
        type: object
    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 : 関連するスケーリングされたジョブが更新されると、オートスケーラーは既存のジョブを終了します。オートスケーラーは、最新の仕様でジョブを再作成します。
    • gradual : 関連するスケーリングされたジョブが更新された場合、オートスケーラーは既存のジョブを終了しません。オートスケーラーは、最新の仕様で新しいジョブを作成します。
    12
    オプション: スケーリングストラテジーを指定します: defaultcustom、または accurate。デフォルトは default です。詳細については、以下の関連情報セクションのリンクを参照してください。
    13
    カスタムメトリックオートスケーラートリガーについてのセクションで説明されているように、スケーリングの基礎として使用するトリガーを指定します。
    14
    オプション: カスタムメトリックオートスケーラートリガー認証の作成のセクションで説明されているように、トリガー認証を指定します。
    15
    オプション: カスタムメトリックオートスケーラートリガー認証の作成のセクションで説明されているように、クラスタートリガー認証を指定します。
    注記

    namespace トリガー認証とクラスタートリガー認証の両方を指定する必要はありません。

  2. カスタムメトリックオートスケーラーを作成します。

    $ oc create -f <file-name>.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.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: failure-domain.beta.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.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. 関連情報

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. ノードテイントを使用した Pod 配置の制御

テイントおよび容認 (Toleration) により、ノードはノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。

4.6.1. テイントおよび容認 (Toleration) について

テイント により、ノードは Pod に一致する 容認 がない場合に Pod のスケジュールを拒否することができます。

テイントは Node 仕様 (NodeSpec) でノードに適用され、容認は Pod 仕様 (PodSpec) で Pod に適用されます。テイントをノードに適用する場合、スケジューラーは Pod がテイントを容認しない限り、Pod をそのノードに配置することができません。

ノード仕様のテイントの例

apiVersion: v1
kind: Node
metadata:
  name: my-node
#...
spec:
  taints:
  - effect: NoExecute
    key: key1
    value: value1
#...

Pod 仕様での容認の例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
#...
spec:
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoExecute"
    tolerationSeconds: 3600
#...

テイントおよび容認は、key、value、および effect で設定されています。

表4.1 テイントおよび容認コンポーネント

パラメーター説明

key

key には、253 文字までの文字列を使用できます。キーは文字または数字で開始する必要があり、文字、数字、ハイフン、ドットおよびアンダースコアを含めることができます。

value

value には、63 文字までの文字列を使用できます。値は文字または数字で開始する必要があり、文字、数字、ハイフン、ドットおよびアンダースコアを含めることができます。

effect

effect は以下のいずれかにすることができます。

NoSchedule [1]

  • テイントに一致しない新規 Pod はノードにスケジュールされません。
  • ノードの既存 Pod はそのままになります。

PreferNoSchedule

  • テイントに一致しない新規 Pod はノードにスケジュールされる可能性がありますが、スケジューラーはスケジュールしないようにします。
  • ノードの既存 Pod はそのままになります。

NoExecute

  • テイントに一致しない新規 Pod はノードにスケジュールできません。
  • 一致する容認を持たないノードの既存 Pod は削除されます。

operator

Equal

key/value/effect パラメーターは一致する必要があります。これはデフォルトになります。

Exists

key/effect パラメーターは一致する必要があります。いずれかに一致する value パラメーターを空のままにする必要があります。

  1. NoSchedule テイントをコントロールプレーンノードに追加する場合、ノードには、デフォルトで追加される node-role.kubernetes.io/master=:NoSchedule テイントが必要です。

    以下に例を示します。

    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
    #...

容認はテイントと一致します。

  • operator パラメーターが Equal に設定されている場合:

    • key パラメーターは同じになります。
    • value パラメーターは同じになります。
    • effect パラメーターは同じになります。
  • operator パラメーターが Exists に設定されている場合:

    • key パラメーターは同じになります。
    • effect パラメーターは同じになります。

以下のテイントは 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: ノードコントローラーが外部のクラウドプロバイダーを使用して起動すると、このテイントはノード上に設定され、使用不可能とマークされます。cloud-controller-manager のコントローラーがこのノードを初期化した後に、kubelet がこのテイントを削除します。
  • node.kubernetes.io/pid-pressure: ノードが pid 不足の状態です。これはノード条件 PIDPressure=True に対応します。

    重要

    OpenShift Container Platform では、デフォルトの pid.available evictionHard は設定されません。

4.6.1.1. Pod のエビクションを遅延させる容認期間 (秒数) の使用方法

Pod 仕様または MachineSettolerationSeconds パラメーターを指定して、Pod がエビクションされる前にノードにバインドされる期間を指定できます。effect が NoExecute のテイントがノードに追加される場合、テイントを容認する Pod に tolerationSeconds パラメーターがある場合、Pod は期限切れになるまでエビクトされません。

出力例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
#...
spec:
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoExecute"
    tolerationSeconds: 3600
#...

ここで、この Pod が実行中であるものの、一致する容認がない場合、Pod は 3,600 秒間バインドされたままとなり、その後にエビクトされます。テイントが期限前に削除される場合、Pod はエビクトされません。

4.6.1.2. 複数のテイントの使用方法

複数のテイントを同じノードに、複数の容認を同じ Pod に配置することができます。OpenShift Container Platform は複数のテイントと容認を以下のように処理します。

  1. Pod に一致する容認のあるテイントを処理します。
  2. 残りの一致しないテイントは Pod について以下の effect を持ちます。

    • effect が NoSchedule の一致しないテイントが 1 つ以上ある場合、OpenShift Container Platform は Pod をノードにスケジュールできません。
    • effect が NoSchedule の一致しないテイントがなく、effect が PreferNoSchedule の一致しない テイントが 1 つ以上ある場合、OpenShift Container Platform は Pod のノードへのスケジュールを試行しません。
    • effect が NoExecute のテイントが 1 つ以上ある場合、OpenShift Container Platform は Pod をノードからエビクトするか (ノードですでに実行中の場合)、または Pod のそのノードへのスケジュールが実行されません (ノードでまだ実行されていない場合)。

      • テイントを容認しない Pod はすぐにエビクトされます。
      • Pod の仕様に tolerationSeconds を指定せずにテイントを容認する Pod は永久にバインドされたままになります。
      • 指定された tolerationSeconds を持つテイントを容認する Pod は指定された期間バインドされます。

以下に例を示します。

  • 以下のテイントをノードに追加します。

    $ 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 には以下の容認があります。

    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 つ目のテイントに一致する容認がないため、Pod はノードにスケジュールできません。Pod はこのテイントの追加時にノードですでに実行されている場合は実行が継続されます。3 つ目のテイントは 3 つのテイントの中で Pod で容認されない唯一のテイントであるためです。

4.6.1.3. Pod のスケジューリングとノードの状態 (Taint Nodes By Condition) について

Taint Nodes By Condition (状態別のノードへのテイント) 機能はデフォルトで有効にされており、これはメモリー不足やディスク不足などの状態を報告するノードを自動的にテイントします。ノードが状態を報告すると、その状態が解消するまでテイントが追加されます。テイントに NoSchedule の effect がある場合、ノードが一致する容認を持つまでそのノードに Pod をスケジュールすることはできません。

スケジューラーは、Pod をスケジュールする前に、ノードでこれらのテイントの有無をチェックします。テイントがある場合、Pod は別のノードにスケジュールされます。スケジューラーは実際のノードの状態ではなくテイントをチェックするので、適切な Pod 容認を追加して、スケジューラーがこのようなノードの状態を無視するように設定します。

デーモンセットコントローラーは、以下の容認をすべてのデーモンに自動的に追加し、下位互換性を確保します。

  • node.kubernetes.io/memory-pressure
  • node.kubernetes.io/disk-pressure
  • node.kubernetes.io/unschedulable (1.10 以降)
  • node.kubernetes.io/network-unavailable (ホストネットワークのみ)

デーモンセットには任意の容認を追加することも可能です。

注記

コントロールプレーンは、QoS クラスを持つ Pod に node.kubernetes.io/memory-pressure 容認も追加します。これは、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 はテイントをノードに自動的に追加して、Pod のエビクトおよび別のノードでの再スケジュールを開始します。

Taint Based Eviction には NoExecute の effect があり、そのテイントを容認しない Pod はすぐにエビクトされ、これを容認する Pod はエビクトされません (Pod が tolerationSeconds パラメーターを使用しない場合に限ります)。

tolerationSeconds パラメーターを使用すると、ノード状態が設定されたノードに Pod がどの程度の期間バインドされるかを指定することができます。tolerationSeconds の期間後もこの状態が続くと、テイントはノードに残り続け、一致する容認を持つ Pod はエビクトされます。tolerationSeconds の期間前にこの状態が解消される場合、一致する容認を持つ Pod は削除されません。

値なしで tolerationSeconds パラメーターを使用する場合、Pod は not ready(準備未完了) および unreachable(到達不能) のノードの状態が原因となりエビクトされることはありません。

注記

OpenShift Container Platform は、レートが制限された方法で Pod をエビクトし、マスターがノードからパーティション化される場合などのシナリオで発生する大規模な Pod エビクションを防ぎます。

デフォルトでは、特定のゾーン内のノードの 55% 以上が 異常である場合、ノードライフサイクルコントローラーはそのゾーンの状態を PartialDisruption に変更し、Pod の削除率が低下します。この状態の小さなクラスター (デフォルトでは 50 ノード以下) の場合、このゾーンのノードはテイントされず、排除が停止されます。

詳細については、Kubernetes ドキュメントの Rate limits on eviction を参照してください。

OpenShift Container Platform は、node.kubernetes.io/not-ready および node.kubernetes.io/unreachable の容認を、Pod 設定がいずれかの容認を指定しない限り、自動的に 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
これらの容認は、ノード状態の問題のいずれかが検出された後、デフォルトの Pod 動作のバインドを 5 分間維持できるようにします。

これらの容認は必要に応じて設定できます。たとえば、アプリケーションに多数のローカル状態がある場合、ネットワークのパーティション化などに伴い、Pod をより長い時間ノードにバインドさせる必要があるかもしれません。 これにより、パーティションを回復させることができ、Pod のエビクションを回避できます。

デーモンセットによって起動する Pod は、tolerationSeconds が指定されない以下のテイントの NoExecute 容認を使用して作成されます。

  • node.kubernetes.io/unreachable
  • node.kubernetes.io/not-ready

その結果、デーモンセット Pod は、これらのノードの状態が原因でエビクトされることはありません。

4.6.1.5. すべてのテイントの許容

ノードは、operator: "Exists" 容認を key および value パラメーターなしで追加することですべてのテイントを容認するように Pod を設定できます。この容認のある Pod はテイントを持つノードから削除されません。

すべてのテイントを容認するための Pod 仕様

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
#...
spec:
  tolerations:
  - operator: "Exists"
#...

4.6.2. テイントおよび容認 (Toleration) の追加

容認を Pod に、テイントをノードに追加することで、ノードはノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。既存の Pod およびノードの場合、最初に容認を Pod に追加してからテイントをノードに追加して、容認を追加する前に Pod がノードから削除されないようにする必要があります。

手順

  1. Pod 仕様を tolerations スタンザを含めるように編集して、容認を 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
    テイントおよび容認コンポーネント の表で説明されている 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 を取りません。

    この例では、テイントを、キー key1、値 value1、およびテイント effect NoExecute を持つ node1 にテイントを配置します。

  2. テイントおよび容認コンポーネント の表で説明されているパラメーターと共に以下のコマンドを使用してテイントをノードに追加します。

    $ oc adm taint nodes <node_name> <key>=<value>:<effect>

    以下に例を示します。

    $ oc adm taint nodes node1 key1=value1:NoExecute

    このコマンドは、キー key1、値 value1、および effect NoExecute を持つテイントを node1 に配置します。

    注記

    NoSchedule テイントをコントロールプレーンノードに追加する場合、ノードには、デフォルトで追加される node-role.kubernetes.io/master=:NoSchedule テイントが必要です。

    以下に例を示します。

    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 の容認はノードのテイントに一致します。いずれかの容認のある Pod は node1 にスケジュールできます。

4.6.2.1. マシンセットを使用したテイントおよび容認の追加

マシンセットを使用してテイントをノードに追加できます。MachineSet オブジェクトに関連付けられるすべてのノードがテイントで更新されます。容認は、ノードに直接追加されたテイントと同様に、マシンセットによって追加されるテイントに応答します。

手順

  1. Pod 仕様を tolerations スタンザを含めるように編集して、容認を 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
    テイントおよび容認コンポーネント の表で説明されている 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. テイントを MachineSet オブジェクトに追加します。

    1. テイントを付けるノードの MachineSet YAML を編集するか、新規 MachineSet オブジェクトを作成できます。

      $ oc edit machineset <machineset>
    2. テイントを spec.template.spec セクションに追加します。

      マシンセット仕様のテイントの例

      apiVersion: machine.openshift.io/v1beta1
      kind: MachineSet
      metadata:
        name: my-machineset
      #...
      spec:
      #...
        template:
      #...
          spec:
            taints:
            - effect: NoExecute
              key: key1
              value: value1
      #...

      この例では、キー key1、値 value1、およびテイント effect NoExecute を持つテイントをノードに配置します。

    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

      マシンが起動するまで待ちます。テイントは MachineSet オブジェクトに関連付けられたノードに追加されます。

4.6.2.2. テイントおよび容認 (Toleration) 使用してユーザーをノードにバインドする

ノードのセットを特定のユーザーセットによる排他的な使用のために割り当てる必要がある場合、容認をそれらの Pod に追加します。次に、対応するテイントをそれらのノードに追加します。容認が設定された Pod は、テイントが付けられたノードまたはクラスター内の他のノードを使用できます。

Pod がテイントが付けられたノードのみにスケジュールされるようにするには、ラベルを同じノードセットに追加し、ノードのアフィニティーを Pod に追加し、Pod がそのラベルの付いたノードのみにスケジュールできるようにします。

手順

ノードをユーザーの使用可能な唯一のノードとして設定するには、以下を実行します。

  1. 対応するテイントをそれらのノードに追加します。

    以下に例を示します。

    $ oc adm taint nodes node1 dedicated=groupName:NoSchedule
    ヒント

    または、以下の YAML を適用してテイントを追加できます。

    kind: Node
    apiVersion: v1
    metadata:
      name: my-node
    #...
    spec:
      taints:
        - key: dedicated
          value: groupName
          effect: NoSchedule
    #...
  2. カスタム受付コントローラーを作成して容認を Pod に追加します。

4.6.2.3. ノードセレクターおよび容認を使用したプロジェクトの作成

ノードセレクターおよび容認 (アノテーションとして設定されたもの) を使用するプロジェクトを作成して、Pod の特定のノードへの配置を制御できます。プロジェクトで作成された後続のリソースは、容認に一致するテイントを持つノードでスケジュールされます。

前提条件

  • マシンセットを使用するか、ノードを直接編集して、ノード選択のラベルが 1 つ以上のノードに追加されている。
  • マシンセットを使用するか、ノードを直接編集して、テイントが 1 つ以上のノードに追加されている。

手順

  1. metadata.annotations セクションにノードセレクターおよび容認を指定して、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
    テイントおよび容認コンポーネント の表で説明されている toleration パラメーターです。この例では、NoSchedule の effect を使用します。これにより、ノード上の既存の Pod はそのまま残り、Exists Operator は値を取得しません。
  2. oc apply コマンドを使用してプロジェクトを作成します。

    $ oc apply -f project.yaml

<project_name> namespace で作成された後続のリソースは指定されたノードにスケジュールされます。

4.6.2.4. テイントおよび容認 (Toleration) を使用して特殊ハードウェアを持つノードを制御する

ノードの小規模なサブセットが特殊ハードウェアを持つクラスターでは、テイントおよび容認 (Toleration) を使用して、特殊ハードウェアを必要としない Pod をそれらのノードから切り離し、特殊ハードウェアを必要とする Pod をそのままにすることができます。また、特殊ハードウェアを必要とする Pod に対して特定のノードを使用することを要求することもできます。

これは、特殊ハードウェアを必要とする Pod に容認を追加し、特殊ハードウェアを持つノードにテイントを付けることで実行できます。

手順

特殊ハードウェアを持つノードが特定の Pod 用に予約されるようにするには、以下を実行します。

  1. 容認を特別なハードウェアを必要とする Pod に追加します。

    以下に例を示します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    #...
    spec:
      tolerations:
        - key: "disktype"
          value: "ssd"
          operator: "Equal"
          effect: "NoSchedule"
          tolerationSeconds: 3600
    #...
  2. 以下のコマンドのいずれかを使用して、特殊ハードウェアを持つノードにテイントを設定します。

    $ oc adm taint nodes <node-name> disktype=ssd:NoSchedule

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

    $ oc adm taint nodes <node-name> disktype=ssd:PreferNoSchedule
    ヒント

    または、以下の YAML を適用してテイントを追加できます。

    kind: Node
    apiVersion: v1
    metadata:
      name: my_node
    #...
    spec:
      taints:
        - key: disktype
          value: ssd
          effect: PreferNoSchedule
    #...

4.6.3. テイントおよび容認 (Toleration) の削除

必要に応じてノードからテイントを、Pod から容認をそれぞれ削除できます。最初に容認を Pod に追加してからテイントをノードに追加して、容認を追加する前に Pod がノードから削除されないようにする必要があります。

手順

テイントおよび容認 (Toleration) を削除するには、以下を実行します。

  1. ノードからテイントを削除するには、以下を実行します。

    $ 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 から容認を削除するには、容認を削除するための 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
    failure-domain.beta.kubernetes.io/zone: us-east-1a
    node.openshift.io/os_version: '4.5'
    node-role.kubernetes.io/worker: ''
    failure-domain.beta.kubernetes.io/region: us-east-1
    node.openshift.io/os_id: rhcos
    beta.kubernetes.io/instance-type: m4.large
    kubernetes.io/hostname: ip-10-0-131-14
    beta.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.23.0

  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.23.0

    • ラベルをノードに直接追加します。

      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.23.0

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.23.0

    • ラベルをノードに直接追加します。

      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.23.0

4.8. Pod トポロジー分散制約を使用した Pod 配置の制御

Pod トポロジー分散制約を使用して、ノード、ゾーン、リージョンその他のユーザー定義のトポロジードメイン間で Pod の配置を制御できます。

4.8.1. Pod トポロジー分散制約について

Pod トポロジー分散制約 を使用することで、障害ドメイン全体にまたがる Pod の分散に対する詳細な制御を実現し、高可用性とより効率的なリソースの使用を実現できます。

OpenShift Container Platform 管理者はノードにラベルを付け、リージョン、ゾーン、ノード、他のユーザー定義ドメインなどのトポロジー情報を提供できます。これらのラベルをノードに設定した後に、ユーザーは Pod トポロジーの分散制約を定義し、これらのトポロジードメイン全体での Pod の配置を制御できます。

グループ化する Pod を指定し、それらの Pod が分散されるトポロジードメインと、許可できるスキューを指定します。制約により、分散される際に同じ namespace 内の Pod のみが一致し、グループ化されます。

4.8.2. Pod トポロジー分散制約の設定

以下の手順は、Pod トポロジー分散制約を、ゾーンに基づいて指定されたラベルに一致する Pod を分散するように設定する方法を示しています。

複数の Pod トポロジー分散制約を指定できますが、それらが互いに競合しないようにする必要があります。Pod を配置するには、すべての Pod トポロジー分散制約を満たしている必要があります。

前提条件

  • クラスター管理者は、必要なラベルをノードに追加している。

手順

  1. Pod 仕様を作成し、Pod トポロジーの分散制約を指定します。

    pod-spec.yaml ファイルの例

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
      labels:
        region: us-east
    spec:
      topologySpreadConstraints:
      - maxSkew: 1 1
        topologyKey: topology.kubernetes.io/zone 2
        whenUnsatisfiable: DoNotSchedule 3
        labelSelector: 4
          matchLabels:
            region: us-east 5
      containers:
      - image: "docker.io/ocpqe/hello-pod"
        name: hello-pod

    1
    任意の 2 つのトポロジードメイン間の Pod 数の最大差。デフォルトは 1 で、0 の値を指定することはできません。
    2
    ノードラベルのキー。このキーと同じ値を持つノードは同じトポロジーにあると見なされます。
    3
    分散制約を満たさない場合に Pod を処理する方法です。デフォルトは DoNotSchedule であり、これはスケジューラーに Pod をスケジュールしないように指示します。ScheduleAnyway に設定して Pod を依然としてスケジュールできますが、スケジューラーはクラスターがさらに不均衡な状態になるのを防ぐためにスキューの適用を優先します。
    4
    制約を満たすために、分散される際に、このラベルセレクターに一致する Pod はグループとしてカウントされ、認識されます。ラベルセレクターを指定してください。指定しないと、Pod が一致しません。
    5
    今後適切にカウントされるようにするには、この Pod 仕様がこのラベルセレクターに一致するようにラベルを設定していることも確認してください。
  2. Pod を作成します。

    $ oc create -f pod-spec.yaml

4.8.3. Pod トポロジー分散制約の例

以下の例は、Pod トポロジー設定分散制約の設定を示しています。

4.8.3.1. 単一 Pod トポロジー分散制約の例

このサンプル Pod 仕様は単一の Pod トポロジー分散制約を定義します。これは region: us-east というラベルが付いた Pod で一致し、ゾーン間で分散され、スキューの 1 を指定し、これらの要件を満たさない場合に 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

4.8.3.2. 複数の Pod トポロジー分散制約の例

このサンプル Pod 仕様は 2 つの Pod トポロジー分散制約を定義します。どちらも region: us-east というラベルの付いた Pod に一致し、スキューを 1 に指定し、これらの要件を満たしていない場合は Pod はスケジュールされません。

最初の制約は、ユーザー定義ラベルの node に基づいて Pod を分散し、2 つ目の制約はユーザー定義ラベルの rack に基づいて 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

4.8.4. 関連情報

4.9. カスタムスケジューラーの実行

デフォルトのスケジューラーと共に複数のカスタムスケジューラーを実行し、各 Pod に使用するスケジューラーを設定できます。

重要

これは OpenShift Container Platform でカスタムスケジューラーを使用することはサポートされていますが、Red Hat ではカスタムスケジューラーの機能を直接サポートしません。

デフォルトのスケジューラーを設定する方法については、Controlling pod placement using the scheduler を参照してください。

特定のスケジューラーを使用して指定された Pod をスケジュールするには、Pod の仕様にスケジューラーの名前を指定 します。

4.9.1. カスタムスケジューラーのデプロイ

クラスターにカスタムスケジューラーを追加するには、デプロイメントにカスタムスケジューラーのイメージを追加します。

前提条件

  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。
  • スケジューラーバイナリーがある。

    注記

    スケジューラーバイナリーの作成方法に関する情報は、本書では扱っておりません。たとえば、Kubernetes ドキュメントの Configure Multiple Schedulers を参照してください。カスタムスケジューラーの実際の機能は、Red Hat ではサポートされない点に留意してください。

  • スケジューラーバイナリーを含むイメージを作成し、これをレジストリーにプッシュしている。

手順

  1. スケジューラー設定ファイルを保持する設定マップを含むファイルを作成します。

    scheduler-config-map.yaml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: scheduler-config
      namespace: kube-system 1
    data:
      scheduler-config.yaml: | 2
        apiVersion: kubescheduler.config.k8s.io/v1beta2
        kind: KubeSchedulerConfiguration
        profiles:
          - schedulerName: custom-scheduler 3
        leaderElection:
          leaderElect: false

    1
    この手順では、kube-system namespace を使用しますが、お好みの namespace を使用することができます。
    2
    この手順の後半で Deployment リソースを定義するときに、--config 引数を使用して、このファイルをスケジューラーコマンドに渡します。
    3
    カスタムスケジューラーのスケジューラープロファイルを定義します。このスケジューラー名は、Pod 設定で schedulerName を定義する際に使用されます。
  2. ConfigMap を作成します。

    $ oc create -f scheduler-config-map.yaml
  3. カスタムスケジューラーのデプロイメントリソースを含むファイルを作成します。

    custom-scheduler.yaml ファイルの例

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: custom-scheduler
      namespace: kube-system 1
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: custom-scheduler-as-kube-scheduler
    subjects:
    - kind: ServiceAccount
      name: custom-scheduler
      namespace: kube-system 2
    roleRef:
      kind: ClusterRole
      name: system:kube-scheduler
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: custom-scheduler-as-volume-scheduler
    subjects:
    - kind: ServiceAccount
      name: custom-scheduler
      namespace: kube-system 3
    roleRef:
      kind: ClusterRole
      name: system:volume-scheduler
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        component: scheduler
        tier: control-plane
      name: custom-scheduler
      namespace: kube-system 4
    spec:
      selector:
        matchLabels:
          component: scheduler
          tier: control-plane
      replicas: 1
      template:
        metadata:
          labels:
            component: scheduler
            tier: control-plane
            version: second
        spec:
          serviceAccountName: custom-scheduler
          containers:
          - command:
            - /usr/local/bin/kube-scheduler
            - --config=/etc/config/scheduler-config.yaml 5
            image: "<namespace>/<image_name>:<tag>" 6
            livenessProbe:
              httpGet:
                path: /healthz
                port: 10259
                scheme: HTTPS
              initialDelaySeconds: 15
            name: kube-second-scheduler
            readinessProbe:
              httpGet:
                path: /healthz
                port: 10259
                scheme: HTTPS
            resources:
              requests:
                cpu: '0.1'
            securityContext:
              privileged: false
            volumeMounts:
            - name: config-volume
              mountPath: /etc/config
          hostNetwork: false
          hostPID: false
          volumes:
            - name: config-volume
              configMap:
                name: scheduler-config

    1 2 3 4
    この手順では、kube-system namespace を使用しますが、お好みの namespace を使用することができます。
    5
    カスタムスケジューラーのコマンドには、異なる引数が必要な場合があります。
    6
    カスタムスケジューラー用に作成したコンテナーイメージを指定します。
  4. クラスター内にデプロイメントリソースを作成します。

    $ oc create -f custom-scheduler.yaml

検証

  • スケジューラー Pod が実行されていることを確認します。

    $ oc get pods -n kube-system

    カスタムスケジューラー Pod は Running としてリスト表示されます。

    NAME                                                       READY   STATUS    RESTARTS   AGE
    custom-scheduler-6cd7c4b8bc-854zb                          1/1     Running   0          2m

4.9.2. カスタムスケジューラーを使用した Pod のデプロイ

カスタムスケジューラーをクラスターにデプロイした後、デフォルトのスケジューラーではなくそのスケジューラーを使用するように Pod を設定できます。

注記

各スケジューラーには、クラスター内のリソースの個別のビューがあります。このため、各スケジューラーは独自のノードセットを動作する必要があります。

2 つ以上のスケジューラーが同じノードで動作する場合、それらは互いに介入し、利用可能なリソースよりも多くの Pod を同じノードにスケジュールする可能性があります。この場合、Pod はリソースが十分にないために拒否される可能性があります。

前提条件

  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。
  • カスタムスケジューラーがクラスターにデプロイされている。

手順

  1. クラスターがロールベースアクセス制御 (RBAC) を使用する場合は、カスタムスケジューラー名を system:kube-scheduler クラスターロールに追加します。

    1. system:kube-scheduler クラスターロールを編集します。

      $ oc edit clusterrole system:kube-scheduler
    2. カスタムスケジューラーの名前を、leases および endpoints リソースの resourceNames リストに追加します。

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        annotations:
          rbac.authorization.kubernetes.io/autoupdate: "true"
        creationTimestamp: "2021-07-07T10:19:14Z"
        labels:
          kubernetes.io/bootstrapping: rbac-defaults
        name: system:kube-scheduler
        resourceVersion: "125"
        uid: 53896c70-b332-420a-b2a4-f72c822313f2
      rules:
      ...
      - apiGroups:
        - coordination.k8s.io
        resources:
        - leases
        verbs:
        - create
      - apiGroups:
        - coordination.k8s.io
        resourceNames:
        - kube-scheduler
        - custom-scheduler 1
        resources:
        - leases
        verbs:
        - get
        - update
      - apiGroups:
        - ""
        resources:
        - endpoints
        verbs:
        - create
      - apiGroups:
        - ""
        resourceNames:
        - kube-scheduler
        - custom-scheduler 2
        resources:
        - endpoints
        verbs:
        - get
        - update
      ...
      1 2
      この例では、custom-scheduler をカスタムスケジューラー名として使用します。
  2. Pod 設定を作成し、schedulerName パラメーターでカスタムスケジューラーの名前を指定します。

    custom-scheduler-example.yaml ファイルの例

    apiVersion: v1
    kind: Pod
    metadata:
      name: custom-scheduler-example
      labels:
        name: custom-scheduler-example
    spec:
      schedulerName: custom-scheduler 1
      containers:
      - name: pod-with-second-annotation-container
        image: docker.io/ocpqe/hello-pod

    1
    使用するカスタムスケジューラーの名前です。この例では custom-scheduler になります。スケジューラー名が指定されていない場合、Pod はデフォルトのスケジューラーを使用して自動的にスケジュールされます。
  3. Pod を作成します。

    $ oc create -f custom-scheduler-example.yaml

検証

  1. 以下のコマンドを入力し、Pod が作成されたことを確認します。

    $ oc get pod custom-scheduler-example

    custom-scheduler-example Pod が出力に表示されます。

    NAME                       READY     STATUS    RESTARTS   AGE
    custom-scheduler-example   1/1       Running   0          4m
  2. 以下のコマンドを入力し、カスタムスケジューラーが Pod をスケジュールしたことを確認します。

    $ oc describe pod custom-scheduler-example

    以下の切り捨てられた出力に示されるように、スケジューラー custom-scheduler がリスト表示されます。

    Events:
      Type    Reason          Age        From                                               Message
      ----    ------          ----       ----                                               -------
      Normal  Scheduled       <unknown>  custom-scheduler                                   Successfully assigned default/custom-scheduler-example to <node_name>

4.9.3. 関連情報

4.10. Descheduler を使用した Pod のエビクト

スケジューラー は、新しい Pod をホストするのに最適なノードを決定するために使用されますが、デスケジューラーは、実行中の Pod を削除して、Pod をより適切なノードに再スケジュールできるようにするために使用できます。

4.10.1. Descheduler について

Descheduler を使用して Pod を特定のストラテジーに基づいてエビクトし、Pod がより適切なノードに再スケジュールされるようにできます。

以下のような状況では、実行中の Pod のスケジュールを解除することに利点があります。

  • ノードの使用率が低くなっているか、使用率が高くなっている。
  • テイントまたはラベルなどの、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.10.2. Descheduler プロファイル

以下の Descheduler ストラテジーを利用できます。

AffinityAndTaints

このプロファイルは、Pod 間の非アフィニティー、ノードアフィニティー、およびノードのテイントに違反する Pod をエビクトします。

これにより、以下のストラテジーが有効になります。

  • RemovePodsViolatingInterPodAntiAffinity: Pod 間の非アフィニティーに違反する Pod を削除します。
  • RemovePodsViolatingNodeAffinity: ノードのアフィニティー に違反する Pod を削除します。
  • RemovePodsViolatingNodeTaints: ノード上の NoSchedule テイントに違反する 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 を削除の対象にすることができます。

4.10.3. Descheduler のインストール

Descheduler はデフォルトで利用できません。Descheduler を有効にするには、Kube Descheduler Operator を OperatorHub からインストールし、1 つ以上の Descheduler プロファイルを有効にする必要があります。

前提条件

  • クラスター管理者の権限。
  • 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. Profiles セクションをデプロイメントし、1 つ以上のプロファイルを選択して有効にします。AffinityAndTaints プロファイルはデフォルトで有効になっています。Add Profile をクリックして、追加のプロファイルを選択します。

        注記

        TopologyAndDuplicatesSoftTopologyAndDuplicates の両方を有効にしないでください。両方を有効にすると、競合が生じます。

      2. オプション: Profile Customizations セクションをデプロイメントし、LifecycleAndUtilization プロファイルのカスタム Pod ライフタイム値を設定します。有効な単位は sm、または h です。デフォルトの Pod の有効期間は 24 時間です。
      3. オプション: Descheduling Interval Seconds フィールドを使用して、Descheduler の実行間の秒数を変更します。デフォルトは 3600 秒です。
    4. Create をクリックします。

また、後で OpenShift CLI (oc) を使用して、Descheduler のプロファイルおよび設定を設定することもできます。Web コンソールから Descheduler インスタンスを作成する際にプロファイルを調整しない場合、AffinityAndTaints プロファイルはデフォルトで有効にされます。

4.10.4. Descheduler プロファイルの設定

Descheduler が Pod のエビクトに使用するプロファイルを設定できます。

前提条件

  • クラスター管理者の権限

手順

  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
      profileCustomizations:
        podLifetime: 48h        1
      profiles:                 2
      - AffinityAndTaints
      - TopologyAndDuplicates   3
      - LifecycleAndUtilization
      - EvictPodsWithLocalStorage
      - EvictPodsWithPVC
    1
    オプション: LifecycleAndUtilization プロファイルのカスタム Pod ライフタイム値を有効にします。有効な単位は sm、または h です。デフォルトの Pod の有効期間は 24 時間です。
    2
    1 つ以上のプロファイルを追加して有効にします。使用可能なプロファイル: AffinityAndTaintsTopologyAndDuplicatesLifecycleAndUtilizationSoftTopologyAndDuplicatesEvictPodsWithLocalStorage 、および EvictPodsWithPVC
    3
    TopologyAndDuplicatesSoftTopologyAndDuplicates の両方を有効にしないでください。両方を有効にすると、競合が生じます。

    複数のプロファイルを有効にすることができますが、プロファイルを指定する順番は重要ではありません。

  3. 変更を適用するためにファイルを保存します。

4.10.5. Descheduler の間隔の設定

Descheduler の実行間隔を設定できます。デフォルトは 3600 秒 (1 時間) です。

前提条件

  • クラスター管理者の権限

手順

  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.10.6. Descheduler のアンインストール

Descheduler インスタンスを削除し、Kube Descheduler Operator をアンインストールして Descheduler をクラスターから削除できます。この手順では、KubeDescheduler CRD および openshift-kube-descheduler-operator namespace もクリーンアップします。

前提条件

  • クラスター管理者の権限。
  • 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 エントリーの横にある Options メニュー 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.11. セカンダリースケジューラー

4.11.1. セカンダリースケジューラーの概要

Secondary Scheduler Operator をインストールして、デフォルトのスケジューラーと共にカスタムのセカンダリースケジューラーを実行して Pod をスケジュールすることができます。

4.11.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.11.2. Red Hat OpenShift リリースノートのセカンダリースケジューラー Operator

Red Hat OpenShift のセカンダリースケジューラー Operator を使用すると、カスタムセカンダリースケジューラーを OpenShift Container Platform クラスターにデプロイできます。

本リリースノートでは、Red Hat OpenShift のセカンダリースケジューラー Operator の開発を追跡します。

重要

Red Hat OpenShift の Secondary Scheduler Operator の導入により、カスタムスケジューラーのデプロイ へのサポートは、OpenShift Container Platform の次のリリースで削除される予定となっています。

詳細については、Secondary Scheduler Operator について を参照してください。

4.11.2.1. Red Hat OpenShift 1.0.1 のセカンダリースケジューラー Operator のリリースノート

発行日: 2022-07-28

以下のアドバイザリーは、Red Hat OpenShift 1.0.1 の セカンダリースケジューラー Operator で利用できます。

重要

Red Hat OpenShift 1.0.0 の Secondary Scheduler Operator を使用している場合、OpenShift Container Platform の次のマイナーリリースに更新すると、バージョン 1.0.1 に自動的にアップグレードされることが想定されています。

4.11.2.1.1. 新機能および拡張機能
  • Red Hat OpenShift 1.0.1 の セカンダリースケジューラー Operator の OpenShift Container Platform の最大バージョンは 4.11 です。
4.11.2.1.2. バグ修正
  • 以前は、セカンダリースケジューラーのカスタムリソース (CR) が削除された後、セカンダリースケジューラーのデプロイメントが削除されなかったため、セカンダリースケジューラー Operator とオペランドを完全にアンインストールできませんでした。セカンダリースケジューラーの CR が削除されると、セカンダリースケジューラーのデプロイメントが削除されるようになったため、セカンダリースケジューラー Operator を完全にアンインストールできるようになりました。(BZ#2100923)
4.11.2.1.3. 既知の問題
  • 現時点で、Secondary Scheduler Operator を使用して設定マップ、CRD、RBAC ポリシーなどの追加のリソースをデプロイできません。カスタムセカンダリースケジューラーに必要なロールとロールバインディング以外のリソースは、外部から適用する必要があります。(BZ#2071684)

4.11.2.2. Red Hat OpenShift 1.0.0 のセカンダリースケジューラー Operator のリリースノート

発行日: 2022-04-18

以下のアドバイザリーは、Red Hat OpenShift 1.0.0 の Secondary Scheduler Operator で利用できます。

4.11.2.2.1. 新機能および拡張機能
  • これは、Red Hat OpenShift のセカンダリースケジューラー Operator の初期リリースです。
4.11.2.2.2. 既知の問題
  • 現時点で、Secondary Scheduler Operator を使用して設定マップ、CRD、RBAC ポリシーなどの追加のリソースをデプロイできません。カスタムセカンダリースケジューラーに必要なロールとロールバインディング以外のリソースは、外部から適用する必要があります。(BZ#2071684)

4.11.3. セカンダリースケジューラーを使用した Pod のスケジューリング

OpenShift Container Platform でカスタムセカンダリースケジューラーを実行するには、セカンダリースケジューラー Operator をインストールし、セカンダリースケジューラーをデプロイし、セカンダリースケジューラーを Pod 定義に設定します。

4.11.3.1. セカンダリースケジューラー Operator のインストール

Web コンソールを使用して、Red Hat OpenShift の Secondary Scheduler Operator をインストールできます。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • 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. フィルターボックスに Red Hat の SecondarySchedulerOperator と入力します。
    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.11.3.2. セカンダリースケジューラーのデプロイ

Secondary Scheduler Operator のインストール後に、セカンダリースケジューラーをデプロイできます。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • 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/v1beta3
          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.11.3.3. セカンダリースケジューラーを使用した Pod のスケジューリング

セカンダリースケジューラーを使用して Pod をスケジュールするには、Pod 定義の schedulerName フィールドを設定します。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • 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.11.4. セカンダリースケジューラー Operator のアンインストール

Operator をアンインストールして関連リソースを削除することにより、Red Hat OpenShift のセカンダリースケジューラー Operator を OpenShift Container Platform から削除できます。

4.11.4.1. セカンダリースケジューラー Operator のアンインストール

Web コンソールを使用して、Red Hat OpenShift のセカンダリースケジューラー Operator をアンインストールできます。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • 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.11.4.2. Secondary Scheduler Operator リソースの削除

オプションで、Red Hat の Secondary Scheduler Operator をアンインストールした後、関連するリソースをクラスターから削除できます。

前提条件

  • cluster-admin 権限でクラスターにアクセスできる。
  • 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章 ジョブと DeamonSet の使用

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 の容認がデーモンセット 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 つのジョ