ワークロードをデプロイする

このページでは、Google Distributed Cloud ハードウェアにワークロードをデプロイする手順と、ワークロードの構成時に遵守する必要がある制限事項について説明します。

これらの手順を完了する前に、Distributed Cloud のインストール要件を満たしDistributed Cloud ハードウェアを注文する必要があります。

Google Distributed Cloud ラックが選択した宛先に到着すると、Distributed Cloud の注文時に指定したハードウェア、 Google Cloud、一部のネットワーク設定が事前構成されています。

Google の設置担当者が物理的な設置を完了し、システム管理者が Distributed Cloud をローカル ネットワークに接続します。

ハードウェアがローカル ネットワークに接続されると、 Google Cloud と通信してソフトウェア アップデートをダウンロードし、Google Cloud プロジェクトに接続します。これで、ノードプールをプロビジョニングして、Distributed Cloud にワークロードをデプロイする準備が整いました。

デプロイの概要

Distributed Cloud ハードウェアにワークロードをデプロイする手順は次のとおりです。

  1. 省略可: Distributed Cloud Edge Network API を有効にします

  2. 省略可: Distributed Cloud ゾーンのネットワーク構成を初期化します

  3. 省略可: Distributed Cloud ネットワーキングを構成します

  4. Distributed Cloud クラスタを作成します

  5. 省略可: Cloud Key Management Service と統合してワークロード データの CMEK のサポートを有効にする場合は、[ローカル ストレージの顧客管理の暗号鍵(CMEK)のサポートを有効にする] を選択します。Distributed Cloud がワークロード データを暗号化する方法については、ローカル ストレージのセキュリティをご覧ください。

  6. ノードプールを作成する。このステップでは、ノードをノードプールに割り当て、必要に応じて、Cloud KMS を使用してワークロード データの暗号化に使用する Linux Unified Key Setup(LUKS)パスフレーズをラップおよびラップ解除するようにノードプールを構成します。

  7. クラスタの認証情報を取得して、クラスタをテストします。

  8. プロジェクトに対する Edge Container 閲覧者ロールroles/edgecontainer.viewer)または Edge Container 管理者ロールroles/edgecontainer.admin)を割り当てて、ユーザーにクラスタへのアクセス権を付与します。

  9. RoleBindingClusterRoleBinding を使用して、クラスタ リソースへのきめ細かいロールベースのアクセス権をユーザーに割り当てます

  10. 省略可: Google Distributed Cloud 上の VM ランタイムのサポートを有効にして、Distributed Cloud 上の仮想マシンでワークロードを実行します

  11. 省略可: GPU サポートを有効にして、Distributed Cloud で GPU ベースのワークロードを実行します

  12. 省略可: Distributed Cloud クラスタをGoogle Cloudに接続します。

    1. Google Cloud プロジェクトへの VPN 接続を作成します

    2. VPN 接続が機能していることを確認します

  13. 省略可: 限定公開の Google アクセスを構成して、Pod が Cloud VPN を使用してGoogle Cloud API とサービスにアクセスできるようにします

  14. 省略可: Cloud VPN を使用して Pod がGoogle Cloud API とサービスにアクセスできるように Private Service Connect を構成します

NGINX ロードバランサをサービスとしてデプロイする

次の例は、NGINX サーバーをデプロイして、Distributed Cloud クラスタでサービスとして公開する方法を示しています。

  1. 次の内容で nginx-deployment.yaml という名前の YAML ファイルを作成します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: nginx
    labels:
      app: nginx
    spec:
    replicas: 1
    selector:
      matchLabels:
         app: nginx
    template:
      metadata:
         labels:
         app: nginx
      spec:
         containers:
         - name: nginx
         image: nginx:latest
         ports:
         - containerPort: 80 
  2. 次のコマンドを使用して、YAML ファイルをクラスタに適用します。

    kubectl apply -f nginx-deployment.yaml
    
  3. 次の内容で nginx-service.yaml という名前の YAML ファイルを作成します。

    apiVersion: v1
    kind: Service
    metadata:
    name: nginx-service
    spec:
    type: LoadBalancer
    selector:
      app: nginx
      ports:
         - protocol: TCP
           port: 8080
           targetPort: 80
  4. 次のコマンドを使用して、YAML ファイルをクラスタに適用します。

    kubectl apply -f nginx-deployment.yaml
    
  5. 次のコマンドを使用して、MetalLB ロードバランサによってサービスに割り当てられた外部 IP アドレスを取得します。

    kubectl get services
    

    このコマンドでは、次のような出力が返されます。

    NAME            TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE
    nginx-service   LoadBalancer   10.51.195.25   10.100.68.104   8080:31966/TCP   11d
    

