Kubernetes ネイティブ・アプリをクラスターにデプロイする

Kubernetes のテクニックを使って、 IBM Cloud® Kubernetes Service でコンテナ化されたアプリをデプロイする。 ユーザーにダウンタイムを与えることなく、ローリングアップデートやロールバックを実行できます。

設定ファイルの作成については、「 設定のベストプラクティス 」ガイドを参照してください。

Kubernetes ダッシュボードの起動

Kubernetes ダッシュボードにアクセスして、 IBM Cloud コンソール または CLI からクラスタとワーカーノードの情報を表示します。

開始する前に、適切な アクセス・ロールを持って いることを確認してください。 アカウントにログインします。 該当する場合は、適切なリソース・グループをターゲットにします。 クラスターのコンテキストを設定します。

IBM Cloud コンソールからの Kubernetes ダッシュボードの起動

  1. IBM Cloud コンソール にログインします。
  2. メニュー・バーから、使用するアカウントを選択します。
  3. メニューからメニューアイコン をクリックし 、Containers(コンテナ) > Clusters(クラスタ) の順にクリックします。
  4. **「クラスター」**ページで、アクセスするクラスターをクリックします。
  5. クラスターの詳細ページで、**「Kubernetes Dashboard」**ボタンをクリックします。

CLI からの Kubernetes ダッシュボードの起動

