Accede a registros privados con certificados de la AC privados


En esta página, se muestra cómo permitir que las cargas de trabajo que se ejecutan en Google Kubernetes Engine (GKE) accedan a los registros de imágenes privadas con la clave pública de la autoridad certificadora (CA) que emitió el certificado para el registro.

Cómo funciona

Almacena la clave pública de la AC que se usa con el objetivo de emitir certificados para tus registros privados en Secret Manager y configura qué nombres de dominio completamente calificados (FQDN) del registro usan esa clave pública para la validación del certificado. GKE recupera automáticamente la clave y actualiza la configuración del registro del entorno de ejecución del contenedor durante el inicio del nodo. Cuando implementas una carga de trabajo que usa una imagen de contenedor de tu registro privado, se producen los siguientes pasos:

  1. El kubelet en el nodo intenta extraer la imagen del registro privado.
  2. El registro presenta un certificado TLS del servidor.
  3. El entorno de ejecución del contenedor valida el certificado de registro con firma criptográfica y garantiza que el FQDN coincide con lo que especificaste.
  4. Si se aprueba la validación, GKE extrae la imagen y programa tu carga de trabajo.

Ventajas

Este método de acceso a los registros privados proporciona beneficios como los siguientes:

  1. Mejora la confiabilidad de la configuración del entorno de ejecución del contenedor: El uso de métodos como DaemonSets para establecer la configuración de conteinerd agrega el riesgo de que ocurra una condición de carrera, en la que otros DaemonSets podrían ejecutarse antes de tu DaemonSet de configuración.
  2. Reducir la vulnerabilidad a los ataques de elevación de privilegios: Quita la necesidad de ejecutar DaemonSets con privilegios que modifican la configuración del entorno de ejecución del contenedor.
  3. Reduce la sobrecarga de administración: Secret Manager te permite almacenar claves públicas de AC en una ubicación central; administrar el acceso a las claves con la IAM y, además, implementar el control de versión y anotaciones. Para obtener más información, consulta la Descripción general del producto de Secret Manager.
  4. Mejora la auditabilidad: Cloud Logging ya recopila registros, incluso cuando se agregan certificados a un clúster y cuando los nodos de GKE extraen imágenes.

Precios

En este documento, usarás los siguientes componentes facturables de Google Cloud:

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

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.

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 gcloud components update para obtener la versión más reciente.
  • Enable the Secret Manager API.

    Enable the API

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

Requisitos

Si quieres usar claves públicas de AC privadas para acceder a registros privados, debes cumplir con 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 Container-Optimized OS con containerd, que es la opción predeterminada para todos los clústeres de GKE. Las imágenes de nodo de Ubuntu con containerd no son compatibles. Las imágenes de nodos de Windows Server no son compatibles.
  • Tus grupos de nodos deben tener el permiso de acceso cloud-platform para que los nodos descarguen los certificados. Para obtener más información, consulta Permisos de acceso predeterminados en GKE. En este documento, se incluyen instrucciones para configurar el permiso de acceso cuando creas un clúster o un grupo de nodos.

Limitaciones

Ten en cuenta las siguientes limitaciones:

  • No puedes usar certificados de la AC privados en las imágenes de nodo de Ubuntu.
  • No puedes usar certificados de la AC privados en los nodos de Windows Server.
  • Cada clúster admite hasta cinco certificados de la AC privados para registros privados.
  • Cada certificado puede tener hasta 25 nombres de dominio completamente calificados (FQDN).
  • Cada dominio solo se puede usar en un único archivo de certificado. Sin embargo, los paquetes de certificados son compatibles.
  • Los certificados deben ser codificados con PEM.
  • El servidor no rota los certificados automáticamente. Para obtener más información, consulta Rota tus certificados de la AC privados en este documento.
  • Los FQDN tienen las siguientes limitaciones:
    • La longitud máxima del FQDN es de 255 caracteres, incluidos los caracteres especiales.
    • Los FQDN solo pueden usar letras, números y guiones (-).
    • Punycode no es compatible.
    • Los caracteres comodín no son compatibles.

Migra desde DaemonSets de configuración

En los clústeres de GKE Standard, puedes implementar DaemonSets con privilegios para modificar la configuración del entorno de ejecución del 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:

  • El almacenamiento de claves públicas de AC privadas en Secret Manager solo configura el acceso a los registros privados. No se admite otra configuración relacionada con el registro.
  • Habilitar esta función hace que tu clúster use el modelo de configuración de la ruta de acceso del host 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, duplicaciones o proxies, actualiza los DaemonSets para usar el modelo de la ruta de acceso del host de CRI.

    Para conocer los campos disponibles en el modelo de ruta de acceso del host de CRI, consulta Configuración del registro en el repositorio de GitHub de containerd.

Cuando habilitas esta función, GKE aplica el modelo de configuración de la ruta de acceso del host de CRI a nodos nuevos del clúster. Los nodos existentes continúan usando el modelo de configuración anterior hasta que se vuelven a crear durante eventos como las actualizaciones.

Actualiza los DaemonSets para que admitan 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 de forma condicional un modelo de configuración específico según los archivos de configuración en containerd en el nodo. Para ver un ejemplo de DaemonSet que implementa esta lógica condicional, en el repositorio de GitHub GoogleCloudPlatform/k8s-node-tools, consulta el manifiesto de insecure-registry-config.yaml.

Almacena tus claves públicas de CA en Secret Manager

Almacena las claves públicas de las AC privadas que emiten los certificados de registro privado como secretos en Secret Manager. Para obtener instrucciones, en la documentación de Secret Manager, consulta Crea un secreto.

Configura el acceso a Secret Manager desde GKE