SR-IOV 関数を使用してコンテナをデプロイする

次の例は、Distributed Cloud の SR-IOV ネットワーク関数オペレータ機能を使用する Pod をデプロイする方法を示しています。

Distributed Cloud ネットワーキング コンポーネントを作成する

次のように、必要な Distributed Cloud ネットワーキング コンポーネントを作成します。これらのコンポーネントの詳細については、Distributed Cloud のネットワーキング機能をご覧ください。

  1. ネットワークを作成します。

    gcloud edge-cloud networking networks create NETWORK_NAME \
        --location=REGION \
        --zone=ZONE_NAME \
        --mtu=MTU_SIZE
    

    次のように置き換えます。

    • NETWORK_NAME: このネットワークを一意に識別するわかりやすい名前。
    • REGION: ターゲットの Distributed Cloud ゾーンが属する Google Cloud リージョン。
    • ZONE_NAME: ターゲットの Distributed Cloud ゾーンの名前。
    • MTU_SIZE: このネットワークの最大伝送単位(MTU)サイズ。有効な値は 1,500 と 9,000 です。この値は default ネットワークの MTU サイズと一致し、すべてのネットワークで同じである必要があります。
  2. サブネットワークを作成します。

    gcloud edge-cloud networking subnets create SUBNETWORK_NAME \
        --network=NETWORK_NAME \
        --ipv4-range=IPV4_RANGE \
        --vlan-id=VLAN_ID \
        --location=REGION \
        --zone=ZONE_NAME
    

    次のように置き換えます。

    • SUBNETWORK_NAME: このサブネットワークを一意に識別する説明的な名前。
    • NETWORK_NAME: このサブネットワークをカプセル化するネットワーク。
    • IPV4_RANGE: このサブネットワークが IP アドレス/プレフィックス形式でカバーする IPv4 アドレス範囲。
    • VLAN_ID: このサブネットワークのターゲット VLAN ID。
    • REGION: ターゲットの Distributed Cloud ゾーンが属する Google Cloud リージョン。
    • ZONE_NAME: ターゲットの Distributed Cloud ゾーンの名前。
  3. サブネットワークが正常に作成されるまで、サブネットワークのステータスをモニタリングします。

    watch -n 30 'gcloud edge-cloud networking subnets list \
        --location=REGION \
        --zone=ZONE_NAME
    

    次のように置き換えます。

    • REGION: ターゲットの Distributed Cloud ゾーンが属する Google Cloud リージョン。
    • ZONE_NAME: ターゲットの Distributed Cloud ゾーンの名前。

    ステータスは PENDING から PROVISIONING に進み、最終的に RUNNING になります。

    VLAN ID、サブネットワーク CIDR ブロック、CIDR ブロックのゲートウェイ IP アドレスを記録します。これらの値は、この手順の後半で使用します。

NodeSystemConfigUpdate リソースを構成する

クラスタ内の各ノードに対して、次のように NodeSystemConfigUpdate ネットワーク関数オペレータ リソースを構成します。

  1. 次のコマンドを使用して、ターゲット クラスタのノードプールで実行されているノードを一覧表示します。

    kubectl get nodes | grep -v master
    

    このコマンドでは、次のような出力が返されます。

    NAME                                 STATUS   ROLES       AGE     VERSION
    pool-example-node-1-01-b2d82cc7      Ready    <none>      2d      v1.22.8-gke.200
    pool-example-node-1-02-52ddvfc9      Ready    <none>      2d      v1.22.8-gke.200
    

    返されたノード名を記録し、その短縮名を導出します。たとえば、pool-example-node-1-01-b2d82cc7 ノードの略称は node101 です。

  2. 前の手順で記録した各ノードについて、次の内容を含む専用の NodeSystemConfigUpdate リソース ファイルを作成します。

    apiVersion: networking.gke.io/v1
    kind: NodeSystemConfigUpdate
    metadata:
    name: nodesystemconfigupdate-NODE_SHORT_NAME
    namespace: nf-operator
    spec:
    kubeletConfig:
      cpuManagerPolicy: Static
      topologyManagerPolicy: SingleNumaNode
    nodeName: NODE_NAME
    osConfig:
      hugePagesConfig:
         ONE_GB: 2
         TWO_MB: 0
      isolatedCpusPerSocket:
         "0": 40
         "1": 40
    sysctls:
      nodeLevel:
         net.core.rmem_max: "8388608"
         net.core.wmem_max: "8388608"

    次のように置き換えます。

    • NODE_NAME: ターゲット ノードの完全な名前。例: pool-example-node-1-01-b2d82cc7
    • NODE_SHORT_NAME: ターゲット ノードの完全名から派生した短い名前。例: node101

    各ファイルに node-system-config-update-NODE_SHORT_NAME.yaml という名前を付けます。

  3. 次のコマンドを使用して、各 NodeSystemConfigUpdate リソース ファイルをクラスタに適用します。

    kubectl apply -f node-system-config-update-NODE_SHORT_NAME.yaml
    

    NODE_SHORT_NAME は、対応するターゲット ノードの短い名前に置き換えます。

    リソースをクラスタに適用すると、影響を受ける各ノードが再起動します。これには最大 30 分かかることがあります。

    1. 影響を受けるノードのステータスをモニタリングし、すべてのノードが正常に再起動されるまで待ちます。
    kubectl get nodes | grep -v master
    

    各ノードのステータスは、再起動が完了すると not-ready から ready に移行します。

