Sincronizar secrets com secrets do Kubernetes

Neste documento, descrevemos como sincronizar secrets armazenados no Secret Manager com secrets do Kubernetes nos clusters do Google Kubernetes Engine (GKE).

O processo de sincronização permite que aplicativos em execução no GKE acessem secrets do Secret Manager usando métodos padrão do Kubernetes, como variáveis de ambiente ou montagens de volume. Isso é útil para aplicativos já projetados para ler secrets do objeto Secret do Kubernetes, em vez de precisar ser atualizado para acessar diretamente o Secret Manager.

Recomendação: o recurso de sincronização de secrets é uma alternativa ao complemento do Secret Manager, que monta secrets como arquivos na memória diretamente nos seus pods. Use o complemento do Secret Manager sempre que seu aplicativo for compatível, porque é um método mais seguro de acessar secrets do Secret Manager no GKE.

Antes de começar

Conclua os seguintes pré-requisitos antes de sincronizar os secrets:

  • 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

  • Instale e inicialize a CLI gcloud. Se você já instalou a CLI gcloud, instale a versão mais recente executando o comando gcloud components update.

  • Verifique se você tem um cluster do GKE em execução. Esse recurso requer a versão 1.34 ou mais recente do GKE.

  • Verifique se a federação de identidade da carga de trabalho para GKE está ativada no cluster do GKE. Isso é necessário para a autenticação. A federação de identidade da carga de trabalho para o GKE é ativada por padrão em um cluster do Autopilot.

  • Verifique se você tem as permissões necessárias do Identity and Access Management para gerenciar clusters do GKE e o Secret Manager.

Ativar a sincronização de secrets em um cluster do GKE

Ative o recurso de sincronização de secrets ao criar ou atualizar um cluster. Esse recurso está disponível nos clusters Standard e Autopilot.

Ativar a sincronização de secrets em um novo cluster

Para criar um cluster com sincronização de secrets, use um destes comandos da CLI gcloud:

Cluster padrão

Para usar o Secret Manager na linha de comando, primeiro instale ou faça upgrade para a versão 378.0.0 ou mais recente da Google Cloud CLI. No Compute Engine ou no GKE, você precisa fazer a autenticação com o escopo do cloud-platform.

Ative a sincronização de secrets sem rotação automática.

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

Ative a sincronização de chaves secretas com rotação automática. O intervalo padrão é de dois 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

Ative a sincronização de secrets com um intervalo de rotação personalizado. O intervalo mínimo é 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

Substitua:

  • CLUSTER_NAME: o nome do cluster do GKE
  • CONTROL_PLANE_LOCATION: a região ou zona do plano de controle do cluster, como us-central1 ou us-east1-a.
  • PROJECT_ID: o ID do projeto Google Cloud

Cluster do Autopilot

Para usar o Secret Manager na linha de comando, primeiro instale ou faça upgrade para a versão 378.0.0 ou mais recente da Google Cloud CLI. No Compute Engine ou no GKE, você precisa fazer a autenticação com o escopo do cloud-platform.

Ative a sincronização de secrets sem rotação automática.

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

Ative a sincronização de chaves secretas com rotação automática. O intervalo padrão é de dois minutos.

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

Ative a sincronização de secrets com um intervalo de rotação personalizado. O intervalo mínimo é 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

Substitua:

  • CLUSTER_NAME: o nome do cluster do GKE
  • CONTROL_PLANE_LOCATION: a região ou zona do plano de controle do cluster, como us-central1 ou us-east1-a.

Ativar a sincronização de secrets em um cluster atual

Para atualizar os clusters atuais com a sincronização de secrets, use um dos seguintes comandos da CLI gcloud:

gcloud

Para usar o Secret Manager na linha de comando, primeiro instale ou faça upgrade para a versão 378.0.0 ou mais recente da Google Cloud CLI. No Compute Engine ou no GKE, você precisa fazer a autenticação com o escopo do cloud-platform.

Ativar a sincronização de secrets em um cluster atual

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

Ativar a rotação com um intervalo personalizado

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

Desativar rotação

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

Substitua:

  • CLUSTER_NAME: o nome do cluster do GKE
  • CONTROL_PLANE_LOCATION: a região ou zona do plano de controle do cluster, como us-central1 ou us-east1-a.

Configurar a sincronização de secrets

