Acceder a registros privados con certificados de CA privada


En esta página se explica cómo permitir que las cargas de trabajo que se ejecutan en Google Kubernetes Engine (GKE) accedan a registros de imágenes privados mediante la clave pública de la autoridad de certificación (CA) que emitió el certificado del registro.

Esta página está dirigida a especialistas en seguridad que gestionan el acceso a las cargas de trabajo de su organización. 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. Cloud de Confiance by S3NS

Antes de leer esta página, asegúrate de que conoces Secret Manager.

Cómo funciona el acceso a registros privados

Almacena la clave pública de la autoridad de certificación usada para emitir certificados para tus registros privados en Secret Manager y configura qué nombres de dominio completos (FQDNs) de registro usan esa clave pública para la validación de certificados. GKE obtiene automáticamente la clave y actualiza la configuración del registro del tiempo de ejecución del contenedor durante el arranque del nodo. Cuando despliega una carga de trabajo que usa una imagen de contenedor de su registro privado, se siguen estos pasos:

  1. El kubelet del nodo intenta extraer la imagen del registro privado.
  2. El registro presenta un certificado TLS del lado del servidor.
  3. El tiempo de ejecución del contenedor valida el certificado del registro de forma criptográfica y se asegura de que el FQDN coincida con el que has especificado.
  4. Si la validación se supera, GKE extrae la imagen y programa tu carga de trabajo.

Ventajas

Este método para acceder a registros privados ofrece ventajas como las siguientes:

  1. Mejorar la fiabilidad de la configuración del tiempo de ejecución del contenedor: usar métodos como DaemonSets para definir la configuración de containerd añade el riesgo de que se produzca una condición de carrera, en la que otros DaemonSets se ejecuten antes que tu DaemonSet de configuración.
  2. Reduce la vulnerabilidad a los ataques de escalada de privilegios: elimina la necesidad de ejecutar DaemonSets con privilegios que modifiquen la configuración del tiempo de ejecución del contenedor.
  3. Reduce la sobrecarga de gestión: Secret Manager te permite almacenar claves públicas de CA en una ubicación central, gestionar el acceso a las claves mediante IAM e implementar el control de versiones y las anotaciones. Para obtener más información, consulta la descripción general del producto Secret Manager.
  4. Mejorar la auditabilidad: Cloud Logging ya recoge registros, incluidos los de cuando se añaden certificados a un clúster y cuando los nodos de GKE extraen imágenes.

Precios

En este documento, se usan los siguientes componentes facturables de Cloud de Confiance:

  • GKE
  • Secret Manager
  • Registro: GKE genera registros de auditoría de actividad administrativa y, si está habilitada, registros de auditoría de acceso a datos para esta función. Para obtener información sobre los diferentes tipos de registros de auditoría, consulta Registros de auditoría de GKE.

Para generar una estimación de costes basada en el uso previsto, utiliza la calculadora de precios.

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.
  • Enable the Secret Manager API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  • Ya debes tener un registro privado y certificados de AC privados para acceder al registro. En esta guía no se explica cómo configurar un registro privado ni cómo crear certificados.

Requisitos

Para usar claves públicas de una AC privada para acceder a registros privados, debes cumplir los siguientes requisitos:

  • Tus clústeres deben usar la versión 1.27.3-gke.1700 de GKE o una posterior.
  • Debes usar una imagen de nodo de Container-Optimized OS con containerd, que es la predeterminada para todos los clústeres de GKE, o imágenes de nodo de Ubuntu con containerd que tengan la versión 1.33.0 o una posterior. No se admiten imágenes de nodos de Windows Server.
  • Tus grupos de nodos deben tener el permiso de acceso cloud-platform para que tus nodos puedan descargar los certificados. Para obtener más información, consulta Permisos de acceso predeterminados en GKE. En este documento se incluyen instrucciones para definir el ámbito de acceso al crear un clúster o un grupo de nodos.

Limitaciones

Ten en cuenta las siguientes limitaciones:

  • No puedes usar certificados de AC privada en imágenes de nodos de Ubuntu con una versión anterior a la 1.33.0.
  • No puedes usar certificados de AC privada en nodos de Windows Server.
  • Cada clúster admite hasta cinco certificados de CA privada para registros privados.
  • Cada certificado puede tener hasta 25 nombres de dominio completos (FQDNs).
  • Cada dominio solo se puede usar en un archivo de certificado. Sin embargo, se admiten paquetes de certificados.
  • Los certificados deben estar codificados en PEM.
  • El servidor no rota los certificados automáticamente. Para obtener más información, consulta Rotar los certificados de tu autoridad de certificación privada en este documento.
  • Los FQDNs tienen las siguientes limitaciones:
    • La longitud máxima del FQDN es de 255 caracteres, incluidos los caracteres especiales.
    • Los FQDNs solo pueden usar letras, números y guiones (-).
    • No se admite Punycode.
    • No se admiten comodines.