SR-IOV ネットワーク機能用に ToR スイッチを構成する

このセクションの手順に沿って、Distributed Cloud ラック内の各 Distributed Cloud ToR スイッチのネットワーク インターフェースを SR-IOV ネットワーク機能の動作用に構成します。

  1. 次の内容のファイルを mlnc6-pcie1-tor1-sriov.yaml という名前で作成します。このファイルは、最初の ToR スイッチの最初のネットワーク インターフェースを構成します。

      apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
      kind: SriovNetworkNodePolicy
      metadata:
      name: mlnx6-pcie1-tor1-sriov
      namespace: sriov-network-operator
      spec:
      deviceType: netdevice
      isRdma: false
      linkType: eth
      mtu: 9000
      nicSelector:
         pfNames:
         - enp59s0f0np0
      nodeSelector:
         edgecontainer.googleapis.com/network-sriov.capable: "true"
      numVfs: 31
      priority: 99
      resourceName: mlnx6_pcie1_tor1_sriov
  2. 次の内容のファイルを mlnc6-pcie1-tor2-sriov.yaml という名前で作成します。このファイルは、最初の ToR スイッチの 2 番目のネットワーク インターフェースを構成します。

      apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
      kind: SriovNetworkNodePolicy
      metadata:
      name: mlnx6-pcie1-tor2-sriov
      namespace: sriov-network-operator
      spec:
      deviceType: netdevice
      isRdma: false
      linkType: eth
      mtu: 9000
      nicSelector:
         pfNames:
         - enp59s0f1np1
      nodeSelector:
         edgecontainer.googleapis.com/network-sriov.capable: "true"
      numVfs: 31
      priority: 99
      resourceName: mlnx6_pcie1_tor2_sriov
  3. 次の内容のファイルを mlnc6-pcie2-tor1-sriov.yaml という名前で作成します。このファイルは、2 番目の ToR スイッチの最初のネットワーク インターフェースを構成します。

      apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
      kind: SriovNetworkNodePolicy
      metadata:
      name: mlnx6-pcie2-tor1-sriov
      namespace: sriov-network-operator
      spec:
      deviceType: netdevice
      isRdma: false
      linkType: eth
      mtu: 9000
      nicSelector:
         pfNames:
         - enp216s0f0np0
      nodeSelector:
         edgecontainer.googleapis.com/network-sriov.capable: "true"
      numVfs: 31
      priority: 99
      resourceName: mlnx6_pcie2_tor1_sriov
  4. 次の内容のファイルを mlnc6-pcie2-tor2-sriov.yaml という名前で作成します。このファイルは、2 番目の ToR スイッチの 2 番目のネットワーク インターフェースを構成します。

      apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
      kind: SriovNetworkNodePolicy
      metadata:
      name: mlnx6-pcie2-tor2-sriov
      namespace: sriov-network-operator
      spec:
      deviceType: netdevice
      isRdma: false
      linkType: eth
      mtu: 9000
      nicSelector:
         pfNames:
         - enp216s0f1np1
      nodeSelector:
         edgecontainer.googleapis.com/network-sriov.capable: "true"
      numVfs: 31
      priority: 99
      resourceName: mlnx6_pcie2_tor2_sriov
  5. 次のコマンドを使用して、ToR 構成ファイルをクラスタに適用します。

    kubectl apply -f mlnc6-pcie1-tor1-sriov.yaml
    kubectl apply -f mlnc6-pcie1-tor2-sriov.yaml
    kubectl apply -f mlnc6-pcie2-tor1-sriov.yaml
    kubectl apply -f mlnc6-pcie2-tor2-sriov.yaml
    

    影響を受けるノードは閉鎖され、ドレインされ、再起動されます。

  6. 次のコマンドを使用して、ノードのステータスをモニタリングします。

    watch -n 5 'kubectl get sriovnetworknodestates -o yaml -A | \ 
    grep "syncStatus\|pool-"|sed "N;s/\n/ /"'
    

    影響を受けるすべてのノードに syncStatus: Succeeded が表示されたら、Ctrl+C キーを押してモニタリング コマンドループを終了します。

    このコマンドは、次のような出力を返します。これは、ToR スイッチで SR-IOV ネットワーク機能が有効になっていることを示しています。

    Allocated resources:
    (Total limits may be over 100 percent, i.e., overcommitted.)
    Resource                       Requests     Limits
    --------                       --------     ------
    cpu                            2520m (3%)   7310m (9%)
    memory                         3044Mi (1%)  9774Mi (3%)
    ephemeral-storage              0 (0%)       0 (0%)
    hugepages-1Gi                  0 (0%)       0 (0%)
    hugepages-2Mi                  0 (0%)       0 (0%)
    devices.kubevirt.io/kvm        0            0
    devices.kubevirt.io/tun        0            0
    devices.kubevirt.io/vhost-net  0            0
    gke.io/mlnx6_pcie1_tor1_sriov  3            3
    gke.io/mlnx6_pcie1_tor2_sriov  0            0
    gke.io/mlnx6_pcie2_tor1_sriov  0            0
    gke.io/mlnx6_pcie2_tor2_sriov  0            0
    

