Implementa cargas de trabajo

En esta página, se describen los pasos para implementar cargas de trabajo en tu hardware de Google Distributed Cloud y las limitaciones que debes cumplir cuando configures tus cargas de trabajo.

Antes de completar estos pasos, debes cumplir con los requisitos de instalación de Distributed Cloud y pedir el hardware de Distributed Cloud.

Cuando el rack de Google Distributed Cloud llega al destino que elegiste, ya está configurado con hardware, Google Cloudy algunos parámetros de configuración de red que especificaste cuando pediste Distributed Cloud.

Los instaladores de Google completan la instalación física, y el administrador del sistema conecta Distributed Cloud a tu red local.

Después de que el hardware se conecta a tu red local, se comunica con Google Cloud para descargar actualizaciones de software y conectarse con tu proyectoGoogle Cloud . Luego, podrás aprovisionar grupos de nodos e implementar cargas de trabajo en Distributed Cloud.

Descripción general de implementación

Para implementar una carga de trabajo en tu hardware de Distributed Cloud, completa los siguientes pasos:

  1. Opcional: Habilita la API de Distributed Cloud Edge Network.

  2. Opcional: Inicializa la configuración de red de tu zona de Distributed Cloud.

  3. Opcional: Configura las redes de Distributed Cloud.

  4. Crea un clúster de Distributed Cloud.

  5. Opcional: Habilita la compatibilidad con las claves de encriptación administradas por el cliente (CMEK) para el almacenamiento local si deseas realizar la integración con Cloud Key Management Service para habilitar la compatibilidad con las CMEK para los datos de tu carga de trabajo. Para obtener información sobre cómo Distributed Cloud encripta los datos de las cargas de trabajo, consulta Seguridad del almacenamiento local.

  6. Crea un grupo de nodos. En este paso, asignarás nodos a un grupo de nodos y, de manera opcional, configurarás el grupo de nodos para que use Cloud KMS para encapsular y desencapsular la frase de contraseña de Linux Unified Key Setup (LUKS) para encriptar los datos de la carga de trabajo.

  7. Obtén credenciales para un clúster para probarlo.

  8. Otorga a los usuarios acceso al clúster asignándoles el rol de visualizador de contenedores de Edge (roles/edgecontainer.viewer) o el rol de administrador de contenedores de Edge (roles/edgecontainer.admin) en el proyecto.

  9. Asigna a los usuarios acceso detallado basado en roles a los recursos del clúster con RoleBinding y ClusterRoleBinding.

  10. Opcional: Habilita la compatibilidad con el entorno de ejecución de VM en Google Distributed Cloud para ejecutar cargas de trabajo en máquinas virtuales en Distributed Cloud.

  11. Opcional: Habilita la compatibilidad con GPU para ejecutar cargas de trabajo basadas en GPU en Distributed Cloud.

  12. Opcional: Conecta el clúster de Distributed Cloud aGoogle Cloud:

    1. Crea una conexión de VPN a tu proyecto Google Cloud .

    2. Verifica que la conexión de VPN esté operativa.

  13. Opcional: Configura el acceso privado a Google para permitir que tus Pods accedan a las APIs y los servicios con Cloud VPN.Google Cloud

  14. Opcional: Configura Private Service Connect para permitir que tus Pods accedan a las APIs y los servicios con Cloud VPN.Google Cloud

Implementa el balanceador de cargas de NGINX como un servicio

En el siguiente ejemplo, se ilustra cómo implementar el servidor NGINX y exponerlo como un servicio en un clúster de Distributed Cloud:

  1. Crea un archivo YAML llamado nginx-deployment.yaml con el siguiente contenido:

    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. Aplica el archivo YAML al clúster con el siguiente comando:

    kubectl apply -f nginx-deployment.yaml
    
  3. Crea un archivo YAML llamado nginx-service.yaml con el siguiente contenido:

    apiVersion: v1
    kind: Service
    metadata:
    name: nginx-service
    spec:
    type: LoadBalancer
    selector:
      app: nginx
      ports:
         - protocol: TCP
           port: 8080
           targetPort: 80
  4. Aplica el archivo YAML al clúster con el siguiente comando:

    kubectl apply -f nginx-deployment.yaml
    
  5. Obtén la dirección IP externa asignada al servicio por el balanceador de cargas de MetalLB con el siguiente comando:

    kubectl get services
    

    El comando muestra un resultado similar al siguiente:

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

Implementa un contenedor con funciones de SR-IOV

En el siguiente ejemplo, se ilustra cómo implementar un Pod que usa las funciones del operador de funciones de red de SR-IOV de Distributed Cloud.

Crea los componentes de redes de Distributed Cloud