CLI方式は、自動化とCI/CD統合を可能にする。 始める前に CLIをインストールして ください。

  1. Kubernetes の資格情報を取得してください。

    kubectl config view -o jsonpath='{.users[0].user.auth-provider.config.id-token}'
    
  2. 出力から id-token 値をコピーする。

  3. プロキシを開始する。

    kubectl proxy
    

    出力例

    Starting to serve on 127.0.0.1:8001
    
  4. ダッシュボードにサインインします。

    1. ブラウザで次の URL( URL )にアクセスしてください:
        http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
        ```
    2. サインオン・ページで**トークン**認証方法を選択します。
    
    3. **id-tokenの**値を **Token** フィールドに貼り付け、 **SIGN INを**クリックします。
    
    

proxy コマンドを終了するには CTRL+C を使用する。 kubectl proxy を再度実行してダッシュボードを再起動します。

Kubernetes ダッシュボードでアプリをデプロイする方法

設定の詳細を入力するか、YAMLファイルをアップロードして、ダッシュボードからアプリをデプロイする。

作業を開始する前に、 ダッシュボードを 開き、 サービス・アクセス・ロールを持って いることを確認してください。 アカウントにログインします。 該当する場合は、適切なリソース・グループをターゲットにします。 クラスターのコンテキストを設定します。

アプリをデプロイするには

  1. **「+ 作成 (+ Create)」**をクリックします。

  2. 展開方法を選択する:

    • アプリの詳細を指定 」を選択し、詳細を入力してください。
    • YAMLまたはJSONファイルをアップロード 」を選択して、アプリ の設定ファイルをアップロードしてください。
  3. Deployments をクリックして、アプリが正常にデプロイされたことを確認します。

CLI でアプリをデプロイする方法

CLI方式は正確な制御を提供し、自動化を可能にする。 アプリのリソースを定義し、バージョン管理可能な設定ファイルを作成します。

開始する前に、 CLIをインストール し、 サービス・アクセス・ロールが あることを確認してください。 アカウントにログインします。 該当する場合は、適切なリソース・グループをターゲットにします。 クラスターのコンテキストを設定します。

アプリをデプロイするには

  1. 必要に応じて、 DeploymentServiceIngress リソースを含む設定ファイルを作成する。 Kubernetes リソースを処理する際の個人情報の保護の詳細を確認してください。

  2. 設定ファイルを適用する。

    kubectl apply -f config.yaml
    
  3. アプリにアクセスできることを確認します。

ラベルを使用した特定のワーカー・ノードへのアプリのデプロイ

アプリをデプロイすると、アプリ・ポッドが、クラスター内のさまざまなワーカー・ノードに無差別にデプロイされます。 場合によっては、アプリ・ポッドのデプロイ先のワーカー・ノードを制限する必要があります。 例えば、特定のワーカー・プールのワーカー・ノードがベアメタル・マシン上にあるため、これらのワーカー・ノードにのみアプリ・ポッドがデプロイされるようにしたいとします。 アプリ・ポッドをデプロイするワーカー・ノードを指定するには、アプリのデプロイメントにアフィニティー・ルールを追加します。

開始前に

特定のワーカー・ノードにアプリをデプロイするには、以下のようにします。

  1. アプリ・ポッドをデプロイするワーカー・プールの ID を取得します。

    ibmcloud ks worker-pool ls --cluster CLUSTER_NAME_OR_ID
    
  2. ワーカー・プールにあるワーカー・ノードをリストし、プライベート IP アドレスの 1 つをメモします。

    ibmcloud ks worker ls --cluster CLUSTER_NAME_OR_ID --worker-pool WORKER_POOL_NAME_OR_ID
    
  3. ワーカー・ノードの説明を表示します。 Labels 出力で、ワーカー・プール ID ラベル ibm-cloud.kubernetes.io/worker-pool-id をメモします。

    このトピックで示す手順では、ワーカー・プール ID を使用して、そのワーカー・プール内のワーカー・ノードにのみアプリ・ポッドをデプロイします。 別のラベルを使用して特定のワーカー・ノードにアプリ・ポッドをデプロイするには、代わりにそのラベルをメモしてください。 例えば、特定のプライベート VLAN 上にあるワーカー・ノードにのみアプリ・ポッドをデプロイするには、privateVLAN= ラベルを使用します。

    kubectl 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.36_1534
                        kubernetes.io/hostname=10.xxx.xx.xxx
                        privateVLAN=1234567
                        publicVLAN=7654321
    Annotations:        node.alpha.kubernetes.io/ttl=0
    ...
    
  4. アプリ展開に、ワーカープール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-idkey<worker_pool_ID>value です。

  5. 更新したデプロイメント構成ファイルを適用します。

    kubectl apply -f with-node-affinity.yaml
    
  6. アプリ・ポッドが、正しいワーカー・ノードにデプロイされたことを確認します。

    1. クラスター内のポッドをリストします。
        kubectl get pods -o wide
        ```
        出力例
        ```sh {: screen}
        NAME                   READY     STATUS              RESTARTS   AGE       IP               NODE
        cf-py-d7b7d94db-vp8pq  1/1       Running             0          15d       172.30.xxx.xxx   10.176.48.78
        ```
    2. 出力で、アプリのポッドを確認します。 ポッドがあるワーカー・ノードの **NODE** プライベート IP アドレスをメモします。
    
        前述の出力例で、アプリ・ポッド `cf-py-d7b7d94db-vp8pq` は、IP アドレス `10.xxx.xx.xxx` のワーカー・ノード上にあります。
    
    3. アプリのデプロイメントに指定したワーカー・プール内にあるワーカー・ノードをリストします。
    
    ```sh {: pre}
        ibmcloud ks worker ls --cluster CLUSTER_NAME_OR_ID --worker-pool WORKER_POOL_NAME_OR_ID
        ```
        出力例
    
        ```sh {: screen}
        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 ks worker get --cluster CLUSTER_NAME_OR_ID --worker WORKER_ID` を実行して、そのワーカー・ノードが存在する VLAN を表示します。
        {: tip}
    
    4. 出力で、前のステップで指定したプライベート IP アドレスを持つワーカー・ノードがこのワーカー・プールにデプロイされていることを確認します。
    
    

NVIDIA GPUマシンへのアプリのデプロイ

GPU マシン・タイプを使用している場合は、AI、機械学習、推論などの計算主体のワークロードに必要な処理時間を短縮できます。

Kubernetes バージョン 1.36 以降の重要なドライバーの変更: IBM Cloud Kubernetes Service Kubernetes バージョン 1.36 以降、GPU を搭載したワーカーノードに NVIDIA GPU ドライバーをインストールしなくなりました。 バージョン 1.36 またはそれ以降のクラスタ上でGPUワークロードを実行する予定の場合、ワーカーノード上でGPUドライバのインストールとライフサイクルを管理する必要があります。 バージョン 1.35 またはそれ以前を実行しているクラスタでは、 IBM- 提供のGPUドライバが引き続き利用可能です。 移行の手引きについては、 セルフマネージド NVIDIA GPU ドライバへの移行を 参照してください。

