Sincronize segredos com segredos do Kubernetes

Este documento descreve como sincronizar segredos armazenados no Secret Manager com segredos do Kubernetes nos seus clusters do Google Kubernetes Engine (GKE).

O processo de sincronização permite que as aplicações em execução no GKE acedam a segredos do Secret Manager através de métodos Kubernetes padrão, como variáveis de ambiente ou montagens de volumes. Isto é útil para aplicações que já foram concebidas para ler secrets do objeto Secret do Kubernetes, em vez de terem de ser atualizadas para aceder diretamente ao Secret Manager.

Recomendação: a funcionalidade de sincronização de segredos é uma alternativa ao suplemento Secret Manager, que monta segredos como ficheiros na memória diretamente nos seus pods. Use o suplemento do Secret Manager sempre que a sua aplicação o suportar, porque é um método mais seguro para aceder a segredos do Secret Manager no GKE.

Antes de começar

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

  • 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, de seguida, inicialize a CLI gcloud. Se instalou anteriormente a CLI gcloud, execute o comando gcloud components update para obter a versão mais recente.

  • Certifique-se de que tem um cluster do GKE em execução. Esta funcionalidade requer a versão 1.34 e posteriores do GKE.

  • Certifique-se de que a federação de identidade da força de trabalho para o GKE está ativada no seu cluster do GKE. Isto é necessário para a autenticação. A Workload Identity Federation para o GKE está ativada por predefinição num cluster do Autopilot.

  • Certifique-se de que tem as autorizações da gestão de identidade e de acesso necessárias para gerir clusters do GKE e o Secret Manager.

Ative a sincronização de segredos num cluster do GKE

Ative a funcionalidade de sincronização secreta quando criar um novo cluster ou atualizar um cluster existente. Esta funcionalidade está disponível em clusters padrão e do Autopilot.

Ative a sincronização de segredos num novo cluster

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

Cluster padrão

Para usar o Secret Manager na linha de comandos, primeiro instale ou atualize para a versão 378.0.0 ou superior da CLI Google Cloud. No Compute Engine ou no GKE, tem de fazer a autenticação com o âmbito cloud-platform.

Ative a sincronização de segredos 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

Ativar a sincronização de segredos com rotação automática. O intervalo predefinido é 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

Ative a sincronização de segredos 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 o seguinte:

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

Cluster do Autopilot

Para usar o Secret Manager na linha de comandos, primeiro instale ou atualize para a versão 378.0.0 ou superior da CLI Google Cloud. No Compute Engine ou no GKE, tem de fazer a autenticação com o âmbito cloud-platform.

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

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

Ativar a sincronização de segredos com rotação automática. O intervalo predefinido é de 2 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 segredos 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 o seguinte:

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

Ative a sincronização de segredos num cluster existente

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

gcloud

Para usar o Secret Manager na linha de comandos, primeiro instale ou atualize para a versão 378.0.0 ou superior da CLI Google Cloud. No Compute Engine ou no GKE, tem de fazer a autenticação com o âmbito cloud-platform.

Ative a sincronização de segredos num cluster existente

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

Ative 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

Desative a rotação

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

Substitua o seguinte:

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

Configure a sincronização de segredos

