Endurecer el aislamiento de cargas de trabajo con GKE Sandbox

En esta página se describe cómo usar GKE Sandbox para proteger el kernel del host de tus nodos cuando los contenedores del pod ejecutan código desconocido o no fiable, o cuando necesitan un aislamiento adicional del nodo. En esta página se explica cómo habilitar GKE Sandbox y monitorizar los clústeres cuando GKE Sandbox está en ejecución.

Esta página está dirigida a los especialistas en seguridad que deben aislar sus cargas de trabajo para obtener una protección adicional frente a código desconocido o no fiable. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido, consulta Roles y tareas habituales de los usuarios de GKE. Trusted Cloud by S3NS

Antes de leer esta página, asegúrate de que conoces la descripción general de GKE Sandbox.

Habilitar GKE Sandbox

GKE Sandbox se puede usar en clústeres de Autopilot que ejecuten la versión 1.27.4-gke.800 de GKE o una posterior. Para empezar a desplegar cargas de trabajo de Autopilot en un sandbox, ve a la sección Trabajar con GKE Sandbox.

Para usar GKE Sandbox en clústeres de GKE Standard nuevos o ya creados, debes habilitar GKE Sandbox manualmente en el clúster.

Para obtener más información sobre las versiones de las GPUs, consulta los detalles en Compatibilidad con modelos de GPU.

Antes de empezar

Antes de empezar, asegúrate de que has realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la gcloud CLI, obtén la versión más reciente ejecutando gcloud components update.

Habilitar GKE Sandbox en un clúster Standard nuevo

El grupo de nodos predeterminado, que se crea al crear un clúster, no puede usar GKE Sandbox si es el único grupo de nodos del clúster, ya que las cargas de trabajo del sistema gestionadas por GKE deben ejecutarse por separado de las cargas de trabajo en zona de pruebas no fiables. Para habilitar GKE Sandbox durante la creación del clúster, debes añadir al menos un grupo de nodos adicional al clúster.

Consola

Para ver tus clústeres, ve al menú Google Kubernetes Engine de laTrusted Cloud consola.

  1. En la Trusted Cloud consola, ve a la página Crear un clúster de Kubernetes.

    Ir a Crear un clúster de Kubernetes

  2. Opcional, pero recomendado: En el menú de navegación, vaya a Clúster, haga clic en Funciones y seleccione las siguientes casillas para que se registren los mensajes de gVisor:

    • Cloud Logging
    • Cloud Monitoring
    • Managed Service para Prometheus
  3. Haz clic en Añadir grupo de nodos.

  4. En el menú de navegación, vaya a Grupos de nodos, expanda el nuevo grupo de nodos y haga clic en Nodos.

  5. Configura los siguientes ajustes del grupo de nodos:

    1. En la lista desplegable Tipo de imagen, selecciona Container-Optimized OS con Containerd (cos_containerd). Este es el único tipo de imagen admitido para el espacio aislado de GKE.
    2. En Configuración de la máquina, selecciona una Serie y un Tipo de máquina.
    3. Opcionalmente, si usas una versión compatible de GKE, selecciona un tipo de GPU o TPU. Debe ser uno de los siguientes tipos de GPU:

      • nvidia-gb200: NVIDIA GB200 NVL72 (vista previa)
      • nvidia-b200: NVIDIA B200 (180 GB) (versión preliminar)
      • nvidia-h200-141gb: NVIDIA H200 (141 GB) (vista previa)
      • nvidia-h100-mega-80gb: NVIDIA H100 Mega (80 GB)
      • nvidia-h100-80gb: NVIDIA H100 (80 GB)
      • nvidia-a100-80gb: NVIDIA A100 (80 GB)
      • nvidia-tesla-a100: NVIDIA A100 (40 GB)
      • nvidia-l4: NVIDIA L4
      • nvidia-tesla-t4: NVIDIA T4
      Para obtener más información, consulta la compatibilidad con modelos de GPU.

      o los siguientes tipos de TPU:

      • v4
      • v5e
      • v5p
      • v6e
  6. En el menú de navegación, debajo del nombre del grupo de nodos que estás configurando, haz clic en Seguridad y selecciona la casilla Habilitar el espacio aislado con gVisor.

  7. Sigue configurando el clúster y los grupos de nodos según sea necesario.

  8. Haz clic en Crear.

gcloud