NetworkAttachmentDefinition リソースを構成する

クラスタの NetworkAttachmentDefinition リソースを次のように構成します。

  1. 次の内容のファイルを network-attachment-definition.yaml という名前で作成します。

    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
    name: sriov-net1
    annotations:
      k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx6_pcie1_tor1_sriov
    spec:
    config: '{
    "type": "sriov",
    "cniVersion": "0.3.1",
    "vlan": VLAN_ID,
    "name": "sriov-network",
    "ipam": {
      "type": "host-local",
      "subnet": "SUBNETWORK_CIDR",
      "routes": [{
         "dst": "0.0.0.0/0"
      }],
      "gateway": "GATEWAY_ADDRESS"
    }
    }'

次のように置き換えます。

  • VLAN_ID: このガイドの前半で作成したサブネットワークの VLAN ID。
  • SUBNETWORK_CIDR: サブネットワークの CIDR ブロック。
  • GATEWAY_ADDRESS: サブネットワークのゲートウェイ IP アドレス。
  1. 次のコマンドを使用して、リソースをクラスタに適用します。

    kubectl apply -f network-attachment-definition.yaml
    

SR-IOV ネットワーク関数を使用して Pod をデプロイする

このセクションの手順を完了して、クラスタに SR-IOV ネットワーク関数を含む Pod をデプロイします。Pod の構成ファイルの annotations フィールドには、このガイドの前半で作成した NetworkAttachmentDefinition リソースの名前と、そのリソースがデプロイされた Namespace(この例では default)を指定します。

  1. 次の内容で Pod 仕様ファイル sriovpod.yaml を作成します。

         apiVersion: v1
         kind: Pod
         metadata:
         name: sriovpod
         annotations:
            k8s.v1.cni.cncf.io/networks: default/sriov-net1
         spec:
         containers:
         - name: sleeppodsriov
            command: ["sh", "-c", "trap : TERM INT; sleep infinity & wait"]
            image: busybox
            securityContext:
               capabilities:
               add:
                  - NET_ADMIN
  2. 次のコマンドを使用して、Pod 仕様ファイルをクラスタに適用します。

    kubectl apply -f sriovpod.yaml
    
  3. 次のコマンドを使用して、Pod が正常に起動したことを確認します。

    kubectl get pods
    
  4. 次のコマンドを使用して、Pod のコマンドライン シェルを確立します。

    kubectl exec -it sriovpod -- sh
    
  5. Pod シェルで次のコマンドを使用して、Pod が SR-IOV ネットワーク機能オペレータ機能を使用して ToR スイッチと通信していることを確認します。

    ip addr
    

    このコマンドでは、次のような出力が返されます。

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
       link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
       inet 127.0.0.1/8 scope host lo
          valid_lft forever preferred_lft forever
       inet6 ::1/128 scope host 
          valid_lft forever preferred_lft forever
    51: net1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 9000 qdisc mq qlen 1000
       link/ether 2a:af:96:a5:42:ab brd ff:ff:ff:ff:ff:ff
       inet 192.168.100.11/25 brd 192.168.100.127 scope global net1
          valid_lft forever preferred_lft forever
    228: eth0@if229: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue qlen 1000
       link/ether 46:c9:1d:4c:bf:32 brd ff:ff:ff:ff:ff:ff
       inet 10.10.3.159/32 scope global eth0
          valid_lft forever preferred_lft forever
       inet6 fe80::44c9:1dff:fe4c:bf32/64 scope link 
          valid_lft forever preferred_lft forever
    

    net1 インターフェースで返される情報は、ToR スイッチと Pod 間のネットワーク接続が確立されたことを示します。