以下のステップは、GPU を必要とするワークロードをデプロイする方法を示しています。 ただし、GPUとCPUの両方でワークロードを処理する必要のないアプリもデプロイすることは可能です。

この Kubernetes デモでは、機械 TensorFlow 学習フレームワークなどの数学的に負荷の高いワークロードも試すことができます。

前提条件

開始前に

  • GPU フレーバーを使用する クラスター またはワーカー・プールを作成します。 ベアメタル・マシンのセットアップは、完了するまでに 1 営業日以上かかることがあることに留意してください。 使用可能なフレーバーのリストについては、以下のリンクを参照してください。

  • クラスター内の Kubernetes リソースを処理できる適切な Kubernetes RBAC 役割を付与する、サービス・アクセス役割が自分に割り当てられていることを確認します。

Kubernetes バージョン 1.36 以降の場合 : NVIDIA GPUドライバスタックをご自身でインストールし、管理する必要があります。 IBM Cloud Kubernetes Service は、ワーカーノードにプレインストールされたGPUドライバーを提供しなくなりました。 NVIDIA GPU Operatorインストールガイドに従って、必要なコンポーネントをインストールしてください:

  • NVIDIA カーネルドライバ
  • コンテナ・ランタイム・コンポーネント(例: nvidia-container-toolkit)
  • Kubernetes デバイスプラグイン

ドライバがインストールされるまで、GPUを要求するポッドは Pending。 これらのドライバは、ノード上で互換ドライバが利用可能になった後、自動的に Running

Kubernetes バージョン 1.35 以前の場合: IBM-提供されたGPUドライバーは、GPUワーカーノードに自動的にインストールされます。 ドライバーの追加インストールは不要です。

ワークロードのデプロイ

  1. YAML ファイルを作成します。 この例では、 Job のYAMLファイルが、コマンドが完了し正常に終了するまで実行される短命なPodを作成することで、バッチ処理のようなワークロードを管理します。

    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 デバイスプラグインは、デフォルトのリソース要求を制限値に合わせて設定します。

    • キーは「 nvidia.com/gpu 」と指定する必要があります。
    • 2 のように、要求する GPU の総数を入力してください。 コンテナー・ポッドは GPU を共有せず、GPU はオーバーコミットできないことに注意してください。 例えば、mg1c.16x128 マシンが 1 台のみの場合、そのマシンには GPU が 2 つしかないため、指定できるのは最大で 2 つです。
  2. YAML ファイルを適用します。 以下に例を示します。

    kubectl apply -f nvidia-devicequery.yaml
    
  3. nvidia-devicequery 」ラベルでポッドをフィルタリングして、ジョブポッドを確認してください。 STATUSCompleted であることを確認します。

    kubectl get pod -A -l 'name in (nvidia-devicequery)'
    

    出力例

    NAME                  READY     STATUS      RESTARTS   AGE
    nvidia-devicequery-ppkd4      0/1       Completed   0          36s
    
  4. ポッドに describe を実行して、GPU デバイス・プラグインがポッドをどのようにスケジュールしたかを確認します。

    • Limits フィールドと Requests フィールドで、指定したリソース制限とデバイス・プラグインが自動的に設定した要求とが一致していることを確認します。
    • イベントで、ポッドが GPU ワーカー・ノードに割り当てられていることを確認します。
        kubectl describe pod nvidia-devicequery-ppkd4
        ```
        出力例
        ```sh {: screen}
        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
        ...
        ```
    
  5. ジョブが GPU を使用してそのワークロードの計算を実行したことを検証するには、ログを確認します。

    kubectl 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

セルフマネージド NVIDIA GPU ドライバへの移行

Kubernetes バージョン 1.36 へのアップグレード時の IBM-提供 GPU ドライバからセルフマネージドドライバへの移行の詳細なガイダンスについては、 Kubernetes 1.36 用のセルフマネージド NVIDIA GPU ドライバへの移行を 参照してください。