GKE Sandbox no se puede habilitar en el grupo de nodos predeterminado y no es posible crear grupos de nodos adicionales al mismo tiempo que se crea un clúster con el comando gcloud. En su lugar, crea el clúster como lo harías normalmente. Aunque es opcional, te recomendamos que habilites el registro y la monitorización para que se registren los mensajes de gVisor.

A continuación, usa el comando gcloud container node-pools create y asigna el valor type=gvisor a la marca -- sandbox. El tipo de imagen de nodo debe ser cos_containerd para el entorno aislado de GKE.

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Sustituye las siguientes variables:

  • NODE_POOL_NAME: el nombre del nuevo grupo de nodos.
  • CLUSTER_NAME: el nombre de tu clúster.
  • NODE_VERSION: la versión que se va a usar en el grupo de nodos.
  • MACHINE_TYPE: el tipo de máquina que se va a usar en los nodos.

Para crear un grupo de nodos de GPU con GKE Sandbox, ejecuta el siguiente comando:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --accelerator=type=GPU_TYPE,gpu-driver-version=DRIVER_VERSION \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Haz los cambios siguientes:

  • GPU_TYPE: un tipo de GPU compatible. Para obtener más información, consulta GKE Sandbox.

  • MACHINE_TYPE: una máquina que coincida con el tipo de GPU solicitado. Para obtener más información, consulta los requisitos de GPU de Google Kubernetes Engine.

  • DRIVER_VERSION: la versión del controlador de NVIDIA que se va a instalar. Se puede definir lo siguiente:

    • default: instala la versión predeterminada del controlador para tu versión de GKE.
    • latest: instala la versión más reciente del controlador disponible para tu versión de GKE. Solo disponible para los nodos que usan Container-Optimized OS.

Para crear un grupo de nodos de TPU con GKE Sandbox, ejecuta el siguiente comando:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --num-nodes=NUM_NODES \
  --tpu-topology=TPU_TOPOLOGY \
  --machine-type=MACHINE_TYPE \
  --image-type=cos_containerd \
  --sandbox type=gvisor
  • MACHINE_TYPE: un tipo de TPU admitido. Para obtener más información, consulta GKE Sandbox.

Habilitar GKE Sandbox en un clúster Standard

Puedes habilitar GKE Sandbox en un clúster Standard que ya tengas añadiendo un nuevo grupo de nodos y habilitando la función en ese grupo.

Consola

Para crear un grupo de nodos con GKE Sandbox habilitado, sigue estos pasos:

  1. Ve a la página Google Kubernetes Engine en la Trusted Cloud consola.

    Ir a Google Kubernetes Engine

  2. Haz clic en el nombre del clúster que quieras modificar.

  3. Haz clic en Añadir grupo de nodos.

  4. Configura la página Detalles del grupo de nodos como se indica.

  5. En el menú de navegación, haga clic en Nodos y configure los siguientes ajustes:

    1. En la lista desplegable Tipo de imagen, selecciona Container-Optimized OS con Containerd (cos_containerd). Este es el único tipo de imagen admitido para el espacio aislado de GKE.
    2. En Configuración de la máquina, selecciona una Serie y un Tipo de máquina.
    3. Opcionalmente, si usas una versión compatible de GKE, selecciona un tipo de GPU o TPU. Debe ser uno de los siguientes tipos de GPU:

      • nvidia-gb200: NVIDIA GB200 NVL72 (vista previa)
      • nvidia-b200: NVIDIA B200 (180 GB) (versión preliminar)
      • nvidia-h200-141gb: NVIDIA H200 (141 GB) (vista previa)
      • nvidia-h100-mega-80gb: NVIDIA H100 Mega (80 GB)
      • nvidia-h100-80gb: NVIDIA H100 (80 GB)
      • nvidia-a100-80gb: NVIDIA A100 (80 GB)
      • nvidia-tesla-a100: NVIDIA A100 (40 GB)
      • nvidia-l4: NVIDIA L4
      • nvidia-tesla-t4: NVIDIA T4
      Para obtener más información, consulta la compatibilidad con modelos de GPU.

      o los siguientes tipos de TPU:

      • v4
      • v5e
      • v5p
      • v6e
  6. En el menú de navegación, haz clic en Seguridad y marca la casilla Habilitar sandbox con gVisor.

  7. Haz clic en Crear.

gcloud

Para crear un grupo de nodos con GKE Sandbox habilitado, usa un comando como el siguiente:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --machine-type=MACHINE_TYPE \
  --image-type=cos_containerd \
  --sandbox type=gvisor

