Neste tutorial, mostramos como armazenar os dados sensíveis usados pelos clusters do Google Kubernetes Engine (GKE) no Secret Manager. Você vai aprender a acessar os dados dos pods com mais segurança usando a federação de identidade da carga de trabalho do GKE e as bibliotecas de cliente doGoogle Cloud .
Armazenar seus dados confidenciais fora do armazenamento do cluster reduz o risco de acesso não autorizado aos dados em caso de ataque. O uso da federação de identidade da carga de trabalho para acessar os dados evita os riscos associados ao gerenciamento de chaves de contas de serviço de longa duração e permite controlar o acesso aos secrets usando o Identity and Access Management (IAM) em vez das regras do RBAC no cluster. Use qualquer provedor de armazenamento de secrets externos, como Secret Manager ou HashiCorp Vault.
Esta página é destinada a especialistas em segurança que querem mover dados sensíveis do armazenamento no cluster. Para saber mais sobre papéis comuns e exemplos de tarefas que mencionamos no conteúdo do Google Cloud , consulte Tarefas e funções de usuário comuns do GKE.
Este tutorial usa um cluster do Autopilot do GKE. Para executar as etapas usando o GKE Standard, é necessário ativar manualmente a federação de identidade da carga de trabalho para o GKE.
É possível usar a federação de identidade da carga de trabalho para o GKE para acessar qualquer Google Cloud API de cargas de trabalho do GKE sem precisar usar abordagens menos seguras, como arquivos de chave de conta de serviço estáticos. Neste tutorial, usamos o Secret Manager como exemplo, mas é possível usar as mesmas etapas para acessar outras APIs Google Cloud. Para saber mais, consulte Federação de identidade da carga de trabalho para o GKE.
Prepare o ambiente
Clone o repositório do GitHub que contém os arquivos de amostra deste tutorial:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd ~/kubernetes-engine-samples/security/wi-secrets
Criar um secret no Secret Manager
No exemplo a seguir, mostramos os dados que você usará para criar um secret:
Crie um secret para armazenar os dados de amostra:
gcloud secrets create bq-readonly-key \ --data-file=manifests/bq-readonly-key \ --ttl=3600s
Este comando faz o seguinte:
- Crie um novo secret do Secret Manager com a chave de amostra
na região
us-central1
Google Cloud . - Define o secret para expirar uma hora depois da execução do comando.
- Crie um novo secret do Secret Manager com a chave de amostra
na região
Crie o cluster e os recursos do Kubernetes
Crie um cluster do GKE, namespaces do Kubernetes e contas de serviço do Kubernetes. Crie dois namespaces, um para acesso somente leitura e outro para acesso de leitura e gravação ao secret. Crie também uma conta de serviço do Kubernetes em cada namespace para usar com a federação de identidade da carga de trabalho do GKE.
Crie um cluster do GKE Autopilot:
gcloud container clusters create-auto secret-cluster \ --location=us-central1
A implantação do cluster pode levar cerca de cinco minutos. Os clusters do Autopilot sempre têm a federação de identidade da carga de trabalho ativada do GKE. Se você quiser usar um cluster do GKE Standard, ative manualmente a federação de identidade da carga de trabalho para o GKE antes de continuar.
Crie um namespace
readonly-ns
e um namespaceadmin-ns
:kubectl create namespace readonly-ns kubectl create namespace admin-ns
Crie uma conta de serviço do Kubernetes
readonly-sa
e uma conta de serviço do Kubernetesadmin-sa
:kubectl create serviceaccount readonly-sa --namespace=readonly-ns kubectl create serviceaccount admin-sa --namespace=admin-ns
Criar políticas de permissão do IAM
Conceda à conta de serviço do
readonly-sa
acesso somente leitura para o secret:gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/readonly-ns/sa/readonly-sa \ --role='roles/secretmanager.secretAccessor' \ --condition=None
Substitua:
PROJECT_NUMBER
: o número numérico do projeto Google Cloud.PROJECT_ID
: o ID do projeto Google Cloud .
Conceda à conta de serviço do
admin-sa
acesso de leitura e gravação ao secret:gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/admin-ns/sa/admin-sa \ --role='roles/secretmanager.secretAccessor' \ --condition=None gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/admin-ns/sa/admin-sa \ --role='roles/secretmanager.secretVersionAdder' \ --condition=None
Verificar acesso do secret
Implante pods de teste em cada namespace para verificar o acesso somente leitura e gravação.
Revise o manifesto do pod somente leitura:
Esse pod usa a conta de serviço
readonly-sa
no namespacereadonly-ns
.Revise o manifesto de pod de leitura/gravação:
Esse pod usa a conta de serviço
admin-sa
no namespaceadmin-ns
.Implante os pods de teste:
kubectl apply -f manifests/admin-pod.yaml kubectl apply -f manifests/readonly-pod.yaml
Os pods podem levar alguns minutos para começar a ser executados. Para monitorar o progresso, execute o seguinte comando:
watch kubectl get pods -n readonly-ns
Quando o status do pod mudar para
RUNNING
, pressioneCtrl+C
para retornar à linha de comando.
Testar o acesso somente leitura
Abra um shell no pod
readonly-test
:kubectl exec -it readonly-test --namespace=readonly-ns -- /bin/bash
Tente ler o secret:
gcloud secrets versions access 1 --secret=bq-readonly-key
A resposta é
key=my-api-key
.Tente gravar novos dados no secret:
printf "my-second-api-key" | gcloud secrets versions add bq-readonly-key --data-file=-
O resultado será assim:
ERROR: (gcloud.secrets.versions.add) PERMISSION_DENIED: Permission 'secretmanager.versions.add' denied for resource 'projects/PROJECT_ID/secrets/bq-readonly-key' (or it may not exist).
O pod que usa a conta de serviço somente leitura só pode ler o secret e não pode gravar novos dados.
Saia do pod:
exit
Testar o acesso de leitura/gravação
Abra um shell no pod
admin-test
:kubectl exec -it admin-test --namespace=admin-ns -- /bin/bash
Tente ler o secret:
gcloud secrets versions access 1 --secret=bq-readonly-key
A resposta é
key=my-api-key
.Tente gravar novos dados no secret:
printf "my-second-api-key" | gcloud secrets versions add bq-readonly-key --data-file=-
O resultado será assim:
Created version [2] of the secret [bq-readonly-key].
Leia a nova versão do secret:
gcloud secrets versions access 2 --secret=bq-readonly-key
A resposta é
my-second-api-key
.Saia do pod:
exit
Os pods recebem apenas o nível de acesso concedido à conta de serviço do Kubernetes usada no manifesto do pod. Qualquer pod que use a
conta do Kubernetes admin-sa
no namespace admin-ns
pode gravar novas versões do
secret, mas qualquer pod no namespace readonly-ns
que use a conta de serviço do Kubernetes readonly-sa
só pode ler o secret.
Acessar secrets do seu código
Nesta seção, você realizará as ações a seguir:
Implante um aplicativo de amostra que leia o secret no Secret Manager usando bibliotecas de cliente.
Verifique se o app pode acessar o secret.
Acesse os secrets do Secret Manager do código do seu aplicativo sempre que possível, usando a API Secret Manager.
Veja o exemplo de código-fonte do aplicativo:
Este aplicativo chama a API Secret Manager para tentar ler o secret.
Revise o exemplo de manifesto do pod do aplicativo:
Esse manifesto faz o seguinte:
- Cria um pod no namespace
readonly-ns
que usa a conta de serviçoreadonly-sa
. - Extrai um aplicativo de amostra de um registro de imagem do Google. Este
aplicativo chama a API Secret Manager usando as
bibliotecas de cliente doGoogle Cloud . É possível ver o código do aplicativo
em
/main.go
no repositório. - Define as variáveis de ambiente que o aplicativo de amostra deve usar.
- Cria um pod no namespace
Substitua as variáveis de ambiente no aplicativo de amostra:
sed -i "s/YOUR_PROJECT_ID/PROJECT_ID/g" "manifests/secret-app.yaml"
Implante o app de amostra:
kubectl apply -f manifests/secret-app.yaml
O pod pode levar alguns minutos para começar a funcionar. Se o pod precisar de um novo nó no cluster, talvez você veja eventos do tipo
CrashLoopBackOff
enquanto o GKE provisiona o nó. As falhas são interrompidas quando o nó é provisionado com sucesso.Verifique o acesso do secret:
kubectl logs readonly-secret-test -n readonly-ns
A resposta é
my-second-api-key
. Se a saída estiver em branco, é possível que o pod ainda não esteja em execução. Aguarde alguns minutos e tente novamente.
Abordagens alternativas
Se for necessário ativar os dados sensíveis nos pods, use o complemento do Secret Manager para o GKE. Esse complemento implanta e gerencia o provedor do Google Cloud Secret Manager para o driver CSI do Kubernetes Secret Store nos clusters do GKE. Para instruções, consulte Usar o complemento do Secret Manager com o GKE.
Fornecer secrets como volumes montados tem os seguintes riscos:
- Os volumes montados são suscetíveis a ataques de travessia de diretórios.
- As variáveis de ambiente podem ser comprometidas devido a configurações incorretas, como abrir um endpoint de depuração.
Sempre que possível, recomendamos que você acesse os secrets programaticamente por meio da API Secret Manager. Para instruções, use o aplicativo de amostra neste tutorial ou consulte as bibliotecas de cliente do Secret Manager.