Para sincronizar segredos, conclua os seguintes passos:

  1. Crie uma Kubernetes ServiceAccount com o seguinte comando:

    kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
    

    Substitua o seguinte:

    • KSA_NAME: o nome da sua ServiceAccount do Kubernetes
    • NAMESPACE: o namespace do Kubernetes onde quer criar a ServiceAccount
  2. Crie uma política de autorização da IAM que faça referência à nova conta de serviço do Kubernetes e conceda autorização à conta de serviço para aceder ao segredo:

    gcloud

    Para usar o Secret Manager na linha de comandos, primeiro instale ou atualize para a versão 378.0.0 ou superior da CLI Google Cloud. No Compute Engine ou no GKE, tem de fazer a autenticação com o â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
    

    Substitua o seguinte:

    • SECRET_PROJECT_ID: o ID do projeto onde o segredo está armazenado. Pode ser igual ao PROJECT_ID se o segredo estiver armazenado no mesmo projeto que o cluster do GKE.
    • PROJECT_NUMBER: o número do seu Google Cloud projeto
    • PROJECT_ID: o ID do seu Google Cloud projeto
    • NAMESPACE: o namespace do Kubernetes
    • KSA_NAME: o nome da sua ServiceAccount do Kubernetes
  3. Crie um recurso personalizado SecretProviderClass com um manifesto YAML. O recurso SecretProviderClass define os segredos específicos a obter do Secret Manager, incluindo os respetivos nomes de recursos e caminhos. O suplemento Secret Manager também usa o recurso SecretProviderClass para listar os segredos a montar e o nome do ficheiro como os montar.

    Crie um ficheiro 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 o seguinte:

    • SECRET_PROVIDER_CLASS_NAME: o nome do seu objeto SecretProviderClass.
    • NAMESPACE: o namespace do Kubernetes onde está a criar este recurso.
    • resourceName: o identificador de recurso completo do segredo no Secret Manager. Tem de incluir o ID do projeto, o nome do segredo e a versão no seguinte formato: projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION.
      • SECRET_PROJECT_ID: o ID do Google Cloud projeto onde o segredo está armazenado. Pode ser igual a PROJECT_ID se o segredo estiver armazenado no mesmo projeto que o cluster do GKE.
      • SECRET_NAME: o nome do segredo.
      • SECRET_VERSION: a versão do secret. A versão do Secret tem de estar na mesma região que o cluster.
    • path: o nome do ficheiro local ou o alias através do qual o valor do segredo vai ser exposto no ambiente do Kubernetes. É o identificador exclusivo que associa uma versão específica do Secret Manager à representação local usada pelo cluster. Quando o segredo é sincronizado com um segredo do Kubernetes através do recurso SecretSync, este caminho é referenciado pelo campo sourcePath para localizar o valor secreto para sincronização. Pode mapear vários segredos (definidos por resourceName) para diferentes nomes de caminhos na mesma SecretProviderClass.
  4. Para aplicar o manifesto, execute o seguinte comando:

    kubectl apply -f spc.yaml
    
  5. Crie um recurso personalizado SecretSync com um manifesto YAML. Este recurso indica ao controlador de sincronização que crie ou atualize um Kubernetes Secret com base nos conteúdos definidos na SecretProviderClass.

    Crie um ficheiro 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 o seguinte:

    • KUBERNETES_SECRET_NAME: o nome que quer dar ao novo segredo do Kubernetes que vai ser criado pelo recurso SecretSync.
    • NAMESPACE: o namespace do Kubernetes onde o novo recurso é criado. Tem de ser o mesmo espaço de nomes que o SecretProviderClass.
    • KSA_NAME: o nome da ServiceAccount do Kubernetes que o controlador SecretSync usa para criar e atualizar o segredo do Kubernetes de destino. Esta ServiceAccount tem de ter as autorizações necessárias para aceder a segredos externos do Secret Manager.
    • SECRET_PROVIDER_CLASS_NAME: o nome do objeto SecretProviderClass que criou no passo anterior. O recurso SecretSync usa isto para encontrar a configuração correta para os segredos.
    • KUBERNETES_SECRET_TYPE: o tipo de secret do Kubernetes a criar, como Opaque, tls ou docker-registry. Isto determina como o Kubernetes processa os dados do segredo.
    • sourcePath: o nome do ficheiro local ou o alias (o valor do campo path em SecretProviderClass) que identifica os dados secretos a obter. O controlador SecretSync usa este sourcePath para pedir o conteúdo secreto específico e convertê-lo num novo segredo do Kubernetes.
    • targetKey: a chave que vai ser usada na secção data do novo segredo do Kubernetes que está a ser criado. Isto define como o conteúdo secreto obtido através do sourcePath é denominado e armazenado no objeto Kubernetes Secret final. A utilização de várias entradas na matriz de dados permite-lhe definir vários pares de chave-valor no mesmo segredo de destino.
  6. Para aplicar o manifesto, execute o seguinte comando:

    kubectl apply -f secret-sync.yaml
    

    O controlador de sincronização cria um segredo do Kubernetes no espaço de nomes especificado. Este segredo contém os dados mapeados a partir do Secret Manager.

  7. Verifique se o Kubernetes Secret foi criado:

    kubectl get secret KUBERNETES_SECRET_NAME -n NAMESPACE -o yaml
    

    Substitua o seguinte:

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

    kubectl describe secretSync KUBERNETES_SECRET_NAME -n NAMESPACE
    

    Substitua o seguinte:

    • KUBERNETES_SECRET_NAME: o nome do novo segredo do Kubernetes
    • NAMESPACE: o namespace do Kubernetes onde o novo segredo deve existir