Para sincronizar segredos, siga estas etapas:

  1. Crie uma conta de serviço do Kubernetes usando o seguinte comando:

    kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
    

    Substitua:

    • KSA_NAME: o nome da sua ServiceAccount do Kubernetes
    • NAMESPACE: o namespace do Kubernetes em que você quer criar a ServiceAccount.
  2. Crie uma política de permissão do IAM que faça referência à nova ServiceAccount do Kubernetes e conceda a ela permissão para acessar o secret:

    gcloud

    Para usar o Secret Manager na linha de comando, primeiro instale ou faça upgrade para a versão 378.0.0 ou mais recente da Google Cloud CLI. No Compute Engine ou no GKE, você precisa fazer a autenticação com o escopo do 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
    

    Substitua:

    • SECRET_PROJECT_ID: o ID do projeto em que o secret está armazenado. Pode ser o mesmo que PROJECT_ID se o secret estiver armazenado no mesmo projeto que o cluster do GKE.
    • PROJECT_NUMBER: o número do seu projeto Google Cloud
    • PROJECT_ID: o ID do projeto Google Cloud
    • NAMESPACE: o namespace do Kubernetes
    • KSA_NAME: o nome da sua ServiceAccount do Kubernetes
  3. Crie um recurso personalizado SecretProviderClass usando um manifesto YAML. O recurso SecretProviderClass define os segredos específicos a serem recuperados do Secret Manager, incluindo os nomes e caminhos dos recursos. O complemento do Secret Manager também usa o recurso SecretProviderClass para listar os secrets a serem montados e o nome do arquivo em que serão montados.

    Crie um arquivo spc.yaml com o seguinte conteúdo:

    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"
    

    Substitua:

    • SECRET_PROVIDER_CLASS_NAME: o nome do objeto SecretProviderClass.
    • NAMESPACE: o namespace do Kubernetes em que você está criando esse recurso.
    • resourceName: o identificador completo do recurso para o secret no Secret Manager. Isso precisa incluir o ID do projeto, o nome do secret e a versão no formato: projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION.
      • SECRET_PROJECT_ID: o ID do Google Cloud projeto em que o secret está armazenado. Pode ser o mesmo que o PROJECT_ID se o secret estiver armazenado no mesmo projeto que o cluster do GKE.
      • SECRET_NAME: o nome do secret.
      • SECRET_VERSION: a versão do secret. A versão do secret precisa estar na mesma região que o cluster.
    • path: o nome do arquivo local ou alias em que o valor secreto será exposto no ambiente do Kubernetes. É o identificador exclusivo que vincula uma versão específica do Secret Manager à representação local usada pelo cluster. Quando o secret é sincronizado com um secret do Kubernetes usando o recurso SecretSync, esse caminho é referenciado pelo campo sourcePath para localizar o valor do secret para sincronização. É possível mapear vários secrets (definidos por resourceName) para diferentes nomes de caminho na mesma SecretProviderClass.
  4. Para aplicar o manifesto, execute o seguinte comando:

    kubectl apply -f spc.yaml
    
  5. Crie um recurso personalizado SecretSync usando um manifesto YAML. Esse recurso instrui o controlador de sincronização a criar ou atualizar um secret do Kubernetes com base no conteúdo definido na SecretProviderClass.

    Crie um arquivo secret-sync.yaml com o seguinte conteúdo:

    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"
    

    Substitua:

    • KUBERNETES_SECRET_NAME: o nome que você quer dar ao novo secret do Kubernetes que será criado pelo recurso SecretSync.
    • NAMESPACE: o namespace do Kubernetes em que o novo recurso é criado. Ele precisa estar no mesmo namespace que a SecretProviderClass.
    • KSA_NAME: o nome da ServiceAccount do Kubernetes que o controlador SecretSync usa para criar e atualizar o secret de destino do Kubernetes. Essa ServiceAccount precisa ter as permissões necessárias para acessar secrets externos do Secret Manager.
    • SECRET_PROVIDER_CLASS_NAME: o nome do objeto SecretProviderClass que você criou na etapa anterior. O recurso SecretSync usa isso para encontrar a configuração correta dos secrets.
    • KUBERNETES_SECRET_TYPE: o tipo de secret do Kubernetes a ser criado, como Opaque, tls ou docker-registry. Isso determina como o Kubernetes processa os dados do secret.
    • sourcePath: o nome do arquivo ou alias local (o valor do campo path em SecretProviderClass) que identifica os dados secretos a serem recuperados. O controlador SecretSync usa esse sourcePath para solicitar o conteúdo específico do secret e convertê-lo em um novo secret do Kubernetes.
    • targetKey: a chave que será usada na seção data do novo secret do Kubernetes que está sendo criado. Isso define como o conteúdo do secret recuperado usando o sourcePath é nomeado e armazenado no objeto final do secret do Kubernetes. Usar várias entradas na matriz de dados permite definir vários pares de chave-valor no mesmo secret de destino.
  6. Para aplicar o manifesto, execute o seguinte comando:

    kubectl apply -f secret-sync.yaml
    

    O controlador de sincronização cria um secret do Kubernetes no namespace especificado. Esse secret contém os dados mapeados do Secret Manager.

  7. Verifique se o Secret do Kubernetes foi criado:

    kubectl get secret KUBERNETES_SECRET_NAME -n NAMESPACE -o yaml
    

    Substitua:

    • KUBERNETES_SECRET_NAME: o nome do novo secret do Kubernetes
    • NAMESPACE: o namespace do Kubernetes em que o novo Secret é criado
  8. Para resolver um problema de sincronização, use o seguinte comando:

    kubectl describe secretSync KUBERNETES_SECRET_NAME -n NAMESPACE
    

    Substitua:

    • KUBERNETES_SECRET_NAME: o nome do novo secret do Kubernetes
    • NAMESPACE: o namespace do Kubernetes em que o novo Secret vai existir.