Migrar desde DaemonSets de configuración

En los clústeres Estándar de GKE, puedes desplegar DaemonSets con privilegios para modificar la configuración del tiempo de ejecución de tu contenedor. Este método modifica directamente la configuración de containerd en cada nodo.

Si usas DaemonSets con privilegios para configurar el acceso a registros privados, ten en cuenta lo siguiente antes de usar este documento:

  • Almacenar las claves públicas de la CA privada solo en Secret Manager se configura el acceso a los registros privados. No se admite otra configuración relacionada con el registro.
  • Si habilitas esta función, tu clúster usará el modelo de configuración hostpath de CRI de containerd, que no es compatible con el modelo de configuración anterior. Si tienes algún DaemonSet que modifique la configuración del host de containerd, como para registros privados no seguros, réplicas o proxies, actualiza los DaemonSets para que usen el modelo de hostpath de CRI.

    Para ver los campos disponibles en el modelo de ruta de host de CRI, consulta la configuración del registro en el repositorio de GitHub de containerd.

Cuando habilitas esta función, GKE aplica el modelo de configuración de hostpath de CRI a los nodos nuevos del clúster. Los nodos actuales seguirán usando el modelo de configuración anterior hasta que se vuelvan a crear durante eventos como las actualizaciones.

Actualizar DaemonSets para que admita ambos modelos de configuración

Para reducir el riesgo de que tus DaemonSets de configuración no funcionen en nodos que admitan un modelo de configuración específico, asegúrate de que tus DaemonSets usen condicionalmente un modelo de configuración específico en función de los archivos de configuración de containerd del nodo. Para ver un ejemplo de DaemonSet que implementa esta lógica condicional, consulta el manifiesto insecure-registry-config.yaml en el GoogleCloudPlatform/k8s-node-toolsrepositorio de GitHub.

Almacenar las claves públicas de la CA en Secret Manager

Almacena las claves públicas de tus AC privadas que emiten tus certificados de registro privado como secretos en Secret Manager. Para obtener instrucciones, consulta el artículo Crear un secreto de la documentación de Secret Manager.

Configurar el acceso a Secret Manager desde GKE

Para asegurarte de que la cuenta de servicio de gestión de identidades y accesos del clúster tiene los permisos necesarios para extraer secretos de Secret Manager, pide a tu administrador que le conceda los siguientes roles de gestión de identidades y accesos en el secreto:

Para obtener más información sobre cómo conceder roles, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones.

Estos roles predefinidos contienen los permisos necesarios para extraer secretos de Secret Manager. Para ver los permisos exactos que se necesitan, despliega la sección Permisos necesarios:

Permisos obligatorios

Para extraer secretos de Secret Manager, se necesitan los siguientes permisos:

  • resourcemanager.projects.get
  • resourcemanager.projects.list
  • secretmanager.secrets.get
  • secretmanager.secrets.list
  • secretmanager.versions.get
  • secretmanager.versions.list
  • secretmanager.versions.access

Es posible que tu administrador también pueda conceder estos permisos a la cuenta de servicio de IAM del clúster con roles personalizados u otros roles predefinidos.

Si no has asociado una cuenta de servicio de gestión de identidades y accesos personalizada a tu clúster o grupo de nodos (que es el método recomendado), el clúster usará la cuenta de servicio predeterminada de Compute Engine.

Si es posible, te recomendamos que configures tus clústeres y grupos de nodos con una cuenta de servicio de gestión de identidades y accesos con los privilegios mínimos. Para obtener instrucciones, consulta Usar cuentas de servicio con el mínimo de privilegios.

Crear un archivo de configuración de tiempo de ejecución