Con el objetivo de garantizar que la cuenta de servicio de IAM del clúster tenga los permisos necesarios para extraer secretos de Secret Manager, pídele a tu administrador que otorgue a la cuenta de servicio de IAM del clúster los siguientes roles de IAM en el secreto:

Para obtener más información sobre cómo otorgar roles, consulta Administra 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 son necesarios, expande la sección Permisos requeridos:

Permisos necesarios

Se requieren los siguientes permisos para extraer secretos de Secret Manager:

  • 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 otorgar estos permisos a la cuenta de servicio de IAM del clúster con roles personalizados o con otros roles predefinidos.

Si no asociaste una cuenta de servicio de IAM personalizada con tu clúster o grupo de nodos, que es nuestro enfoque recomendado, el clúster usa 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 IAM con privilegios mínimos. Para obtener instrucciones, consulta Usa cuentas de servicio con privilegios mínimos.

Crea un archivo de configuración del entorno de ejecución

Para habilitar la capacidad de usar certificados de la AC privados en los registros privados en GKE, crea un archivo YAML con el objetivo de modificar la configuración de containerd.

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

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

    El resultado es el número de tu proyecto numérico.

  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
    

    Reemplaza lo siguiente:

    • PROJECT_NUMBER: el número de proyecto que obtuviste en el paso anterior.
    • SECRET_VERSION: el número de versión del secreto en Secret Manager. De forma opcional, puedes usar un alias de versión, pero te recomendamos usar el número de versión para evitar la complejidad de la administración.
    • FQDN1, FQDN2: los nombres de dominio completamente calificados para tus registros privados. También puedes usar una dirección IPv4 si se emitió 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.

Aplica 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 cuando creas clúster de GKE nuevo.

Ejecuta el siguiente comando:

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

Reemplaza lo siguiente:

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

Puedes habilitar la configuración de registro privado en clústeres estándar nuevos con la ejecución del comando gcloud container clusters create con las mismas opciones.

Aplica la configuración de containerd a los clústeres existentes

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

Verifica los permisos de acceso

Los clústeres existentes deben tener el permiso de acceso cloud-platform para usar esta función. En esta sección, se muestra cómo verificar los permisos de acceso y actualizar un clúster existente con un archivo de configuración de registro privado nuevo o modificado.

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

Verifica 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 permiso de acceso https://www.googleapis.com/auth/cloud-platform, crea un clúster nuevo con este permiso de acceso.

Verifica los permisos de acceso de Standard

Para verificar los permisos de acceso al clúster estándar, verifica 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)'

Reemplaza NODE_POOL_NAME por el nombre del grupo de nodos.

Si tu clúster no tiene el permiso de acceso https://www.googleapis.com/auth/cloud-platform, crea un grupo de nodos nuevo con el permiso de acceso cloud-platform y borra el grupo de nodos existente.

Actualiza el clúster para usar 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"

Vuelve a crear los nodos en los clústeres de Standard

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

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

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

Verifica que tu clúster pueda acceder al registro privado

Ejecuta el siguiente comando:

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

El resultado es similar al siguiente:

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

Implementa una carga de trabajo que acceda a una imagen privada

En esta sección, implementarás un Pod estático que hace referencia a una imagen de tu registro privado.

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

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

    Reemplaza IMAGE_NAME por el nombre de tu imagen privada.

  2. Implementa el Pod:

    kubectl create -f private-registry-pod.yaml
    

Rota tus certificados de la AC privados

Secret Manager y GKE no pueden rotar automáticamente los certificados de la AC privados en Secret Manager. Para realizar una rotación del certificado, sigue estos pasos. Estos pasos requieren que vuelvas a crear los nodos existentes dos veces. Te recomendamos que realices rotaciones de certificados durante el tiempo de inactividad programado para minimizar el impacto de las interrupciones de la carga de trabajo.

  1. Crea un paquete de certificados codificados con PEM que contenga los certificados antiguos y nuevos.
  2. Agrega el paquete como una versión nueva del secreto en Secret Manager.
  3. Actualiza el campo secretURI del archivo de configuración del entorno de ejecución con el nuevo número de versión del secreto.
  4. Actualiza tu clúster para usar la versión nueva 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 es similar al siguiente:

    2024-01-31T09:27:30.864308964Z
    
  6. Busca 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"
    

    Reemplaza CLUSTER_UPDATE_TIMESTAMP por la marca de tiempo del paso anterior.

    El resultado es una lista de nombres de nodos que no se volvieron a crear con la configuración actualizada. Cuando el resultado esté en blanco, continúa con el paso siguiente.

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

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

  9. Borra la versión anterior del secreto de Secret Manager.

Visualiza registros de auditoría en Registros

En esta sección, se muestra cómo usar los registros para verificar si GKE instaló tu versión del secreto en tus nodos.

  1. Ve al Explorador de registros en la consola de Google Cloud:

    Ir al 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 el certificado se instaló sin errores, el resultado es similar al siguiente:

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

    Si la instalación del certificado falló, el resultado es similar al siguiente:

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

Prácticas recomendadas

Te recomendamos aplicar las siguientes prácticas recomendadas cuando uses 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 del certificado diferente a lo largo del tiempo, lo que puede causar complejidades en el seguimiento de las versiones específicas que usan tus cargas de trabajo.
  • Usa períodos de mantenimiento y exclusiones para controlar cuándo GKE puede volver a crear los nodos con el objetivo de aplicar opciones de configuración actualizadas de containerd.
  • Proporciona acceso a los secretos a nivel de secreto, no a nivel de proyecto.

Inhabilita las opciones de configuración de containerd

Para quitar tu configuración personalizada, haz lo siguiente:

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

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

Solucionar problemas

Si quieres conocer los pasos para la solución de problemas, consulta Soluciona problemas del entorno de ejecución del contenedor.