Gerenciar a rotação de secrets

Se você ativar a flag --enable-secret-sync-rotation no cluster, o controlador de sincronização vai verificar periodicamente o Secret Manager em busca de novas versões dos secrets especificados no recurso SecretProviderClass. A flag --secret-sync-rotation-interval determina a frequência com que o controlador verifica se há atualizações.

Se o controlador detectar uma nova versão do secret no Secret Manager, ele vai atualizar o secret correspondente do Kubernetes. O controlador compara hashes do conteúdo do secret para atualizar os secrets somente quando ocorrem mudanças.

Os aplicativos que usam esses secrets precisam detectar e recarregar os valores atualizados do secret do Kubernetes. O design do aplicativo determina como isso é processado.

Desativar a sincronização de secrets

Para desativar a sincronização de secrets, execute o seguinte comando da CLI gcloud:

gcloud

Para usar o Secret Manager na linha de comando, primeiro instale ou faça upgrade para a versão 378.0.0 ou mais recente da Google Cloud CLI. No Compute Engine ou no GKE, você precisa fazer a autenticação com o escopo do cloud-platform.

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

Substitua:

  • CLUSTER_NAME: o nome do cluster do GKE
  • CONTROL_PLANE_LOCATION: a região ou zona do plano de controle do cluster, como us-central1 ou us-east1-a.

Esse comando interrompe o controlador de sincronização. Ela não exclui nenhum Secret do Kubernetes que já tenha sido criado. É necessário excluir manualmente os Secrets do Kubernetes sincronizados que não são mais necessários.

Excluir secrets sincronizados

Para excluir um Secret do Kubernetes sincronizado, exclua o recurso SecretSync usando o seguinte comando:

    kubectl delete secretsync KUBERNETES_SECRET_NAME --namespace NAMESPACE

Substitua:

  • KUBERNETES_SECRET_NAME: o nome do secret do Kubernetes
  • NAMESPACE: o namespace do Kubernetes em que o Secret existe

Migrar do driver CSI do Secrets Store atual

Se você estiver migrando da instalação atual do driver CSI do Secrets Store, siga estas etapas:

  1. Atualize o campo provider na SecretProviderClass de gcp para gke. O exemplo a seguir mostra como atualizar o 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. Crie um recurso SecretSync. Use a seguinte configuração de amostra:

    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"
    

Considerações sobre segurança

O Secret Manager oferece recursos de segurança como controle de acesso com o IAM, chaves de criptografia gerenciadas pelo cliente (CMEK) e registro de auditoria. Os secrets são criptografados em repouso e em trânsito no Secret Manager. Quando você sincroniza secrets com secrets do Kubernetes, a segurança deles no cluster depende da configuração do cluster do GKE. Considere o seguinte:

  • Armazenamento: os secrets do Kubernetes são armazenados no etcd, que é o principal repositório de dados do GKE. Por padrão, o GKE criptografa dados em repouso. Para aumentar a segurança, criptografe os secrets do Kubernetes na camada do aplicativo usando uma chave que você gerencia no Cloud Key Management Service(Cloud KMS). A criptografia de secrets oferece uma camada extra de segurança para cargas de trabalho sensíveis.

  • Controle de acesso: o GKE oferece suporte a várias opções para gerenciar o acesso a recursos em projetos e clusters usando controle de acesso baseado em papéis (RBAC). Permissões de RBAC muito amplas podem expor segredos a cargas de trabalho ou usuários não intencionais. Conceda acesso seguindo o princípio de privilégio mínimo e audite regularmente o acesso ao Secret Manager e aos segredos do Kubernetes.

  • Variáveis de ambiente: para melhorar a segurança, ative secrets do Kubernetes como volumes em vez de usá-los como variáveis de ambiente. Isso reduz o risco de registro acidental ou exposição a outros processos.

A seguir