Para poder usar certificados de AC privada en registros privados de GKE, debes crear un archivo YAML para modificar la configuración de containerd.

  1. Obtén el número de tu proyecto: Cloud de Confiance

    gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)"
    

    El resultado es el número de proyecto.

  2. Guarda la siguiente configuración como containerd-configuration.yaml:

    privateRegistryAccessConfig:
      certificateAuthorityDomainConfig:
      - gcpSecretManagerCertificateConfig:
          secretURI: "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION"
        fqdns:
          - "FQDN1"
          - "FQDN2"
      enabled: true
    

    Haz los cambios siguientes:

    • PROJECT_NUMBER: el número de proyecto que has obtenido en el paso anterior.
    • SECRET_VERSION: el número de versión de tu secreto en Secret Manager. También puedes usar un alias de versión, pero te recomendamos que utilices el número de versión para evitar que la gestión sea compleja.
    • FQDN1, FQDN2: los nombres de dominio completos de tus registros privados. También puedes usar una dirección IPv4 si se ha emitido un certificado para esa dirección, pero no lo recomendamos.

Para obtener una descripción de estos campos, consulta privateRegistryAccessConfig en la tabla de opciones de configuración de containerd disponibles.

Aplicar la configuración de containerd a clústeres nuevos

En esta sección se muestra cómo aplicar un archivo de configuración de containerd al crear un clúster de GKE.

Ejecuta el siguiente comando:

gcloud container clusters create-auto CLUSTER_NAME \
    --location=LOCATION \
    --scopes="cloud-platform" \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

Haz los cambios siguientes:

  • CLUSTER_NAME: el nombre del nuevo clúster.
  • LOCATION: la ubicación de Compute Engine de tu nuevo clúster.
  • PATH_TO_CONFIG_FILE: la ruta al archivo de configuración que has creado, como ~/containerd-configuration.yaml.

Puedes habilitar la configuración de registro privado en los nuevos clústeres Estándar ejecutando el comando gcloud container clusters create con las mismas opciones.

Aplicar la configuración de containerd a clústeres

En esta sección se muestra cómo aplicar una configuración de containerd a clústeres y nodos.

Comprobar los permisos de acceso

Los clústeres ya creados deben tener el ámbito de acceso cloud-platform para usar esta función. En esta sección se explica cómo comprobar los ámbitos de acceso y actualizar un clúster con un archivo de configuración de registro privado nuevo o modificado.

Para obtener información sobre los permisos de acceso predeterminados en los clústeres nuevos, consulta Permisos de acceso en GKE.

Comprobar los permisos de acceso de Autopilot

Ejecuta el siguiente comando:

gcloud container clusters describe CLUSTER_NAME \
    --location=LOCATION \
    --flatten=nodeConfig \
    --format='csv[delimiter="\\n",no-heading](oauthScopes)'

Si tu clúster no tiene el https://www.googleapis.com/auth/cloud-platform ámbito de acceso, crea uno nuevo con este ámbito.

Consultar los permisos de acceso estándar

Para comprobar los ámbitos de acceso de tu clúster estándar, consulta un grupo de nodos:

gcloud container node-pools describe NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --flatten=nodeConfig \
    --format='csv[delimiter="\\n",no-heading](oauthScopes)'

Sustituye NODE_POOL_NAME por el nombre del grupo de nodos.

Si tu clúster no tiene el ámbito de acceso https://www.googleapis.com/auth/cloud-platform, crea un grupo de nodos con el ámbito de acceso cloud-platform y elimina el grupo de nodos que ya tengas.

Actualizar el clúster para que use el archivo de configuración

Ejecuta el siguiente comando:

gcloud container clusters update CLUSTER_NAME \
    --location=LOCATION \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

Volver a crear nodos en clústeres estándar

Si tu clúster estándar no usa actualizaciones automáticas, debes volver a crear manualmente tus grupos de nodos para aplicar la nueva configuración. Para activar una recreación manual de nodos, actualiza tu clúster a la misma versión de GKE que ya utiliza.

gcloud container clusters upgrade CLUSTER_NAME \
    --location=LOCATION \
    --cluster-version=VERSION

Sustituye VERSION por la misma versión del parche de GKE que ya usa el clúster.

Verificar que el clúster puede acceder al registro privado

Ejecuta el siguiente comando:

gcloud container clusters describe CLUSTER_NAME \
    --location=LOCATION \
    --flatten="nodePoolDefaults.nodeConfigDefaults.containerdConfig"

El resultado debería ser similar al siguiente:

    containerdConfig:
      privateRegistryAccessConfig:
        certificateAuthorityDomainConfig:
        - fqdns:
          - 203.0.113.105
          gcpSecretManagerCertificateConfig:
            secretUri: projects/123456789012/secrets/example-secret-name/versions/1
        enabled: true

Desplegar una carga de trabajo que acceda a una imagen privada

