Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Kubernetes e gestão de secrets na nuvem: Parte 2

By Alexei LedenevMay 7, 20205 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

1 2vmdytkvuqf4gosqpgyjka

Armazene chaves de API, senhas, certificados e outros dados sensíveis em serviços de gestão de secrets nativos da nuvem e acesse-os a partir de clusters K8s.

Introdução

Os secrets são essenciais para o funcionamento de muitos sistemas em produção. A exposição acidental de secrets é um dos maiores riscos e precisa ser tratada com cuidado. Os desenvolvedores devem fazer o possível para proteger os secrets das aplicações.

O problema fica ainda mais complicado quando uma empresa migra para uma arquitetura de microsserviços e vários serviços precisam acessar diferentes secrets para funcionar corretamente. Isso traz novos desafios: como distribuir, gerenciar, monitorar e rotacionar os secrets das aplicações sem expô-los acidentalmente?

No post anterior ( Parte I), mostrei uma forma de integrar os serviços de gestão de secrets da AWS e do Google Cloud ( AWS Secrets Manager, AWS SSM Parameter Store e Google Cloud Secret Manager) com o Kubernetes, usando o initContainer doitintl/secrets-init adicionado manualmente a um Pod de destino.

Neste post, vou apresentar uma abordagem nativa do Kubernetes para integrar os serviços de gestão de secrets na nuvem mencionados acima.

Injeção automática de secrets na nuvem

Embora dê para alterar manualmente os arquivos YAML de Deployment do Kubernetes para usar o secret-init como sistema init do container, seria muito melhor se alguém fizesse isso por você — e somente para os Pods do Kubernetes que referenciam secrets na nuvem. Felizmente, o Kubernetes permite inspecionar e alterar qualquer Pod antes da criação do container, por meio de um mecanismo conhecido como mutating admission webhook.

O doitintl/kube-secrets-init é um projeto open source da DoiT International que implementa um mutating admission webhook do Kubernetes para injeção de secrets na nuvem, com suporte tanto a secrets gerenciados pela AWS quanto pelo Google Cloud.

O kube-secrets-init monitora clusters Kubernetes em busca de Pods recém-criados ou atualizados e adiciona um initContainer com o utilitário doitintl/secrets-init aos Pods que referenciam secrets na nuvem, seja diretamente (via variáveis de ambiente) ou indiretamente (via Secret e ConfigMap do Kubernetes).

0 hvfcvwhqc bmz8jd

Integração com o AWS Secrets Manager

Você pode usar uma referência ARN de um secret da AWS como valor de uma variável de ambiente. O secrets-init resolve esse valor, com base no ARN informado, para o valor do secret referenciado.

https://gist.github.com/930c9ea733557f9715f976df042bf361

Integração com o AWS Systems Manager Parameter Store

Você pode usar o AWS Systems Manager Parameter Store para armazenar parâmetros e secrets de aplicações.

Basta informar uma referência ARN do AWS Parameter Store como variável de ambiente. O secrets-init resolve esse valor, com base no ARN informado, para o valor do parâmetro referenciado.

https://gist.github.com/f7d9a81d5e239cdd734989a689d46f82

Integração com o Google Secret Manager

Você pode informar o nome de um Google Secret (com o prefixo gcp:secretmanager:) como valor de uma variável de ambiente. O secrets-init resolve esse valor, com base no nome informado, para o valor do secret referenciado. O nome do secret pode incluir uma versão, caso queira referenciar uma versão específica.

https://gist.github.com/d121cce3a9d4664a876deb95f18493d7

Pré-requisitos

AWS

Para resolver secrets da AWS no AWS Secrets Manager e no Parameter Store, a aplicação secrets-init precisa ser executada sob uma IAM Role da AWS com uma das IAM policies abaixo anexadas.

Para o AWS Secrets Manager:

https://gist.github.com/7348301b4882a564cbd9644d6697c3eb

Para o AWS Systems Manager Parameter Store:

