Sincronizar secretos con secretos de Kubernetes

En este documento se describe cómo sincronizar los secretos almacenados en Secret Manager con los secretos de Kubernetes en tus clústeres de Google Kubernetes Engine (GKE).

El proceso de sincronización permite que las aplicaciones que se ejecutan en GKE accedan a los secretos de Secret Manager mediante métodos estándar de Kubernetes, como variables de entorno o montajes de volúmenes. Esto es útil para las aplicaciones que ya están diseñadas para leer secretos del objeto Secret de Kubernetes, en lugar de tener que actualizarse para acceder directamente a Secret Manager.

Recomendación: La función de sincronización de secretos es una alternativa al complemento Secret Manager, que monta los secretos como archivos en memoria directamente en tus pods. Usa el complemento Secret Manager siempre que tu aplicación lo admita, ya que es un método más seguro para acceder a los secretos de Secret Manager en GKE.

Antes de empezar

Completa los siguientes requisitos previos antes de sincronizar los secretos:

  • Enable the Secret Manager and Google Kubernetes Engine APIs.

    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 APIs

  • Instala y, a continuación, inicializa gcloud CLI. Si ya has instalado la CLI de gcloud, obtén la versión más reciente ejecutando el comando gcloud components update.

  • Asegúrate de que tienes un clúster de GKE en ejecución. Esta función requiere GKE 1.34 o una versión posterior.

  • Asegúrate de que Workload Identity Federation para GKE esté habilitado en tu clúster de GKE. Es obligatorio para la autenticación. Workload Identity Federation para GKE está habilitado de forma predeterminada en los clústeres Autopilot.

  • Asegúrate de que tienes los permisos de Gestión de Identidades y Accesos necesarios para gestionar clústeres de GKE y Secret Manager.

Habilitar la sincronización de secretos en un clúster de GKE

Habilita la función de sincronización de secretos cuando crees un clúster o actualices uno que ya tengas. Esta función está disponible en los clústeres Estándar y Autopilot.

Habilitar la sincronización de secretos en un clúster nuevo

Para crear un clúster con sincronización de secretos, usa uno de estos comandos de gcloud CLI:

Clúster estándar

Para usar Secret Manager en la línea de comandos, primero debes instalar o actualizar a la versión 378.0.0 o una posterior de la CLI de Google Cloud. En Compute Engine o GKE, debes autenticarte con el ámbito cloud-platform.

Habilita la sincronización de secretos sin rotación automática.

gcloud beta container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --workload-pool=PROJECT_ID.svc.id.goog \
    --enable-secret-sync

Habilita la sincronización de secretos con rotación automática. El intervalo predeterminado es de 2 minutos.

gcloud beta container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --workload-pool=PROJECT_ID.svc.id.goog \
    --enable-secret-sync \
    --enable-secret-sync-rotation

Habilita la sincronización de secretos con un intervalo de rotación personalizado. El intervalo mínimo es de 1 minuto.

gcloud beta container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --workload-pool=PROJECT_ID.svc.id.goog \
    --enable-secret-sync \
    --enable-secret-sync-rotation \
    --secret-sync-rotation-interval=1m

Haz los cambios siguientes:

  • CLUSTER_NAME: el nombre de tu clúster de GKE
  • CONTROL_PLANE_LOCATION: la región o zona del plano de control de tu clúster, como us-central1 o us-east1-a
  • PROJECT_ID: tu ID de proyecto Google Cloud

Clúster de Autopilot

Para usar Secret Manager en la línea de comandos, primero debes instalar o actualizar a la versión 378.0.0 o una posterior de la CLI de Google Cloud. En Compute Engine o GKE, debes autenticarte con el ámbito cloud-platform.

Habilita la sincronización de secretos sin rotación automática.

gcloud beta container clusters create-auto CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync

Habilita la sincronización de secretos con rotación automática. El intervalo predeterminado es de 2 minutos.

gcloud beta container clusters create-auto CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync \
    --enable-secret-sync-rotation

Habilita la sincronización de secretos con un intervalo de rotación personalizado. El intervalo mínimo es de 1 minuto.

gcloud beta container clusters create-auto CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync \
    --enable-secret-sync-rotation \
    --secret-sync-rotation-interval=1m

Haz los cambios siguientes:

  • CLUSTER_NAME: el nombre de tu clúster de GKE
  • CONTROL_PLANE_LOCATION: la región o zona del plano de control de tu clúster, como us-central1 o us-east1-a