Faça a gestão da rotação de segredos

Se ativar a flag --enable-secret-sync-rotation no cluster, o controlador de sincronização verifica periodicamente o Secret Manager para ver se existem novas versões dos segredos especificados no recurso SecretProviderClass. A flag --secret-sync-rotation-interval determina a frequência com que o controlador verifica a existência de atualizações.

Se o controlador detetar uma nova versão secreta no Secret Manager, o controlador atualiza o segredo do Kubernetes correspondente. O controlador compara hashes do conteúdo do segredo para atualizar os segredos apenas quando ocorrem alterações.

As aplicações que usam estes segredos têm de detetar e recarregar os valores dos segredos atualizados do segredo do Kubernetes. O design da aplicação determina como isto é processado.

Desative a sincronização de segredos

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

gcloud

Para usar o Secret Manager na linha de comandos, primeiro instale ou atualize para a versão 378.0.0 ou superior da CLI Google Cloud. No Compute Engine ou no GKE, tem de fazer a autenticação com o âmbito cloud-platform.

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

Substitua o seguinte:

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

Este comando para o controlador de sincronização. Não elimina segredos do Kubernetes que já tenham sido criados. Tem de eliminar manualmente todos os segredos do Kubernetes sincronizados se já não precisar deles.

Elimine segredos sincronizados

Para eliminar um segredo do Kubernetes sincronizado, elimine o recurso SecretSync através do seguinte comando:

    kubectl delete secretsync KUBERNETES_SECRET_NAME --namespace NAMESPACE

Substitua o seguinte:

  • KUBERNETES_SECRET_NAME: o nome do segredo do Kubernetes
  • NAMESPACE: o namespace do Kubernetes onde o segredo existe

Migre a partir do controlador CSI da Secrets Store existente

Se estiver a migrar da sua instalação existente do Secrets Store CSI Driver, siga estes passos:

  1. Atualize o campo provider na SecretProviderClass de gcp para gke. O exemplo seguinte 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 exemplo:

    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 de segurança

O Secret Manager oferece funcionalidades de segurança, como: controlo de acesso com a IAM, chaves de encriptação geridas pelo cliente (CMEK) e registo de auditoria. Os Secrets são encriptados em repouso e em trânsito no Secret Manager. Quando sincroniza segredos com segredos do Kubernetes, a respetiva segurança no cluster depende da configuração do cluster do GKE. Considere o seguinte:

  • Armazenamento: os segredos do Kubernetes são armazenados no etcd, que é o principal armazenamento de dados do GKE. Por predefinição, o GKE encripta os dados em repouso. Para uma segurança melhorada, encripte segredos do Kubernetes na camada de aplicação através da utilização de uma chave que gere no Cloud Key Management Service(Cloud KMS). A encriptação de segredos oferece uma camada adicional de segurança para cargas de trabalho confidenciais.

  • Controlo de acesso: o GKE suporta várias opções para gerir o acesso a recursos em projetos e respetivos clusters através do controlo de acesso baseado em funções (CABF). As autorizações RBAC excessivamente amplas podem expor segredos a cargas de trabalho ou utilizadores não intencionais. Conceda acesso de acordo com o princípio do menor privilégio e audite regularmente o acesso ao Gestor Secreto e aos segredos do Kubernetes.

  • Variáveis de ambiente: para melhorar a segurança, monte segredos do Kubernetes como volumes em vez de os usar como variáveis de ambiente. Isto reduz o risco de registo acidental ou exposição a outros processos.

O que se segue?