https://gist.github.com/3f3dd3d015a4c000341491c18ac2c4b7

Em um cluster EKS, o recomendado é usar AWS IAM Roles for Service Account. Também dá para atribuir uma IAM Role à instância EC2 onde o container está rodando, mas essa opção é considerada menos segura.

Google Cloud

Para resolver secrets do Google no Google Secret Manager, a aplicação secrets-init precisa ser executada sob uma IAM role com permissões suficientes para acessar os secrets desejados. Por exemplo, dá para atribuir as duas IAM roles predefinidas do Google a seguir a uma Google Service Account: Secret Manager Viewer e Secret Manager Secret Accessor.

No cluster GKE, dá para atribuir uma IAM Role a um Pod do Kubernetes via Workload Identity. Também é possível atribuir uma IAM Role à instância GCE onde o container está rodando, mas essa opção é considerada menos segura.

Descomente a flag --provider=google no arquivo deployment.yaml.

O deployment do webhook

  1. Para subir o servidor de webhook do kube-secrets-init, precisamos criar um service de webhook e um deployment no nosso cluster Kubernetes. É bem direto, com exceção de um detalhe: a configuração TLS do servidor. Se você abrir o arquivo deployment.yaml, vai notar que o certificado e o respectivo arquivo de chave privada são lidos a partir de argumentos de linha de comando, e que o caminho desses arquivos vem de um volume mount apontando para um secret do Kubernetes:

https://gist.github.com/b861984a2be2f2f63596f089f417cefc

O ponto mais importante é lembrar de definir o certificado CA correspondente mais adiante na configuração do webhook, para que o apiserver saiba que ele deve ser aceito. Por enquanto, vamos reaproveitar o script originalmente escrito pela equipe do Istio para gerar uma solicitação de assinatura de certificado. Em seguida, enviamos a solicitação para a API do Kubernetes, buscamos o certificado e criamos o secret necessário a partir do resultado.

Primeiro, execute o script webhook-create-signed-cert.sh e verifique se o secret com o certificado e a chave foi criado:

https://gist.github.com/43135c6af29328bcd74a37b0df5188f8

Depois que o secret for criado, podemos criar o deployment e o service. São recursos padrão de deployment e service do Kubernetes. Até aqui, geramos apenas um servidor HTTP que aceita requisições pelo service na porta 443:

https://gist.github.com/3971cf1f46f5a57d11d922ed84b0543f

Configurar o Mutating Admission Webhook

Agora que nosso servidor de webhook está no ar, ele já consegue aceitar requisições do apiserver. Mas, antes, precisamos criar alguns recursos de configuração no Kubernetes. Vamos começar pelo validating webhook e configurar o mutating webhook depois. Se você der uma olhada na configuração do webhook, vai notar que ela contém um placeholder para CA_BUNDLE:

https://gist.github.com/fcafa7ed3b3c3b951b7fad3c0d5fbdb6

Existe um pequeno script que substitui o placeholder CA_BUNDLE na configuração por essa CA. Execute este comando antes de criar a configuração do validating webhook:

https://gist.github.com/6d5bb7724cef04e9e6a2af12da917a21

Crie uma configuração de mutating webhook:

https://gist.github.com/f946d6046cc1a76a21526c346ca403c1

Configurar o RBAC do secrets-init-webhook

Crie uma Service Account do Kubernetes para ser usada com o secrets-init-webhook:

https://gist.github.com/0cda887b586609cbdbb700f7412e70ad

Defina as permissões RBAC para a service account do webhook:

https://gist.github.com/1205f1a5d2f449cc3340a404ea474b77

Resumo

Espero que este post seja útil. Fico no aguardo dos seus comentários e dúvidas.

Você também está convidado a contribuir (Issues, Features, PRs) com o projeto no GitHub doitintl/kube-secrets-init.

Quer mais conteúdos do Alexei? Confira o nosso blog ou siga o Alexei no Twitter.