Sincroniza secretos con Secrets de Kubernetes

En este documento, se describe cómo sincronizar los secretos almacenados en Secret Manager con los secretos de Kubernetes dentro de 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 con métodos estándar de Kubernetes, como variables de entorno o activaciones 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 de Secret Manager, que activa los secretos como archivos en la memoria directamente en tus Pods. Usa el complemento de 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 comenzar

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, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta el comando gcloud components update para obtener la versión más reciente.

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

  • Asegúrate de que Workload Identity Federation for GKE esté habilitada en tu clúster de GKE. Esto es necesario para la autenticación. Workload Identity Federation for GKE está habilitada de forma predeterminada en un clúster de Autopilot.

  • Asegúrate de tener los permisos necesarios de Identity and Access Management para administrar clústeres de GKE y Secret Manager.

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

Habilita la función de sincronización de Secrets cuando crees un clúster nuevo o actualices uno existente. Esta función está disponible en los clústeres de Standard y Autopilot.

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

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

Clúster estándar

Para usar Secret Manager en la línea de comandos, primero instala o actualiza a la versión 378.0.0 o posterior de Google Cloud CLI. En Compute Engine o GKE, debes autenticarte con el permiso 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

Reemplaza lo siguiente:

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

Clúster de Autopilot

Para usar Secret Manager en la línea de comandos, primero instala o actualiza a la versión 378.0.0 o posterior de Google Cloud CLI. En Compute Engine o GKE, debes autenticarte con el permiso 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

Reemplaza lo siguiente:

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

Habilita la sincronización de secretos en un clúster existente

Para actualizar los clústeres existentes 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 instala o actualiza a la versión 378.0.0 o posterior de Google Cloud CLI. En Compute Engine o GKE, debes autenticarte con el permiso cloud-platform.

Habilita la sincronización de secretos en un clúster existente

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

Cómo 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

Inhabilita la rotación

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

Reemplaza lo siguiente:

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

Configura la sincronización de secretos

Para sincronizar secretos, completa los siguientes pasos:

  1. Crea una ServiceAccount de Kubernetes con el siguiente comando:

    kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
    

    Reemplaza lo siguiente:

    • KSA_NAME: Es el nombre de tu ServiceAccount de Kubernetes.
    • NAMESPACE: Es el espacio de nombres de Kubernetes en el que deseas crear la ServiceAccount.
  2. Crea una política de permisos de IAM que haga referencia a la nueva ServiceAccount de Kubernetes y otorga a la ServiceAccount permiso para acceder al secreto:

    gcloud

    Para usar Secret Manager en la línea de comandos, primero instala o actualiza a la versión 378.0.0 o posterior de Google Cloud CLI. En Compute Engine o GKE, debes autenticarte con el permiso 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
    

    Reemplaza lo siguiente:

    • SECRET_PROJECT_ID: Es 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: El número de tu proyecto de Google Cloud
    • PROJECT_ID: El ID de tu proyecto de Google Cloud
    • NAMESPACE: El espacio de nombres de Kubernetes
    • KSA_NAME: Es el nombre de tu ServiceAccount de Kubernetes.
  3. Crea un recurso personalizado SecretProviderClass con un manifiesto YAML. El recurso SecretProviderClass define los secretos específicos que se recuperarán de Secret Manager, incluidos sus nombres y rutas de recursos. El complemento de Secret Manager también usa el recurso SecretProviderClass para enumerar los secretos que se deben unir y el nombre de archivo con el que se deben unir.

    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"
    

    Reemplaza lo siguiente:

    • SECRET_PROVIDER_CLASS_NAME: Es el nombre de tu objeto SecretProviderClass.
    • NAMESPACE: Es el espacio de nombres de Kubernetes en el que crearás este recurso.
    • resourceName: Es el 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: Es el ID del Google Cloud 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.
      • SECRET_NAME: Es el nombre del secreto.
      • SECRET_VERSION: Es la versión del secreto. La versión del secreto debe estar en la misma región que el clúster.
    • path: Es el alias o nombre de archivo local 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 Secret de Kubernetes a través del recurso SecretSync, el campo sourcePath hace referencia a esta ruta de acceso para ubicar el valor del secreto que se sincronizará. Puedes asignar varios secretos (definidos por resourceName) a diferentes nombres de ruta de acceso dentro de la misma SecretProviderClass.
  4. Para aplicar el manifiesto, ejecuta el siguiente comando:

    kubectl apply -f spc.yaml
    
  5. Crea un recurso personalizado SecretSync con un manifiesto YAML. Este recurso indica al controlador de sincronización que cree o actualice un secreto de Kubernetes según el 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"
    

    Reemplaza lo siguiente:

    • KUBERNETES_SECRET_NAME: Es el nombre que deseas darle al nuevo Secret de Kubernetes que creará el recurso SecretSync.
    • NAMESPACE: Es el espacio de nombres de Kubernetes en el que se crea el recurso nuevo. Debe ser el mismo espacio de nombres que el de SecretProviderClass.
    • KSA_NAME: Es el nombre de la ServiceAccount de Kubernetes que usa el controlador de SecretSync para crear y actualizar el Secret de Kubernetes de destino. Esta ServiceAccount debe tener los permisos necesarios para acceder a los secretos externos de Secret Manager.
    • SECRET_PROVIDER_CLASS_NAME: Es el nombre del objeto SecretProviderClass que creaste en el paso anterior. El recurso SecretSync usa este campo para encontrar la configuración correcta de los secretos.
    • KUBERNETES_SECRET_TYPE: Es el tipo de Secret de Kubernetes que se creará, como Opaque, tls o docker-registry. Esto determina cómo Kubernetes controla los datos del secreto.
    • sourcePath: Es el nombre de archivo o alias local (el valor del campo path en SecretProviderClass) que identifica los datos secretos que se recuperarán. El controlador de SecretSync usa este sourcePath para solicitar el contenido secreto específico y convertirlo en un nuevo Secret de Kubernetes.
    • targetKey: Es la clave que se usará en la sección data del nuevo Secret de Kubernetes que se está creando. Define cómo se nombra y almacena el contenido secreto recuperado con sourcePath en el objeto Secret de Kubernetes final. Si usas varias entradas en el array de datos, puedes definir varios pares clave-valor dentro del mismo objeto 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 objeto Secret de Kubernetes en el espacio de nombres especificado. Este secreto contiene los datos asignados desde Secret Manager.

  7. Verifica que se haya creado el Secret de Kubernetes:

    kubectl get secret KUBERNETES_SECRET_NAME -n NAMESPACE -o yaml
    

    Reemplaza lo siguiente:

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

    kubectl describe secretSync KUBERNETES_SECRET_NAME -n NAMESPACE
    

    Reemplaza lo siguiente:

    • KUBERNETES_SECRET_NAME: Es el nombre del Secret de Kubernetes nuevo.
    • NAMESPACE: Es el espacio de nombres de Kubernetes en el que debe existir el nuevo Secret.

