部署工作负载

本页面介绍了在 Google Distributed Cloud 硬件上部署工作负载的步骤,以及在配置工作负载时必须遵守的限制。

在完成这些步骤之前,您必须满足 Distributed Cloud 安装要求订购 Distributed Cloud 硬件

当 Google Distributed Cloud 机架到达您选择的目的地时,它已预配置了硬件、 Google Cloud以及您在订购 Distributed 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. 创建分布式 Cloud 集群

  5. 可选:如果您想与 Cloud Key Management Service 集成,以支持为工作负载数据使用 CMEK,请为本地存储启用对客户管理的加密密钥 (CMEK) 的支持。如需了解 Distributed Cloud 如何加密工作负载数据,请参阅本地存储安全

  6. 创建节点池。 在此步骤中,您将节点分配给节点池,并可以选择性地将节点池配置为使用 Cloud KMS 来封装和解封装 Linux 统一密钥设置 (LUKS) 密码,以加密工作负载数据。

  7. 获取集群的凭据以测试集群。

  8. 通过向用户分配项目的 Edge Container Viewer 角色 (roles/edgecontainer.viewer) 或 Edge Container Admin 角色 (roles/edgecontainer.admin),授予用户对集群的访问权限。

  9. 使用 RoleBindingClusterRoleBinding 为用户分配对集群资源的基于角色的精细访问权限

  10. 可选:启用 VM Runtime on Google Distributed Cloud 支持,以便在 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. 可选:配置 Private Service Connect,以允许您的 Pod 使用 Cloud VPN 访问Google Cloud API 和服务

将 NGINX 负载均衡器部署为服务

以下示例展示了如何在分布式云集群上部署 NGINX 服务器并将其公开为服务:

  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 功能的容器

以下示例说明了如何部署使用分布式云的 SR-IOV 网络功能运算符功能的 Pod。

创建分布式 Cloud 网络组件

按如下方式创建所需的分布式 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) 大小。有效值为 1500 和 9000。此值必须与 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:相应子网覆盖的 IPv4 地址范围(采用 IP 地址/前缀格式)。
    • 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 交换机

按照本部分中的步骤,在分布式云机架中为每个分布式云 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 交换机上的第二个网络接口。

      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 的文件,其中包含以下内容。此文件用于配置第二个 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 的文件,其中包含以下内容。此文件用于配置第二个 ToR 交换机上的第二个网络接口。

      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 资源的名称以及该资源已部署到的命名空间(在本例中为 default)。

  1. 创建一个名为 sriovpod.yaml 且包含以下内容的 Pod 规范文件:

         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 建立命令行 shell:

    kubectl exec -it sriovpod -- sh
    
  5. 在 Pod shell 中使用以下命令,确认 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

命名空间限制

Distributed Cloud 不支持以下命名空间:

  • hostPID
  • hostIPC
  • hostNetwork

资源类型限制

Distributed Cloud 不支持 CertificateSigningRequest 资源类型,该类型允许客户端根据签名请求请求颁发 X.509 证书。

安全上下文限制

Distributed Cloud 不支持特权模式安全上下文。

Pod 绑定限制

Distributed Cloud 不支持将 Pod 绑定到 HostNetwork 命名空间中的主机端口。此外,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 不支持用户或群组模拟。

管理命名空间限制

Distributed Cloud 不允许用户访问以下命名空间:

  • kube-system,但删除 ippools.whereabouts.cni.cncf.io 除外
  • anthos-identity-service
  • cert-manager
  • gke-connect
  • kubevirt
  • metallb-system,但编辑 configMap 资源以设置负载平衡 IP 地址范围除外
  • nf-operator
  • sriov-network-operator

网络钩子限制

Distributed Cloud 对 Webhook 的限制如下:

  • 您创建的任何变更 webhook 都会自动排除 kube-system 命名空间。
  • 以下资源类型的更改性 webhook 已停用:
    • nodes
    • persistentvolumes
    • certificatesigningrequests
    • tokenreviews

后续步骤