Distributed Cloud ワークロードの制限事項

Distributed Cloud ワークロードを構成する場合は、このセクションで説明する制限事項を遵守する必要があります。これらの制限は、Distributed Cloud ハードウェアにデプロイするすべてのワークロードに Distributed Cloud によって適用されます。

Linux ワークロードの制限

Distributed Cloud は、ワークロードに関する次の Linux 機能のみをサポートします。

  • AUDIT_READ
  • AUDIT_WRITE
  • CHOWN
  • DAC_OVERRIDE
  • FOWNER
  • FSETID
  • IPC_LOCK
  • IPC_OWNER
  • KILL
  • MKNOD
  • NET_ADMIN
  • NET_BIND_SERVICE
  • NET_RAW
  • SETFCAP
  • SETGID
  • SETPCAP
  • SETUID
  • SYS_CHROOT
  • SYS_NICE
  • SYS_PACCT
  • SYS_RESOURCE
  • SYS_TIME

Namespace の制限事項

Distributed Cloud は、次の名前空間をサポートしていません。

  • hostPID
  • hostIPC
  • hostNetwork

リソースタイプの制限

Distributed Cloud は、署名リクエストに基づいてクライアントが X.509 証明書の発行をリクエストできる CertificateSigningRequest リソースタイプをサポートしていません。

セキュリティ コンテキストの制限

Distributed Cloud は、特権モードのセキュリティ コンテキストをサポートしていません。

Pod バインディングの制限

Distributed Cloud は、Pod から HostNetwork Namespace 内のホストポートへのバインドをサポートしていません。また、HostNetwork 名前空間は使用できません。

hostPath の音量制限

Distributed Cloud では、読み取り/書き込みアクセス権を持つ次の hostPath ボリュームのみが許可されます。

  • /dev/hugepages
  • /dev/infiniband
  • /dev/vfio
  • /dev/char
  • /sys/devices

PersistentVolumeClaim リソースタイプの制限

Distributed Cloud で許可される PersistentVolumeClaim リソースタイプは次のとおりです。

  • csi
  • nfs
  • local

ボリューム タイプの制限

Distributed Cloud では、次のボリューム タイプのみが許可されます。

  • configMap
  • csi
  • downwardAPI
  • emptyDir
  • hostPath
  • nfs
  • persistentVolumeClaim
  • projected
  • secret

Pod の容認制限

Distributed Cloud では、コントロール プレーン ノードでユーザーが作成した Pod は許可されません。具体的には、Distributed Cloud では、次の容認キーを持つ Pod のスケジュール設定は許可されません。

  • ""
  • node-role.kubernetes.io/master
  • node-role.kubernetes.io/control-plane

権限借用の制限

Distributed Cloud は、ユーザーまたはグループのなりすましをサポートしていません。

管理 Namespace の制限事項

Distributed Cloud では、ユーザーは次の名前空間にアクセスできません。

  • kube-systemippools.whereabouts.cni.cncf.io の削除を除く)
  • anthos-identity-service
  • cert-manager
  • gke-connect
  • kubevirt
  • metallb-system(ロード バランシング IP アドレス範囲を設定するための configMap リソースの編集を除く)
  • nf-operator
  • sriov-network-operator

Webhook を制限

Distributed Cloud は、Webhook を次のように制限します。

  • 作成した変更用 Webhook は、kube-system Namespace を自動的に除外します。
  • 次のリソースタイプでは、ミューテーション Webhook が無効になっています。
    • nodes
    • persistentvolumes
    • certificatesigningrequests
    • tokenreviews

次のステップ