El tipo de imagen de nodo debe ser cos_containerd para el entorno aislado de GKE.

Para crear un grupo de nodos de GPU con GKE Sandbox, ejecuta el siguiente comando:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --accelerator=type=GPU_TYPE,gpu-driver-version=DRIVER_VERSION \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Haz los cambios siguientes:

  • GPU_TYPE: un tipo de GPU compatible. Para obtener más información, consulta GKE Sandbox.

  • MACHINE_TYPE: una máquina que coincida con el tipo de GPU solicitado. Para obtener más información, consulta los requisitos de GPU de Google Kubernetes Engine.

  • DRIVER_VERSION: la versión del controlador de NVIDIA que se va a instalar. Se puede definir lo siguiente:

    • default: instala la versión predeterminada del controlador para tu versión de GKE.
    • latest: instala la versión más reciente del controlador disponible para tu versión de GKE. Solo disponible para los nodos que usan Container-Optimized OS.

Para crear un grupo de nodos de TPU con GKE Sandbox, ejecuta el siguiente comando:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --num-nodes=NUM_NODES \
  --tpu-topology=TPU_TOPOLOGY \
  --machine-type=MACHINE_TYPE \
  --image-type=cos_containerd \
  --sandbox type=gvisor
  • MACHINE_TYPE: un tipo de TPU admitido. Para obtener más información, consulta GKE Sandbox.

Opcional: Habilitar la monitorización y el registro

Es opcional, pero se recomienda habilitar Cloud Logging y Cloud Monitoring en el clúster para que se registren los mensajes de gVisor. Estos servicios están habilitados de forma predeterminada en los clústeres nuevos.

Puedes usar la consola de Trusted Cloud para habilitar estas funciones en un clúster ya creado.

  1. Ve a la página Google Kubernetes Engine en la Trusted Cloud consola.

    Ir a Google Kubernetes Engine

  2. Haz clic en el nombre del clúster que quieras modificar.

  3. En Funciones, en el campo Cloud Logging, haz clic en Editar Cloud Logging.

  4. Selecciona la casilla Habilitar Cloud Logging.

  5. Haz clic en Guardar cambios.

  6. Repite los mismos pasos para los campos Cloud Monitoring y Managed Service for Prometheus para habilitar esas funciones.

Usar GKE Sandbox en Autopilot y Estándar

En los clústeres de Autopilot y en los clústeres estándar con GKE Sandbox habilitado, puedes solicitar un entorno aislado para un pod especificando la gvisor RuntimeClass en la especificación del pod.

En el caso de los clústeres de Autopilot, asegúrate de que estás usando la versión 1.27.4-gke.800 de GKE o una posterior.

Ejecutar una aplicación en un entorno aislado

Para que una implementación se ejecute en un nodo con GKE Sandbox habilitado, asigna el valor gvisor a su spec.template.spec.runtimeClassName, como se muestra en el siguiente ejemplo:

# httpd.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd
  labels:
    app: httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      runtimeClassName: gvisor
      containers:
      - name: httpd
        image: httpd

Crea el despliegue:

kubectl apply -f httpd.yaml

El pod se despliega en un nodo con GKE Sandbox habilitado. Para verificar la implementación, busca el nodo en el que se ha implementado el pod:

kubectl get pods

El resultado debería ser similar al siguiente:

NAME                    READY   STATUS    RESTARTS   AGE
httpd-db5899bc9-dk7lk   1/1     Running   0          24s

En el resultado, busca el nombre del pod y comprueba el valor de RuntimeClass:

kubectl get pods POD_NAME -o jsonpath='{.spec.runtimeClassName}'

El resultado es gvisor.

También puedes enumerar la RuntimeClass de cada pod y buscar los pods en los que se haya definido gvisor:

kubectl get pods -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.runtimeClassName}\n{end}'

El resultado es el siguiente:

POD_NAME: gvisor

Este método para verificar que el pod se está ejecutando en un entorno aislado es fiable porque no depende de ningún dato del propio entorno aislado. No se puede confiar en nada de lo que se informe desde el sandbox, ya que podría ser defectuoso o malicioso.

Ejecutar un pod con aceleradores en GKE Sandbox