Crea los componentes de redes de Distributed Cloud necesarios de la siguiente manera. Para obtener más información sobre estos componentes, consulta Funciones de redes de Distributed Cloud.

  1. Crea una red:

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

    Reemplaza lo siguiente:

    • NETWORK_NAME: Es un nombre descriptivo que identifica de forma única esta red.
    • REGION: Es la Google Cloud región a la que pertenece la zona de Distributed Cloud de destino.
    • ZONE_NAME: Es el nombre de la zona de Distributed Cloud de destino.
    • MTU_SIZE: Es el tamaño de la unidad de transmisión máxima (MTU) para esta red. Los valores válidos son 1,500 y 9,000. Este valor debe coincidir con el tamaño de la MTU de la red default y ser el mismo para todas las redes.
  2. Crea una subred:

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

    Reemplaza lo siguiente:

    • SUBNETWORK_NAME: Es un nombre descriptivo que identifica de forma única esta subred.
    • NETWORK_NAME: Es la red que encapsula esta subred.
    • IPV4_RANGE: Es el rango de direcciones IPv4 que abarca esta subred en el formato de dirección IP o prefijo.
    • VLAN_ID: Es el ID de VLAN de destino para esta subred.
    • REGION: Es la Google Cloud región a la que pertenece la zona de Distributed Cloud de destino.
    • ZONE_NAME: Es el nombre de la zona de Distributed Cloud de destino.
  3. Supervisa el estado de la subred hasta que se cree correctamente:

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

    Reemplaza lo siguiente:

    • REGION: Es la Google Cloud región a la que pertenece la zona de Distributed Cloud de destino.
    • ZONE_NAME: Es el nombre de la zona de Distributed Cloud de destino.

    El estado avanza de PENDING a PROVISIONING y, finalmente, a RUNNING.

    Registra el ID de VLAN, el bloque CIDR de la subred y la dirección IP de la puerta de enlace para el bloque CIDR. Usarás estos valores más adelante en este procedimiento.

Configura los recursos de NodeSystemConfigUpdate

Configura un recurso de operador de función de red NodeSystemConfigUpdate para cada nodo del clúster de la siguiente manera.

  1. Enumera los nodos que se ejecutan en el grupo de nodos del clúster de destino con el siguiente comando:

    kubectl get nodes | grep -v master
    

    El comando muestra un resultado similar al siguiente:

    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
    

    Registra los nombres de los nodos que se muestran y deriva sus nombres cortos. Por ejemplo, para el nodo pool-example-node-1-01-b2d82cc7, su nombre corto es node101.

  2. Para cada nodo que grabaste en el paso anterior, crea un archivo de recursos NodeSystemConfigUpdate dedicado con el siguiente contenido:

    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"

    Reemplaza lo siguiente:

    • NODE_NAME: Es el nombre completo del nodo de destino. Por ejemplo, pool-example-node-1-01-b2d82cc7.
    • NODE_SHORT_NAME: Es el nombre abreviado del nodo de destino derivado de su nombre completo. Por ejemplo, node101

    Asigna a cada archivo el nombre node-system-config-update-NODE_SHORT_NAME.yaml.

  3. Aplica cada uno de los archivos de recursos NodeSystemConfigUpdate al clúster con el siguiente comando:

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

    Reemplaza NODE_SHORT_NAME por el nombre abreviado del nodo de destino correspondiente.

    Cuando aplicas los recursos al clúster, se reinicia cada nodo afectado, lo que puede demorar hasta 30 minutos.

    1. Supervisa el estado de los nodos afectados hasta que todos se reinicien correctamente:
    kubectl get nodes | grep -v master
    

    El estado de cada nodo pasa de not-ready a ready a medida que se completan los reinicios.

Configura los conmutadores ToR para las funciones de red de SR-IOV

Sigue los pasos de esta sección para configurar las interfaces de red en cada conmutador ToR de Distributed Cloud del rack de Distributed Cloud para el funcionamiento de las funciones de red de SR-IOV.

  1. Crea un archivo llamado mlnc6-pcie1-tor1-sriov.yaml con el siguiente contenido: Este archivo configura la primera interfaz de red en el primer conmutador 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. Crea un archivo llamado mlnc6-pcie1-tor2-sriov.yaml con el siguiente contenido: Este archivo configura la segunda interfaz de red en el primer conmutador 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. Crea un archivo llamado mlnc6-pcie2-tor1-sriov.yaml con el siguiente contenido: Este archivo configura la primera interfaz de red en el segundo conmutador 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. Crea un archivo llamado mlnc6-pcie2-tor2-sriov.yaml con el siguiente contenido: Este archivo configura la segunda interfaz de red en el segundo conmutador 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. Aplica los archivos de configuración del ToR al clúster con los siguientes comandos:

    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
    

    Los nodos afectados se acordonan, se desvían y se reinician.

  6. Supervisa el estado de los nodos con el siguiente comando:

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

    Cuando todos los nodos afectados muestren syncStatus: Succeeded, presiona Ctrl + C para salir del bucle de comandos de supervisión.

    El comando muestra un resultado similar al siguiente, lo que indica que se habilitaron las funciones de red SR-IOV en los conmutadores ToR:

    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
    