Administra la rotación de secretos

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

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

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

Inhabilita 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 instala o actualiza a la versión 378.0.0 o posterior de Google Cloud CLI. En Compute Engine o GKE, debes autenticarte con el permiso cloud-platform.

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

Reemplaza lo siguiente:

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

Este comando detiene el controlador de sincronización. No borra ningún Secret de Kubernetes que ya se haya creado. Debes borrar manualmente los objetos Secret de Kubernetes sincronizados si ya no los necesitas.

Borra los secretos sincronizados

Para borrar un secreto de Kubernetes sincronizado, borra el recurso SecretSync con el siguiente comando:

    kubectl delete secretsync KUBERNETES_SECRET_NAME --namespace NAMESPACE

Reemplaza lo siguiente:

  • KUBERNETES_SECRET_NAME: es el nombre del Secret de Kubernetes.
  • NAMESPACE: Es el espacio de nombres de Kubernetes en el que existe el Secret.

Migra desde el controlador de CSI de Secrets Store existente

Si migras desde tu instalación existente del controlador de CSI de Secrets Store, sigue estos pasos:

  1. Actualiza el campo provider en 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 muestra:

    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"
    

Consideraciones de seguridad

Secret Manager ofrece funciones de seguridad como control de acceso con IAM, claves de encriptación administradas por el cliente (CMEK) y registros de auditoría. Los secretos se encriptan en reposo y en tránsito dentro de Secret Manager. Cuando sincronizas secretos con secretos de Kubernetes, su seguridad dentro del 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 aplicación con una clave que administras en Cloud Key Management Service(Cloud KMS). La encriptación de secretos proporciona una capa adicional de seguridad para las cargas de trabajo sensibles.

  • Control de acceso: GKE admite varias opciones para administrar el acceso a los recursos dentro de los proyectos y sus clústeres a través del control de acceso basado en roles (RBAC). Los permisos de RBAC demasiado amplios pueden exponer secretos a cargas de trabajo o usuarios no deseados. Otorga acceso según el principio de privilegio mínimo y audita periódicamente el acceso a Secret Manager y a los secretos de Kubernetes.

  • Variables de entorno: Para mejorar la seguridad, activa los secretos de Kubernetes como volúmenes en lugar de usarlos como variables de entorno. Esto reduce el riesgo de registro accidental o exposición a otros procesos.

¿Qué sigue?