Habilitar la sincronización de secretos en un clúster

Para actualizar los clústeres con la sincronización de secretos, usa uno de los siguientes comandos de gcloud CLI:

gcloud

Para usar Secret Manager en la línea de comandos, primero debes instalar o actualizar a la versión 378.0.0 o una posterior de la CLI de Google Cloud. En Compute Engine o GKE, debes autenticarte con el ámbito cloud-platform.

Habilitar la sincronización de secretos en un clúster

gcloud beta container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync

Habilitar la rotación con un intervalo personalizado

gcloud beta container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync-rotation \
    --secret-sync-rotation-interval=5m

Inhabilitar la rotación

gcloud beta container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --no-enable-secret-sync-rotation

Haz los cambios siguientes:

  • CLUSTER_NAME: el nombre de tu clúster de GKE
  • CONTROL_PLANE_LOCATION: la región o zona del plano de control de tu clúster, como us-central1 o us-east1-a

Configurar la sincronización de secretos

Para sincronizar los secretos, sigue estos pasos:

  1. Crea una cuenta de servicio de Kubernetes con el siguiente comando:

    kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
    

    Haz los cambios siguientes:

    • KSA_NAME: el nombre de tu Kubernetes ServiceAccount
    • NAMESPACE: el espacio de nombres de Kubernetes en el que quieres crear el objeto ServiceAccount.
  2. Crea una política de permiso de gestión de identidades y accesos que haga referencia a la nueva cuenta de servicio de Kubernetes y concede a la cuenta de servicio permiso para acceder al secreto:

    gcloud

    Para usar Secret Manager en la línea de comandos, primero debes instalar o actualizar a la versión 378.0.0 o una posterior de la CLI de Google Cloud. En Compute Engine o GKE, debes autenticarte con el ámbito cloud-platform.

    gcloud secrets add-iam-policy-binding SECRET_PROJECT_ID \
       --role=roles/secretmanager.secretAccessor \
       --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_IDsvc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME
    

    Haz los cambios siguientes:

    • SECRET_PROJECT_ID: el ID del proyecto en el que se almacena el secreto. Puede ser el mismo que PROJECT_ID si el secreto se almacena en el mismo proyecto que el clúster de GKE.
    • PROJECT_NUMBER: tu Google Cloud número de proyecto
    • PROJECT_ID: tu ID de proyecto Google Cloud
    • NAMESPACE: el espacio de nombres de Kubernetes
    • KSA_NAME: el nombre de tu Kubernetes ServiceAccount
  3. Crea un recurso personalizado SecretProviderClass mediante un manifiesto YAML. El recurso SecretProviderClass define los secretos específicos que se van a recuperar de Secret Manager, incluidos sus nombres y rutas de recursos. El complemento Secret Manager también usa el recurso SecretProviderClass para enumerar los secretos que se van a montar y el nombre de archivo con el que se van a montar.

    Crea un archivo spc.yaml con el siguiente contenido:

    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: SECRET_PROVIDER_CLASS_NAME
      namespace: NAMESPACE
    spec:
      provider: gke
      parameters:
        secrets: |
          -   resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION"
              path: "FILENAME.txt"
          -   resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION"
              path: "FILENAME1.txt"
    

    Haz los cambios siguientes:

    • SECRET_PROVIDER_CLASS_NAME: el nombre del objeto SecretProviderClass.
    • NAMESPACE: el espacio de nombres de Kubernetes en el que vas a crear este recurso.
    • resourceName: identificador de recurso completo del secreto en Secret Manager. Debe incluir el ID del proyecto, el nombre del secreto y la versión con el siguiente formato: projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION.
      • SECRET_PROJECT_ID: el ID del Google Cloud proyecto en el que se almacena el secreto. Puede ser el mismo que el de PROJECT_ID si el secreto se almacena en el mismo proyecto que el clúster de GKE.
      • SECRET_NAME: el nombre del secreto.
      • SECRET_VERSION: la versión del secreto. La versión del secreto debe estar en la misma región que el clúster.
    • path: el nombre de archivo local o el alias con el que se expondrá el valor del secreto en el entorno de Kubernetes. Es el identificador único que vincula una versión específica de Secret Manager con la representación local que usa el clúster. Cuando el secreto se sincroniza con un secreto de Kubernetes mediante el recurso SecretSync, el campo sourcePath hace referencia a esta ruta para localizar el valor del secreto que se va a sincronizar. Puedes asignar varios secretos (definidos por resourceName) a diferentes nombres de ruta en la misma SecretProviderClass.
  4. Para aplicar el manifiesto, ejecuta el siguiente comando:

    kubectl apply -f spc.yaml
    
  5. Crea un recurso personalizado SecretSync mediante un manifiesto YAML. Este recurso indica al controlador de sincronización que cree o actualice un secreto de Kubernetes en función del contenido definido en SecretProviderClass.

    Crea un archivo secret-sync.yaml con el siguiente contenido:

    apiVersion: secret-sync.gke.io/v1
    kind: SecretSync
    metadata:
      name: KUBERNETES_SECRET_NAME
      namespace: NAMESPACE
    spec:
      serviceAccountName: KSA_NAME
      secretProviderClassName: SECRET_PROVIDER_CLASS_NAME
      secretObject:
        type: KUBERNETES_SECRET_TYPE
        data:
          -   sourcePath: "FILENAME.txt"
              targetKey: "TARGET_KEY1"
          -   sourcePath: "FILENAME1.txt"
              targetKey: "TARGET_KEY2"
    

    Haz los cambios siguientes:

    • KUBERNETES_SECRET_NAME: el nombre que quieras asignar al nuevo secreto de Kubernetes que creará el recurso SecretSync.
    • NAMESPACE: el espacio de nombres de Kubernetes en el que se crea el nuevo recurso. Debe ser el mismo espacio de nombres que SecretProviderClass.
    • KSA_NAME: el nombre de la cuenta de servicio de Kubernetes que usa el controlador SecretSync para crear y actualizar el secreto de Kubernetes de destino. Esta cuenta de servicio debe tener los permisos necesarios para acceder a los secretos externos de Secret Manager.
    • SECRET_PROVIDER_CLASS_NAME: el nombre del objeto SecretProviderClass que has creado en el paso anterior. El recurso SecretSync usa esto para encontrar la configuración correcta de los secretos.
    • KUBERNETES_SECRET_TYPE: el tipo de secreto de Kubernetes que se va a crear, como Opaque, tls o docker-registry. Determina cómo gestiona Kubernetes los datos del secreto.
    • sourcePath: el nombre de archivo local o el alias (el valor del campo path en SecretProviderClass) que identifica los datos secretos que se van a recuperar. El controlador SecretSync usa este sourcePath para solicitar el contenido de un secreto específico y convertirlo en un nuevo secreto de Kubernetes.
    • targetKey: la clave que se usará en la sección data del nuevo secreto de Kubernetes que se está creando. Define cómo se denomina y se almacena el contenido secreto obtenido mediante sourcePath en el objeto Secret de Kubernetes final. Si usas varias entradas en la matriz de datos, puedes definir varios pares clave-valor en el mismo secreto de destino.
  6. Para aplicar el manifiesto, ejecuta el siguiente comando:

    kubectl apply -f secret-sync.yaml
    

    El controlador de sincronización crea un secreto de Kubernetes en el espacio de nombres especificado. Este secreto contiene los datos asignados desde Secret Manager.

  7. Comprueba que se haya creado el secreto de Kubernetes:

    kubectl get secret KUBERNETES_SECRET_NAME -n NAMESPACE -o yaml
    

    Haz los cambios siguientes:

    • KUBERNETES_SECRET_NAME: el nombre del nuevo secreto de Kubernetes
    • NAMESPACE: el espacio de nombres de Kubernetes donde se crea el nuevo secreto
  8. Para solucionar un problema de sincronización, usa el siguiente comando:

    kubectl describe secretSync KUBERNETES_SECRET_NAME -n NAMESPACE
    

    Haz los cambios siguientes:

    • KUBERNETES_SECRET_NAME: el nombre del nuevo secreto de Kubernetes
    • NAMESPACE: el espacio de nombres de Kubernetes en el que debe estar el nuevo secreto