Configura un recurso NetworkAttachmentDefinition

Configura un recurso NetworkAttachmentDefinition para el clúster de la siguiente manera:

  1. Crea un archivo llamado network-attachment-definition.yaml con el contenido siguiente:

    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"
    }
    }'

Reemplaza lo siguiente:

  • VLAN_ID: Es el ID de VLAN de la subred que creaste antes en esta guía.
  • SUBNETWORK_CIDR: Es el bloque CIDR de la subred.
  • GATEWAY_ADDRESS: Es la dirección IP de la puerta de enlace de la subred.
  1. Aplica el recurso al clúster con el siguiente comando:

    kubectl apply -f network-attachment-definition.yaml
    

Implementa un Pod con funciones de red SR-IOV

Completa los pasos de esta sección para implementar un Pod con funciones de red SR-IOV en el clúster. El campo annotations en el archivo de configuración del Pod especifica el nombre del recurso NetworkAttachmentDefinition que creaste anteriormente en esta guía y el espacio de nombres en el que se implementó (default en este ejemplo).

  1. Crea un archivo de especificación de Pod llamado sriovpod.yaml con el siguiente contenido:

         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. Aplica el archivo de especificación del Pod al clúster con el siguiente comando:

    kubectl apply -f sriovpod.yaml
    
  3. Verifica que el Pod se haya iniciado correctamente con el siguiente comando:

    kubectl get pods
    
  4. Establece una shell de línea de comandos para el Pod con el siguiente comando:

    kubectl exec -it sriovpod -- sh
    
  5. Confirma que el Pod se comunica con los conmutadores ToR a través de la función de operador de red SR-IOV con el siguiente comando en la shell del Pod:

    ip addr
    

    El comando muestra un resultado similar al siguiente:

    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
    

    La información que se muestra para la interfaz net1 indica que se estableció la conectividad de red entre los conmutadores ToR y el Pod.

Limitaciones para las cargas de trabajo de Distributed Cloud

Cuando configures tus cargas de trabajo de Distributed Cloud, debes cumplir con las limitaciones que se describen en esta sección. Distributed Cloud aplica estas limitaciones en todas las cargas de trabajo que implementas en tu hardware de Distributed Cloud.

Limitaciones de las cargas de trabajo de Linux

Distributed Cloud solo admite las siguientes capacidades de Linux para las cargas de trabajo:

  • 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

Restricciones de espacio de nombres

Distributed Cloud no admite los siguientes espacios de nombres:

  • hostPID
  • hostIPC
  • hostNetwork

Restricciones de tipo de recurso

Distributed Cloud no admite el tipo de recurso CertificateSigningRequest, que permite que un cliente solicite que se emita un certificado X.509 en función de una solicitud de firma.

Restricciones de contexto de seguridad

Distributed Cloud no admite el contexto de seguridad del modo con privilegios.

Restricciones de vinculación de Pod

Distributed Cloud no admite la vinculación de Pods a puertos de host en el espacio de nombres HostNetwork. Además, el espacio de nombres HostNetwork no está disponible.

Restricciones de volumen de hostPath

Distributed Cloud solo permite los siguientes volúmenes hostPath con acceso de lectura y escritura:

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

Restricciones del tipo de recurso PersistentVolumeClaim

Distributed Cloud solo permite los siguientes tipos de recursos PersistentVolumeClaim:

  • csi
  • nfs
  • local

Restricciones de tipo de volumen

Distributed Cloud solo permite los siguientes tipos de volúmenes:

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

Restricciones de tolerancia de Pods

Distributed Cloud no permite que los usuarios creen Pods en los nodos del plano de control. Específicamente, Distributed Cloud no permite programar Pods que tengan las siguientes claves de tolerancia:

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

Restricciones de suplantación de identidad

Distributed Cloud no admite la suplantación de usuarios o grupos.

Restricciones del espacio de nombres de administración

Distributed Cloud no permite que los usuarios accedan a los siguientes espacios de nombres:

  • kube-system, con la excepción de borrar ippools.whereabouts.cni.cncf.io
  • anthos-identity-service
  • cert-manager
  • gke-connect
  • kubevirt
  • metallb-system, con la excepción de la edición de recursos configMap para establecer rangos de direcciones IP de balanceo de cargas
  • nf-operator
  • sriov-network-operator

Restricciones de webhook

Distributed Cloud restringe los webhooks de la siguiente manera:

  • Cualquier webhook de mutación que crees excluirá automáticamente el espacio de nombres kube-system.
  • Los webhooks de mutación están inhabilitados para los siguientes tipos de recursos:
    • nodes
    • persistentvolumes
    • certificatesigningrequests
    • tokenreviews

¿Qué sigue?