Red Hat OpenShift クラスタにアプリをデプロイする
Red Hat® OpenShift® on IBM Cloud® クラスターでは、単一のコマンドを使用して、リモート・ファイルまたは GitHub などのリポジトリーからアプリをデプロイできます。 また、クラスターには、そのクラスターの操作に役立つさまざまな組み込みサービスが付属しています。
Red Hat OpenShift へのアプリの移行
Red Hat OpenShift on IBM Cloud クラスターでアプリを作成するために、Red Hat OpenShift コンソールまたは CLI を使用できます。
アプリのデプロイ時にエラーが発生しますか? Red Hat OpenShift には、厳密なセキュリティー・コンテキスト制約などのように、コミュニティー Kubernetes とは異なるデフォルト設定があります。 Red Hat OpenShift クラスターにアプリをデプロイするために、アプリを変更する必要が生じることがある一般的な状況を確認してください。
コンソールによるアプリのデプロイ
Red Hat OpenShift コンソールの Developer パースペクティブを使用すると、さまざまな方式でアプリを作成できます。 詳しくは、 Red Hat OpenShift 資料を参照してください。
- コンソールから、クラスタを選択します。
- **「Red Hat OpenShift Web コンソール」**をクリックします。
- パースペクティブ・スイッチャーで Developer を選択します。 Red Hat OpenShift Web コンソールが Developer パースペクティブに切り替わり、メニューに**「+Add」、「Topology」、「Builds」**などの項目が表示されるようになりました。
- **「+追加 (+Add)」**をクリックします。
- **「Add」ペインのメニュー・バーのドロップダウン・リストから、作成するアプリを配置する「Project」**を選択します。
- アプリを追加するために使用する方式をクリックし、指示に従います。 例えば、**「From Git」**をクリックします。
CLI によるアプリのデプロイ
Red Hat OpenShift on IBM Cloud クラスタにアプリを作成するには、 oc new-app
コマンドを使用する。
例えば、パブリック GitHub リポジトリー、.git
で終わる URL のパブリック GitLab リポジトリー、別のローカル・リポジトリーやリモート・リポジトリーを参照できます。 詳細については、 チュートリアルを試し て 、 Red Hat OpenShift のドキュメントを確認してください。
oc new-app --name <app_name> https://github.com/<path_to_app_repo> [--context-dir=<subdirectory>]
new-app
コマンドは何をするのですか?new-app
コマンドは、ソース・コードからのビルド構成とアプリ・イメージの作成、クラスター内のポッドにコンテナーをデプロイするためのデプロイメント構成の作成、クラスター内でアプリを公開するためのサービスの作成を行います。 ビルド・プロセスの詳細や、 Git 以外のソースについては、 Red Hat OpenShift のドキュメントを参照のこと。
ラベルを使用した特定のワーカー・ノードへのアプリのデプロイ
アプリをデプロイすると、アプリ・ポッドが、クラスター内のさまざまなワーカー・ノードに無差別にデプロイされます。 場合によっては、アプリ・ポッドのデプロイ先のワーカー・ノードを制限する必要があります。 例えば、特定のワーカー・プールのワーカー・ノードがベアメタル・マシン上にあるため、これらのワーカー・ノードにのみアプリ・ポッドがデプロイされるようにしたいとします。 アプリ・ポッドをデプロイするワーカー・ノードを指定するには、アプリのデプロイメントにアフィニティー・ルールを追加します。
開始前に
- Red Hat OpenShift クラスターにアクセスします。
- オプション: アプリを実行するワーカー・プールのラベルを設定します。
特定のワーカー・ノードにアプリをデプロイするには、以下のようにします。
-
アプリ・ポッドをデプロイするワーカー・プールの ID を取得します。
ibmcloud oc worker-pool ls --cluster <cluster_name_or_ID>
-
ワーカー・プールにあるワーカー・ノードをリストし、プライベート IP アドレスの 1 つをメモします。
ibmcloud oc worker ls --cluster <cluster_name_or_ID> --worker-pool <worker_pool_name_or_ID>
-
ワーカー・ノードの説明を表示します。 Labels 出力で、ワーカー・プール ID ラベル
ibm-cloud.kubernetes.io/worker-pool-id
をメモします。このトピックで示す手順では、ワーカー・プール ID を使用して、そのワーカー・プール内のワーカー・ノードにのみアプリ・ポッドをデプロイします。 別のラベルを使用して特定のワーカー・ノードにアプリ・ポッドをデプロイするには、代わりにそのラベルをメモしてください。 例えば、特定のプライベート VLAN 上にあるワーカー・ノードにのみアプリ・ポッドをデプロイするには、
privateVLAN=
ラベルを使用します。oc describe node <worker_node_private_IP>
出力例
NAME: 10.xxx.xx.xxx Roles: <none> Labels: arch=amd64 beta.kubernetes.io/arch=amd64 beta.kubernetes.io/instance-type=b3c.4x16.encrypted beta.kubernetes.io/os=linux failure-domain.beta.kubernetes.io/region=us-south failure-domain.beta.kubernetes.io/zone=dal10 ibm-cloud.kubernetes.io/encrypted-docker-data=true ibm-cloud.kubernetes.io/ha-worker=true ibm-cloud.kubernetes.io/iaas-provider=softlayer ibm-cloud.kubernetes.io/machine-type=b3c.4x16.encrypted ibm-cloud.kubernetes.io/sgx-enabled=false ibm-cloud.kubernetes.io/worker-pool-id=00a11aa1a11aa11a1111a1111aaa11aa-11a11a ibm-cloud.kubernetes.io/worker-version=1.32_1534 kubernetes.io/hostname=10.xxx.xx.xxx privateVLAN=1234567 publicVLAN=7654321 Annotations: node.alpha.kubernetes.io/ttl=0 ...
-
ワーカー プール ID ラベルの アフィニティ ルールをアプリのデプロイメントに追加します。
YAML の例
apiVersion: apps/v1 kind: Deployment metadata: name: with-node-affinity spec: template: spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: ibm-cloud.kubernetes.io/worker-pool-id operator: In values: - <worker_pool_ID> ...
YAML の例のアフィニティー (affinity) セクションでは、
ibm-cloud.kubernetes.io/worker-pool-id
はkey
、<worker_pool_ID>
はvalue
です。 -
更新したデプロイメント構成ファイルを適用します。
oc apply -f with-node-affinity.yaml
-
アプリ・ポッドが、正しいワーカー・ノードにデプロイされたことを確認します。
-
クラスター内のポッドをリストします。
oc get pods -o wide
出力例
NAME READY STATUS RESTARTS AGE IP NODE cf-py-d7b7d94db-vp8pq 1/1 Running 0 15d 172.30.xxx.xxx 10.176.48.78
-
出力で、アプリのポッドを確認します。 ポッドがあるワーカー・ノードの NODE プライベート IP アドレスをメモします。
前述の出力例で、アプリ・ポッド
cf-py-d7b7d94db-vp8pq
は、IP アドレス10.xxx.xx.xxx
のワーカー・ノード上にあります。 -
アプリのデプロイメントに指定したワーカー・プール内にあるワーカー・ノードをリストします。
ibmcloud oc worker ls --cluster <cluster_name_or_ID> --worker-pool <worker_pool_name_or_ID>
出力例
ID Public IP Private IP Machine Type State Status Zone Version kube-dal10-crb20b637238bb471f8b4b8b881bbb4962-w7 169.xx.xxx.xxx 10.176.48.78 b3c.4x16 normal Ready dal10 1.8.6_1504 kube-dal10-crb20b637238bb471f8b4b8b881bbb4962-w8 169.xx.xxx.xxx 10.176.48.83 b3c.4x16 normal Ready dal10 1.8.6_1504 kube-dal12-crb20b637238bb471f8b4b8b881bbb4962-w9 169.xx.xxx.xxx 10.176.48.69 b3c.4x16 normal Ready dal12 1.8.6_1504
別の要因に基づいてアプリのアフィニティー・ルールを作成した場合は、代わりにその値を取得してください。 例えば、アプリ・ポッドが特定の VLAN 上のワーカー・ノードにデプロイされたことを確認するには、
ibmcloud oc worker get --cluster <cluster_name_or_ID> --worker <worker_ID>
を実行して、そのワーカー・ノードが存在する VLAN を表示します。 -
出力で、前のステップで指定したプライベート IP アドレスを持つワーカー・ノードがこのワーカー・プールにデプロイされていることを確認します。
-
NVIDIA GPUマシンにアプリをデプロイする
GPU マシン・タイプを使用している場合は、AI、機械学習、推論などの計算主体のワークロードに必要な処理時間を短縮できます。
以下のステップは、GPU を必要とするワークロードをデプロイする方法を示しています。 しかし、GPUとCPUの両方でワークロードを処理する必要のないアプリをデプロイすることもできます。
また、 この Kubernetes デモを使用して、 TensorFlow 機械学習フレームワークなどの数学的に負荷の高いワークロードを試すこともできます。
前提条件
開始前に
-
GPU フレーバーを使用する クラスター またはワーカー・プールを作成します。 ベアメタル・マシンのセットアップは、完了するまでに 1 営業日以上かかることがあることに留意してください。 使用可能なフレーバーのリストについては、以下のリンクを参照してください。
-
クラスター内の Kubernetes リソースを処理できる適切な Kubernetes RBAC 役割を付与する、サービス・アクセス役割が自分に割り当てられていることを確認します。
プライベート専用クラスターの制限: クラスターにパブリック・ネットワーク接続がない場合は、外部レジストリーおよびイメージ・ストリームから icr.io
へのパブリック・ネットワーク接続またはミラー・イメージを許可する必要があります。 以下の例では、GPU アプリは、イメージ・ストリームとともに OLM マーケットプレイスを使用します。 この例は、クラスタが NVIDIA レジストリ( nvcr.io
)にアクセスできない場合は動作しません。
- ご使用のクラスタバージョンに対応する NVIDIA GPU オペレータをインストールします。
- Node Feature Discoveryおよび NVIDIA GPUオペレータをクラスタバージョンに合わせてインストールします。
NVIDIA GPU オペレーターはバージョン 1.3.1 以降を使用する必要があります。 Node Feature Discovery オペレーターをインストールするときには、Red Hat OpenShift クラスターのバージョンに対応する更新チャネルを選択してください。 Helm チャートなど、他の方法でオペレーターをインストールしないでください。
Node Feature Discovery Operator または NVIDIA GPU Operator のインストールに問題が発生した場合は 、 NVIDIA サポートに連絡するか、 NVIDIA GPU Operator repoに問題を報告してください
ワークロードのデプロイ
-
YAML ファイルを作成します。 この例では、
Job
YAMLは、コマンドが完了し正常に終了するまで実行される短命のポッドを作ることで、バッチ的なワークロードを管理します。GPU ワークロードの場合、ジョブ YAML で
resources: limits: nvidia.com/gpu
フィールドを指定する必要があります。apiVersion: batch/v1 kind: Job metadata: name: nvidia-devicequery labels: name: nvidia-devicequery spec: template: metadata: labels: name: nvidia-devicequery spec: containers: - name: nvidia-devicequery image: nvcr.io/nvidia/k8s/cuda-sample:devicequery-cuda11.7.1-ubuntu20.04 imagePullPolicy: IfNotPresent resources: limits: nvidia.com/gpu: 2 restartPolicy: Never
YAMLコンポーネントを理解する コンポーネント 説明 メタデータとラベルの名前 ジョブの名前とラベルを入力し、ファイルのメタデータと spec template
メタデータの両方で同じ名前を使用します。 例えば、nvidia-devicequery
です。containers.image
実行中インスタンスとなっているコンテナーが属するイメージを指定します。 この例では、 DockerHub CUDA デバイス照会イメージ nvcr.io/nvidia/k8s/cuda-sample:devicequery-cuda11.7.1-ubuntu20.04
を使用するように値が設定されています。containers.imagePullPolicy
イメージが現在ワーカー・ノード上にない場合にのみ新規イメージをプルする場合は、 IfNotPresent
を指定します。resources.limits
GPU マシンの場合は、リソース制限を指定する必要があります。 Kubernetes Device Plug-inは、デフォルトのリソース要求を制限に合うように設定する。
nvidia.com/gpu
のようにキーを指定する必要があります。2
のように、ご要望のGPU数全体を入力してください。 コンテナー・ポッドは GPU を共有せず、GPU はオーバーコミットできないことに注意してください。 例えば、mg1c.16x128
マシンが 1 台のみの場合、そのマシンには GPU が 2 つしかないため、指定できるのは最大で2
つです。
-
YAML ファイルを適用します。 以下に例を示します。
oc apply -f nvidia-devicequery.yaml
-
nvidia-devicequery
ラベルでポッドをフィルタリングして、ジョブポッドを確認します。 STATUS が Completed であることを確認します。oc get pod -A -l 'name in (nvidia-devicequery)'
出力例
NAME READY STATUS RESTARTS AGE nvidia-devicequery-ppkd4 0/1 Completed 0 36s
-
ポッドに describe を実行して、GPU デバイス・プラグインがポッドをどのようにスケジュールしたかを確認します。
-
Limits
フィールドとRequests
フィールドで、指定したリソース制限とデバイス・プラグインが自動的に設定した要求とが一致していることを確認します。 -
イベントで、ポッドが GPU ワーカー・ノードに割り当てられていることを確認します。
oc describe pod nvidia-devicequery-ppkd4
出力例
NAME: nvidia-devicequery-ppkd4 Namespace: default ... Limits: nvidia.com/gpu: 1 Requests: nvidia.com/gpu: 1 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 1m default-scheduler Successfully assigned nvidia-devicequery-ppkd4 to 10.xxx.xx.xxx ...
-
-
ジョブが GPU を使用してそのワークロードの計算を実行したことを検証するには、ログを確認します。
oc logs nvidia-devicequery-ppkd4
出力例
/cuda-samples/sample Starting... CUDA Device Query (Runtime API) version (CUDART static linking) Detected 1 CUDA Capable device(s) Device 0: "Tesla P100-PCIE-16GB" CUDA Driver Version / Runtime Version 11.4 / 11.7 CUDA Capability Major/Minor version number: 6.0 Total amount of global memory: 16281 MBytes (17071734784 bytes) (056) Multiprocessors, (064) CUDA Cores/MP: 3584 CUDA Cores GPU Max Clock rate: 1329 MHz (1.33 GHz) Memory Clock rate: 715 Mhz Memory Bus Width: 4096-bit L2 Cache Size: 4194304 bytes Maximum Texture Dimension Size (x,y,z) 1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384) Maximum Layered 1D Texture Size, (num) layers 1D=(32768), 2048 layers Maximum Layered 2D Texture Size, (num) layers 2D=(32768, 32768), 2048 layers Total amount of constant memory: 65536 bytes Total amount of shared memory per block: 49152 bytes Total shared memory per multiprocessor: 65536 bytes Total number of registers available per block: 65536 Warp size: 32 Maximum number of threads per multiprocessor: 2048 Maximum number of threads per block: 1024 Max dimension size of a thread block (x,y,z): (1024, 1024, 64) Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535) Maximum memory pitch: 2147483647 bytes Texture alignment: 512 bytes Concurrent copy and kernel execution: Yes with 2 copy engine(s) Run time limit on kernels: No Integrated GPU sharing Host Memory: No Support host page-locked memory mapping: Yes Alignment requirement for Surfaces: Yes Device has ECC support: Enabled Device supports Unified Addressing (UVA): Yes Device supports Managed Memory: Yes Device supports Compute Preemption: Yes Supports Cooperative Kernel Launch: Yes Supports MultiDevice Co-op Kernel Launch: Yes Device PCI Domain ID / Bus ID / location ID: 0 / 175 / 0 Compute Mode: < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) > deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 11.4, CUDA Runtime Version = 11.7, NumDevs = 1 Result = PASS
この例では、GPU がワーカー・ノードでスケジュールされているため、GPU を使用してジョブが実行されました。 制限が 2 に設定されている場合は、2 個の GPU のみが表示されます。
テストGPUワークロードをデプロイしたので、次のようなGPU処理に依存するツールを実行するようにクラスタをセットアップしたくなるかもしれません。 IBM Maximo Visual Inspection.
インテルAIアクセラレータ(Gaudi 3)マシンにアプリをデプロイする
この機能は、許可リストに登録されたアカウントでのみ利用可能です。 アクセスを要求するには、「 許可リストに登録された機能へのアクセスを要求する 」を参照してください。
resource.limits
フィールドを使用して Gaudi デバイスを検索する Intel Gaudi の PyTorch コンテナイメージをデプロイするために、以下の例を実行します。 作業を始める前に、クラスタが以下の要件を満たしていることを確認してください。
- バージョン 4.18 以降
- VPCクラスタのみ
- RHCOSワーカーノードのみ
- インテル・ガウディ・ベース・ オペレーター v1.20.1 以降
詳細と例については、 Habanaのドキュメントと クイックスタートの例を参照してください。
- 以下のジョブ設定例をコピーし、以下のファイル名で保存する。
config.yaml
apiVersion: batch/v1 kind: Job metadata: name: habanalabs-gaudi-demo spec: template: spec: hostIPC: true restartPolicy: OnFailure containers: - name: habana-ai-base-container image: vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest workingDir: /root command: ["hl-smi"] securityContext: capabilities: add: ["SYS_NICE"] resources: limits: habana.ai/gaudi: 8 memory: 409Gi hugepages-2Mi: 9500Mi
- クラスターにジョブを適用する。
oc apply -f config.yaml
- ポッドが起動するのを待ち、ジョブが完了したことを確認する。
例oc get po -n default
NAME READY STATUS RESTARTS AGE habanalabs-gaudi-demo-kmdcp 0/1 Completed 0 2m32s
- 詳細はジョブポッドをご覧ください。
oc describe po habanalabs-gaudi-demo-kmdcp
Name: habanalabs-gaudi-demo-kmdcp Namespace: default Priority: 0 Service Account: default Node: test-csrq76620trmo9r8j7u0-btsstagevpc-gaudi3s-00013059/10.180.0.83 Start Time: Tue, 27 May 2025 14:41:50 -0400 Labels: batch.kubernetes.io/controller-uid=c3b33c8a-5fef-4312-9d59-c8b13c03313a batch.kubernetes.io/job-name=habanalabs-gaudi-demo controller-uid=c3b33c8a-5fef-4312-9d59-c8b13c03313a job-name=habanalabs-gaudi-demo Annotations: cni.projectcalico.org/containerID: 7c883dfa9c681ee2c4128b1a5412d4dc181842d0de2a4b7b8019eefc06df37ca cni.projectcalico.org/podIP: cni.projectcalico.org/podIPs: Status: Succeeded IP: 172.17.151.97 IPs: IP: 172.17.151.97 Controlled By: Job/habanalabs-gaudi-demo Containers: habana-ai-base-container: Container ID: cri-o://d75288e9b467f3f820e05e770bbc3d9a2b11cbf8155a54a129fc083d5d507571 Image: vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest Image ID: vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0@sha256:cd599626a8f4d1c3a7b354ccf4ef73e19196f09030d02261d4900bf3467a964c Port: <none> Host Port: <none> Command: hl-smi State: Terminated Reason: Completed Exit Code: 0 Started: Tue, 27 May 2025 14:41:53 -0400 Finished: Tue, 27 May 2025 14:41:54 -0400 Ready: False Restart Count: 0 Limits: habana.ai/gaudi: 8 hugepages-2Mi: 9500Mi memory: 409Gi Requests: habana.ai/gaudi: 8 hugepages-2Mi: 9500Mi memory: 409Gi Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8vn42 (ro) Conditions: Type Status PodReadyToStartContainers False Initialized True Ready False ContainersReady False PodScheduled True Volumes: kube-api-access-8vn42: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true ConfigMapName: openshift-service-ca.crt ConfigMapOptional: <nil> QoS Class: Burstable Node-Selectors: <none> Tolerations: node.kubernetes.io/memory-pressure:NoSchedule op=Exists node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 53s default-scheduler Successfully assigned default/habanalabs-gaudi-demo-kmdcp to test-csrq76620trmo9r8j7u0-btsstagevpc-gaudi3s-00013059 Normal AddedInterface 52s multus Add eth0 [172.17.151.97/32] from k8s-pod-network Normal Pulling 52s kubelet Pulling image "vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest" Normal Pulled 50s kubelet Successfully pulled image "vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest" in 2.146s (2.146s including waiting). Image size: 5188441181 bytes. Normal Created 50s kubelet Created container: habana-ai-base-container Normal Started 50s kubelet Started container habana-ai-base-container
- ガウディ・デバイスの詳細を見るには、ポッド・ログを入手してください。
出力例oc logs habanalabs-gaudi-demo-kmdcp
+-----------------------------------------------------------------------------+ | HL-SMI Version: hl-1.21.0-fw-59.2.1.0 | | Driver Version: 1.20.1-366eb9c | | Nic Driver Version: 1.20.1-213b09b | |-------------------------------+----------------------+----------------------+ | AIP Name Persistence-M| Bus-Id Disp.A | Volatile Uncor-Events| | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | AIP-Util Compute M. | |===============================+======================+======================| | 0 HL-325L N/A | 0000:e9:00.0 N/A | 0 | | N/A 36C P0 228W / 900W | 672MiB / 131072MiB | 0% 0% | |-------------------------------+----------------------+----------------------+ | 1 HL-325L N/A | 0000:c1:00.0 N/A | 0 | | N/A 37C P0 226W / 900W | 672MiB / 131072MiB | 0% 0% | |-------------------------------+----------------------+----------------------+ | 2 HL-325L N/A | 0000:b7:00.0 N/A | 0 | | N/A 36C P0 225W / 900W | 672MiB / 131072MiB | 0% 0% | |-------------------------------+----------------------+----------------------+ | 3 HL-325L N/A | 0000:ad:00.0 N/A | 0 | | N/A 40C P0 228W / 900W | 672MiB / 131072MiB | 0% 0% | |-------------------------------+----------------------+----------------------+ | 4 HL-325L N/A | 0000:a3:00.0 N/A | 0 | | N/A 36C P0 228W / 900W | 672MiB / 131072MiB | 0% 0% | |-------------------------------+----------------------+----------------------+ | 5 HL-325L N/A | 0000:df:00.0 N/A | 0 | | N/A 39C P0 229W / 900W | 672MiB / 131072MiB | 0% 0% | |-------------------------------+----------------------+----------------------+ | 6 HL-325L N/A | 0000:d5:00.0 N/A | 0 | | N/A 36C P0 231W / 900W | 672MiB / 131072MiB | 0% 0% | |-------------------------------+----------------------+----------------------+ | 7 HL-325L N/A | 0000:cb:00.0 N/A | 0 | | N/A 38C P0 227W / 900W | 672MiB / 131072MiB | 0% 0% | |-------------------------------+----------------------+----------------------+ | Compute Processes: AIP Memory | | AIP PID Type Process name Usage | |=============================================================================| | 0 N/A N/A N/A N/A | | 1 N/A N/A N/A N/A | | 2 N/A N/A N/A N/A | | 3 N/A N/A N/A N/A | | 4 N/A N/A N/A N/A | | 5 N/A N/A N/A N/A | | 6 N/A N/A N/A N/A | | 7 N/A N/A N/A N/A | +=============================================================================+