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:
Opcional: Habilita la API de Distributed Cloud Edge Network.
Opcional: Inicializa la configuración de red de tu zona de Distributed Cloud.
Opcional: Configura las redes de Distributed Cloud.
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.
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.
Obtén credenciales para un clúster para probarlo.
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.Opcional: Conecta el clúster de Distributed Cloud aGoogle Cloud:
Opcional: Configura el acceso privado a Google para permitir que tus Pods accedan a las APIs y los servicios con Cloud VPN.Google Cloud
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:
Crea un archivo YAML llamado
nginx-deployment.yamlcon 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
Aplica el archivo YAML al clúster con el siguiente comando:
kubectl apply -f nginx-deployment.yaml
Crea un archivo YAML llamado
nginx-service.yamlcon el siguiente contenido:apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: LoadBalancer selector: app: nginx ports: - protocol: TCP port: 8080 targetPort: 80
Aplica el archivo YAML al clúster con el siguiente comando:
kubectl apply -f nginx-deployment.yaml
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.
Crea una red:
gcloud edge-cloud networking networks create NETWORK_NAME \ --location=REGION \ --zone=ZONE_NAME \ --mtu=MTU_SIZEReemplaza 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 reddefaulty ser el mismo para todas las redes.
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_NAMEReemplaza 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.
Supervisa el estado de la subred hasta que se cree correctamente:
watch -n 30 'gcloud edge-cloud networking subnets list \ --location=REGION \ --zone=ZONE_NAMEReemplaza 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
PENDINGaPROVISIONINGy, finalmente, aRUNNING.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.
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.200Registra 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 esnode101.Para cada nodo que grabaste en el paso anterior, crea un archivo de recursos
NodeSystemConfigUpdatededicado 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.Aplica cada uno de los archivos de recursos
NodeSystemConfigUpdateal clúster con el siguiente comando:kubectl apply -f node-system-config-update-NODE_SHORT_NAME.yaml
Reemplaza
NODE_SHORT_NAMEpor 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.
- 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-readyareadya 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.
Crea un archivo llamado
mlnc6-pcie1-tor1-sriov.yamlcon 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
Crea un archivo llamado
mlnc6-pcie1-tor2-sriov.yamlcon 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
Crea un archivo llamado
mlnc6-pcie2-tor1-sriov.yamlcon 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
Crea un archivo llamado
mlnc6-pcie2-tor2-sriov.yamlcon 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
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.
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:
Crea un archivo llamado
network-attachment-definition.yamlcon 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.
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).
Crea un archivo de especificación de Pod llamado
sriovpod.yamlcon 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
Aplica el archivo de especificación del Pod al clúster con el siguiente comando:
kubectl apply -f sriovpod.yaml
Verifica que el Pod se haya iniciado correctamente con el siguiente comando:
kubectl get pods
Establece una shell de línea de comandos para el Pod con el siguiente comando:
kubectl exec -it sriovpod -- sh
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 foreverLa información que se muestra para la interfaz
net1indica 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_READAUDIT_WRITECHOWNDAC_OVERRIDEFOWNERFSETIDIPC_LOCKIPC_OWNERKILLMKNODNET_ADMINNET_BIND_SERVICENET_RAWSETFCAPSETGIDSETPCAPSETUIDSYS_CHROOTSYS_NICESYS_PACCTSYS_RESOURCESYS_TIME
Restricciones de espacio de nombres
Distributed Cloud no admite los siguientes espacios de nombres:
hostPIDhostIPChostNetwork
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:
csinfslocal
Restricciones de tipo de volumen
Distributed Cloud solo permite los siguientes tipos de volúmenes:
configMapcsidownwardAPIemptyDirhostPathnfspersistentVolumeClaimprojectedsecret
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/masternode-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 borrarippools.whereabouts.cni.cncf.ioanthos-identity-servicecert-managergke-connectkubevirtmetallb-system, con la excepción de la edición de recursosconfigMappara establecer rangos de direcciones IP de balanceo de cargasnf-operatorsriov-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:
nodespersistentvolumescertificatesigningrequeststokenreviews