Para ejecutar una carga de trabajo de GPU o TPU en GKE Sandbox, añade el campo runtimeClassName: gvisor a tu manifiesto, como en los siguientes ejemplos:

  • Ejemplo de manifiesto de pods de GPU en el modo Estándar:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-gpu-pod
    spec:
      runtimeClassName: gvisor
      containers:
      - name: my-gpu-container
        image: nvidia/samples:vectoradd-cuda10.2
        resources:
          limits:
            nvidia.com/gpu: 1
    
  • Ejemplo de manifiesto de pods de GPU en modo Autopilot:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-gpu-pod
    spec:
      runtimeClassName: gvisor
      nodeSelector:
        cloud.google.com/gke-gpu-driver-version: "latest"
        cloud.google.com/gke-accelerator: nvidia-tesla-t4
      containers:
      - name: my-gpu-container
        image: nvidia/samples:vectoradd-cuda10.2
        resources:
          limits:
            nvidia.com/gpu: 1
    
  • Ejemplo de manifiesto de pods de TPU en modo Estándar o Autopilot:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-tpu-pod
    spec:
      runtimeClassName: gvisor
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
        cloud.google.com/gke-tpu-topology: 1x1
      containers:
      - name: my-tpu-container
        image: us-docker.pkg.dev/cloud-tpu-images/jax-ai-image/tpu:latest
        command:
          - bash
          - -c
          - |
            python -c 'import jax; print("TPU cores:", jax.device_count())'
        resources:
          limits:
            google.com/tpu: 1
          requests:
            google.com/tpu: 1
    

Puedes ejecutar cualquier pod de acelerador en modo Autopilot o Standard que cumpla los requisitos de versión y tipo de acelerador en GKE Sandbox añadiendo el campo runtimeClassName: gvisor al manifiesto. Para ejecutar pods de GPU en GKE, consulta lo siguiente:

Para ejecutar pods de TPU en GKE, consulta lo siguiente:

Los tipos de GPU compatibles con Autopilot son los siguientes:

  • nvidia-gb200: NVIDIA GB200 NVL72 (vista previa)
  • nvidia-b200: NVIDIA B200 (180 GB) (versión preliminar)
  • nvidia-h200-141gb: NVIDIA H200 (141 GB) (vista previa)
  • nvidia-h100-mega-80gb: NVIDIA H100 Mega (80 GB)
  • nvidia-h100-80gb: NVIDIA H100 (80 GB)
  • nvidia-a100-80gb: NVIDIA A100 (80 GB)
  • nvidia-tesla-a100: NVIDIA A100 (40 GB)
  • nvidia-l4: NVIDIA L4
  • nvidia-tesla-t4: NVIDIA T4
Para obtener más información, consulta Compatibilidad con modelos de GPU.

Ejecutar un pod normal junto con pods aislados

Los pasos de esta sección se aplican a las cargas de trabajo del modo Estándar. No es necesario que ejecutes pods normales junto con pods de sandbox en el modo Autopilot, ya que el modelo de precios de Autopilot elimina la necesidad de optimizar manualmente el número de pods programados en los nodos.

Después de habilitar GKE Sandbox en un grupo de nodos, puedes ejecutar aplicaciones de confianza en esos nodos sin usar un entorno aislado mediante el uso de marcas y tolerancias de nodos. Estos pods se denominan "pods normales" para distinguirlos de los pods en un espacio aislado.

Los pods normales, al igual que los pods aislados, no pueden acceder a otros servicios ni a los metadatos del clúster.Trusted Cloud Esta prevención forma parte de la configuración del nodo. Si tus pods normales o en un sandbox requieren acceso aTrusted Cloud servicios, usa Workload Identity Federation para GKE.

GKE Sandbox añade la siguiente etiqueta y taint a los nodos que pueden ejecutar pods en un entorno aislado:

labels:
  sandbox.gke.io/runtime: gvisor
taints:
- effect: NoSchedule
  key: sandbox.gke.io/runtime
  value: gvisor

Además de los ajustes de afinidad y tolerancia de nodos que haya en el manifiesto de tu pod, GKE Sandbox aplica los siguientes ajustes de afinidad y tolerancia de nodos a todos los pods que tengan RuntimeClass definido como gvisor:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: sandbox.gke.io/runtime
          operator: In
          values:
          - gvisor
tolerations:
  - effect: NoSchedule
    key: sandbox.gke.io/runtime
    operator: Equal
    value: gvisor