Gestionar la rotación de secretos

Si habilitas la marca --enable-secret-sync-rotation en tu clúster, el controlador de sincronización comprobará periódicamente Secret Manager para ver si hay nuevas versiones de los secretos especificados en el recurso SecretProviderClass. La marca --secret-sync-rotation-interval determina con qué frecuencia comprueba el controlador si hay actualizaciones.

Si el controlador detecta una nueva versión de secreto en Secret Manager, el controlador actualiza el secreto de Kubernetes correspondiente. El controlador compara los hashes del contenido del secreto para actualizar los secretos solo cuando se producen cambios.

Las aplicaciones que usen estos secretos deben detectar y volver a cargar los valores de secreto actualizados del secreto de Kubernetes. El diseño de la aplicación determina cómo se gestiona.

Inhabilitar la sincronización de secretos

Para inhabilitar la sincronización de secretos, ejecuta el siguiente comando de gcloud CLI:

gcloud

Para usar Secret Manager en la línea de comandos, primero debes instalar o actualizar a la versión 378.0.0 o una posterior de la CLI de Google Cloud. En Compute Engine o GKE, debes autenticarte con el ámbito cloud-platform.

gcloud beta container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --no-enable-secret-sync

Haz los cambios siguientes:

  • CLUSTER_NAME: el nombre de tu clúster de GKE
  • CONTROL_PLANE_LOCATION: la región o zona del plano de control de tu clúster, como us-central1 o us-east1-a