En esta sección, desplegarás un pod estático que haga referencia a una imagen de tu registro privado.

  1. Guarda el siguiente archivo de manifiesto como private-registry-pod.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: private-registry-pod
    spec:
      containers:
      - name: private-image
        image: IMAGE_NAME
    

    Sustituye IMAGE_NAME por el nombre de tu imagen privada.

  2. Despliega el pod:

    kubectl create -f private-registry-pod.yaml
    

Rotar los certificados de AC privada

Secret Manager y GKE no pueden rotar automáticamente los certificados de AC privada en Secret Manager. Para llevar a cabo una rotación de certificados, sigue estos pasos. Para seguir estos pasos, debes volver a crear los nodos dos veces. Te recomendamos que realices rotaciones de certificados durante los periodos de inactividad programados para minimizar el impacto de las interrupciones en las cargas de trabajo.

  1. Crea un paquete de certificados codificado en PEM que contenga tanto el certificado antiguo como el nuevo.
  2. Añade el paquete como una nueva versión de secreto en Secret Manager.
  3. Actualiza el campo secretURI de tu archivo de configuración de tiempo de ejecución con el nuevo número de versión del secreto.
  4. Actualiza el clúster para usar la nueva versión del secreto.
  5. Obtén la marca de tiempo de la operación de actualización:

    gcloud container operations list \
        --filter="operationType ~ UPDATE_CLUSTER AND targetLink ~ CLUSTER_NAME" \
        --sort-by=startTime \
        --limit=1 \
        --format='value(endTime)'
    

    El resultado debería ser similar al siguiente:

    2024-01-31T09:27:30.864308964Z
    
  6. Busca los nodos que se crearon antes de que finalizara la operación de actualización:

    kubectl get nodes -o json | jq ".items[] |
    select(.metadata.creationTimestamp | fromdateiso8601 < $(date -d
    CLUSTER_UPDATE_TIMESTAMP +%s)) | .metadata.name"
    

    Sustituye CLUSTER_UPDATE_TIMESTAMP por la marca de tiempo del paso anterior.

    El resultado es una lista de nombres de nodos que no se han vuelto a crear con la configuración actualizada. Si la salida está en blanco, ve al siguiente paso.

  7. Crea una nueva versión del secreto en Secret Manager con solo el nuevo certificado.

  8. Repite los pasos anteriores para actualizar el clúster, obtener la marca de tiempo de la operación y verificar que los nodos usan la nueva versión del secreto.

  9. Elimina la versión antigua del secreto de Secret Manager.

Ver registros de auditoría en Logging

En esta sección se explica cómo usar Logging para comprobar si GKE ha instalado la versión de tu secreto en tus nodos.

  1. Ve a la página Explorador de registros de la Cloud de Confiance consola:

    Ir a Explorador de registros

  2. Especifica la siguiente consulta:

    resource.type="gce_instance"
    textPayload:"Installed certificate \\\"projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION\\\""
    

    Si la instalación del certificado se ha completado correctamente, el resultado será similar al siguiente:

    "Installed certificate "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION""
    

    Si no se ha podido instalar el certificado, el resultado será similar al siguiente:

    "Failed to install certificate "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION""
    

Prácticas recomendadas

Te recomendamos que sigas estas prácticas recomendadas cuando utilices esta función:

  • No uses alias para las versiones de secretos de Secret Manager. Usa el número de versión generado automáticamente para cada versión del secreto. Un alias puede apuntar a una versión de certificado diferente a lo largo del tiempo, lo que puede provocar complejidades a la hora de hacer un seguimiento de las versiones específicas que usan tus cargas de trabajo.
  • Usa las ventanas de mantenimiento y las exclusiones para controlar cuándo puede recrear GKE tus nodos para aplicar las configuraciones de containerd actualizadas.
  • Proporciona acceso a los secretos a nivel de secreto, no a nivel de proyecto.

Inhabilitar opciones de configuración de containerd

Para quitar la configuración personalizada, siga estos pasos:

  1. Actualiza el archivo de configuración para especificar enabled: false en el elemento de configuración que quieras inhabilitar y elimina cualquier otro campo del elemento, como en el siguiente ejemplo:

    privateRegistryAccessConfig:
      enabled: false
  2. Aplica el archivo de configuración actualizado a tu clúster. Para obtener instrucciones, consulta Aplicar la configuración de containerd a clústeres ya creados.

Solucionar problemas

Para ver los pasos para solucionar problemas, consulta Solucionar problemas del tiempo de ejecución del contenedor.