Para programar un pod normal en un nodo con GKE Sandbox habilitado, aplica manualmente la afinidad y la tolerancia de nodos descritas anteriormente en el manifiesto del pod.

  • Si tu pod puede ejecutarse en nodos con GKE Sandbox habilitado, añade la tolerancia.
  • Si tu pod debe ejecutarse en nodos con GKE Sandbox habilitado, añade la afinidad de nodo y la tolerancia.

Por ejemplo, el siguiente manifiesto modifica el manifiesto usado en Ejecutar una aplicación en un sandbox para que se ejecute como un pod normal en un nodo con pods en sandbox. Para ello, se elimina runtimeClass y se añaden tanto el taint como la tolerancia descritos anteriormente.

# httpd-no-sandbox.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-no-sandbox
  labels:
    app: httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: sandbox.gke.io/runtime
                operator: In
                values:
                - gvisor
      tolerations:
        - effect: NoSchedule
          key: sandbox.gke.io/runtime
          operator: Equal
          value: gvisor

Primero, comprueba que la implementación no se esté ejecutando en un espacio aislado:

kubectl get pods -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.runtimeClassName}\n{end}'

La salida es similar a la siguiente:

httpd-db5899bc9-dk7lk: gvisor
httpd-no-sandbox-5bf87996c6-cfmmd:

El httpd Deployment creado anteriormente se está ejecutando en un sandbox porque su runtimeClass es gvisor. La implementación de httpd-no-sandbox no tiene ningún valor para runtimeClass, por lo que no se está ejecutando en un sandbox.

A continuación, comprueba que el Deployment sin aislamiento se esté ejecutando en un nodo con GKE Sandbox. Para ello, ejecuta el siguiente comando:

kubectl get pod -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.nodeName}\n{end}'

El nombre del grupo de nodos se inserta en el valor de nodeName. Verifica que el pod se esté ejecutando en un nodo de un grupo de nodos con GKE Sandbox habilitado.

Verificar la protección de metadatos

Para validar la aserción de que los metadatos están protegidos de los nodos que pueden ejecutar pods en un espacio aislado, puedes ejecutar una prueba:

  1. Crea un Deployment aislado a partir del siguiente manifiesto con kubectl apply -f. Usa la imagen fedora, que incluye el comando curl. El pod ejecuta el comando /bin/sleep para asegurarse de que el despliegue se ejecuta durante 10.000 segundos.

    # sandbox-metadata-test.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: fedora
      labels:
        app: fedora
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: fedora
      template:
        metadata:
          labels:
            app: fedora
        spec:
          runtimeClassName: gvisor
          containers:
          - name: fedora
            image: fedora
            command: ["/bin/sleep","10000"]
    
  2. Obtén el nombre del pod con kubectl get pods y, a continuación, usa kubectl exec para conectarte al pod de forma interactiva.

    kubectl exec -it POD_NAME /bin/sh
    

    Te has conectado a un contenedor que se está ejecutando en el pod, en una sesión de /bin/sh.

  3. En la sesión interactiva, intenta acceder a una URL que devuelva metadatos del clúster:

    curl -s "http://169.254.169.254/computeMetadata/v1/instance/attributes/kube-env" -H "Metadata-Flavor: Google"
    

    El comando se bloquea y, finalmente, se agota el tiempo de espera porque los paquetes se descartan de forma silenciosa.

  4. Pulsa Ctrl+C para finalizar el comando curl y escribe exit para desconectarte del pod.

  5. Quita la línea RuntimeClass del manifiesto YAML y vuelve a implementar el pod con kubectl apply -f FILENAME. El pod aislado se termina y se vuelve a crear en un nodo sin GKE Sandbox.

  6. Obtén el nuevo nombre del pod, conéctate a él con kubectl exec y vuelve a ejecutar el comando curl. Esta vez, se devuelven resultados. La salida de este ejemplo se ha truncado.

    ALLOCATE_NODE_CIDRS: "true"
    API_SERVER_TEST_LOG_LEVEL: --v=3
    AUTOSCALER_ENV_VARS: kube_reserved=cpu=60m,memory=960Mi,ephemeral-storage=41Gi;...
    ...
    

    Escribe exit para desconectarte del Pod.

  7. Elimina la implementación:

    kubectl delete deployment fedora
    

Inhabilitar GKE Sandbox

No puedes inhabilitar GKE Sandbox en clústeres de Autopilot de GKE ni en grupos de nodos de GKE Standard. Si quieres dejar de usar GKE Sandbox, elimina el grupo de nodos.

Siguientes pasos