Este comando detiene el controlador de sincronización. No se eliminarán los secretos de Kubernetes que ya se hayan creado. Debes eliminar manualmente los secretos de Kubernetes sincronizados si ya no los necesitas.

Eliminar secretos sincronizados

Para eliminar un secreto de Kubernetes sincronizado, elimina el recurso SecretSync con el siguiente comando:

    kubectl delete secretsync KUBERNETES_SECRET_NAME --namespace NAMESPACE

Haz los cambios siguientes:

  • KUBERNETES_SECRET_NAME: el nombre del secreto de Kubernetes
  • NAMESPACE: el espacio de nombres de Kubernetes en el que se encuentra el secreto

Migrar desde el controlador de CSI de Secrets Store

Si vas a migrar desde tu instalación del controlador CSI de Secrets Store, sigue estos pasos:

  1. Actualiza el campo provider de tu SecretProviderClass de gcp a gke. En el siguiente ejemplo se muestra cómo actualizar el campo provider:

    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: app-secrets-gke
    spec:
      provider: gke
      parameters:
        secrets: |
          -   resourceName: "projects/87654321/secrets/api-key-secret/versions/2"
              path: "good1.txt"
    
  2. Crea un recurso SecretSync. Usa la siguiente configuración de ejemplo:

    apiVersion: secret-sync.gke.io/v1
    kind: SecretSync
    metadata:
      name: my-kube-secret
      namespace: NAMESPACE
    spec:
      serviceAccountName: KSA_NAME
      secretProviderClassName: my-app-secrets
      secretObject:
        type: Opaque # Or other Kubernetes Secret types
        data:
          -   sourcePath: "my-secret.txt"
              targetKey: "USERNAME"
          -   sourcePath: "another-secret.txt"
              targetKey: "PASSWORD"
    

Cuestiones sobre seguridad

Secret Manager ofrece funciones de seguridad como control de acceso con gestión de identidades y accesos, claves de encriptado gestionadas por el cliente (CMEK) y registros de auditoría. Los secretos se cifran en reposo y en tránsito en Secret Manager. Cuando sincronizas secretos con secretos de Kubernetes, su seguridad en el clúster depende de la configuración de tu clúster de GKE. Ten en cuenta lo siguiente:

  • Almacenamiento: los secretos de Kubernetes se almacenan en etcd, que es el almacén de datos principal de GKE. De forma predeterminada, GKE encripta los datos en reposo. Para mejorar la seguridad, encripta los secretos de Kubernetes en la capa de la aplicación mediante una clave que gestionas en Cloud Key Management Service(Cloud KMS). El cifrado de secretos proporciona una capa adicional de seguridad para las cargas de trabajo sensibles.

  • Control de acceso: GKE admite varias opciones para gestionar el acceso a los recursos de los proyectos y sus clústeres mediante el control de acceso basado en roles (RBAC). Los permisos de control de acceso basado en roles demasiado amplios pueden exponer secretos a cargas de trabajo o usuarios no deseados. Concede acceso siguiendo el principio de mínimos accesos y audita periódicamente el acceso tanto a Secret Manager como a los secretos de Kubernetes.

  • Variables de entorno: para mejorar la seguridad, monta los secretos de Kubernetes como volúmenes en lugar de usarlos como variables de entorno. De este modo, se reduce el riesgo de que se registren datos por accidente o de que se expongan a otros procesos.

Siguientes pasos