Configura cgroups de escritura para contenedores

Puedes permitir que las cargas de trabajo de Google Kubernetes Engine (GKE) administren recursos, como la CPU y la memoria, para los procesos secundarios con la API de cgroups de Linux. En este documento, se muestra cómo proporcionar a los contenedores acceso de lectura y escritura a la API de cgroups sin ejecutarlos en modo privilegiado.

Cuándo usar cgroups grabables

De forma predeterminada, Kubernetes proporciona a todos los contenedores de Linux acceso de solo lectura a la API de cgroups activando el sistema de archivos /sys/fs/cgroup en cada contenedor. De manera opcional, puedes permitir que GKE active este sistema de archivos en modo de lectura y escritura en Pods específicos para que los procesos raíz administren y restrinjan los recursos para los procesos secundarios.

Estos cgroups de escritura ayudan a mejorar la confiabilidad en aplicaciones como Ray, que ejecutan procesos del sistema y código del usuario en el mismo contenedor. Al escribir en el sistema de archivos /sys/fs/cgroup, Ray puede reservar partes de los recursos de un contenedor para procesos críticos. Puedes usar cgroups grabables para mejorar la confiabilidad en estas aplicaciones sin el riesgo de seguridad que implica usar el modo privilegiado para los contenedores.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta el comando gcloud components update para obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos que se describen en este documento.

Habilita los cgroups grabables para tus nodos

Habilita los cgroups grabables en tus grupos de nodos personalizando la configuración de containerd. Puedes aplicar esta configuración a todo tu clúster o a grupos de nodos específicos en clústeres estándar.

En el archivo de configuración de containerd, agrega una sección writableCgroups y configura el campo enabled como true. Para obtener más información, consulta Personaliza la configuración de containerd en los nodos de GKE.

writableCgroups:
  enabled: true

Especifica el archivo de configuración actualizado cuando crees o actualices un clúster o un grupo de nodos.

Cómo usar cgroups grabables en cargas de trabajo

Después de habilitar los cgroups grabables para tu clúster o grupos de nodos, configura tus cargas de trabajo para que cumplan con todos los siguientes requisitos:

  • Selecciona un nodo que tenga habilitados los cgroups de escritura.
  • Habilita los cgroups de escritura para uno o más contenedores en el Pod.
  • Usa la clase de calidad de servicio (QoS) garantizada cumpliendo con una de las siguientes condiciones:

    • Para las cargas de trabajo que especifican recursos a nivel del Pod, establece valores iguales para resources.requests y resources.limits en la especificación del Pod.
    • Para las cargas de trabajo que especifican recursos para cada contenedor, establece valores iguales para resources.requests y resources.limits en la especificación de cada contenedor del Pod, incluidos los contenedores init.

Para configurar estos requisitos, sigue estos pasos:

  1. Para seleccionar nodos que tengan habilitados los cgroups con permisos de escritura, agrega la etiqueta node.gke.io/enable-writable-cgroups: "true" al campo spec.nodeSelector en la especificación del Pod:

    node.gke.io/enable-writable-cgroups: "true"
    
  2. Para habilitar cgroups grabables para tu carga de trabajo, agrega una de las siguientes etiquetas al campo metadata.annotations en la especificación de tu Pod:

    • Habilita para todo el Pod:

      node.gke.io/enable-writable-cgroups: "true"
      
    • Habilita para un contenedor específico en el Pod:

      node.gke.io/enable-writable-cgroups.CONTAINER_NAME: "true"
      

      Reemplaza CONTAINER_NAME por el nombre del contenedor.

  3. Para configurar la clase de QoS garantizada para tu Pod, especifica solicitudes y límites de CPU y memoria iguales para cada contenedor del Pod o para todo el Pod, como en el siguiente ejemplo:

    resources:
      requests:
        cpu: "100m"
        memory: "100Mi"
      limits:
        cpu: "100m"
        memory: "100Mi"
    

    Debes especificar solicitudes y límites iguales para cada contenedor, incluso si habilitas cgroups grabables solo para uno de los contenedores del Pod.

La especificación final del Pod debería ser similar a los siguientes ejemplos.

  • En este ejemplo, se habilitan los cgroups de escritura para todos los contenedores del Pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: writable-cgroups-pod
      annotations:
        node.gke.io/enable-writable-cgroups: "true"
    spec:
      nodeSelector:
        node.gke.io/enable-writable-cgroups: "true"
      containers:
      - name: container
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
      resources:
        requests:
          cpu: "100m"
          memory: "100Mi"
        limits:
          cpu: "100m"
          memory: "100Mi"
    
  • En este ejemplo, se habilitan los cgroups grabables para un contenedor específico en un Pod con varios contenedores:

    apiVersion: v1
    kind: Pod
    metadata:
      name: writable-cgroups-per-container
      annotations:
        node.gke.io/enable-writable-cgroups.busybox-container: "true"
    spec:
      nodeSelector:
        node.gke.io/enable-writable-cgroups: "true"
      containers:
      - name: busybox-container
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"
      - name: container-disabled
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"
    

Verifica que el sistema de archivos cgroup sea grabable

Para verificar los permisos en el sistema de archivos /sys/fs/cgroup de un Pod o un contenedor, sigue estos pasos:

  1. Identifica un Pod que quieras verificar. Puedes usar uno de los Pods de muestra de la sección Usa cgroups grabables en cargas de trabajo.
  2. Crea una sesión de shell en el Pod:

    kubectl exec -it POD_NAME -- /bin/sh
    

    Reemplaza POD_NAME con el nombre del pod.

  3. Describe el sistema de archivos cgroup activado:

    mount | grep cgroup
    

    El resultado es similar a lo siguiente:

    cgroup on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
    

    En este resultado, rw indica que el sistema de archivos se puede escribir. Si ves ro en el resultado, el sistema de archivos es de solo lectura.

¿Qué sigue?