ConfigMaps e Secrets
Nesta aula, você aprenderá a importância de separar configuração do código em aplicações modernas, utilizando ConfigMaps e Secrets no Kubernetes. Exploraremos como criar, usar e montar esses recursos para gerenciar configurações não sensíveis e dados sensíveis, com exemplos práticos em bash.
Em aplicações modernas, especialmente em ambientes de contêineres e orquestração como Kubernetes, a separação entre código e configuração é uma prática essencial para manter a flexibilidade, segurança e escalabilidade. Nesta aula, vamos explorar dois recursos fundamentais do Kubernetes: ConfigMaps e Secrets. Eles permitem que você gerencie configurações de aplicativos sem precisar reconstruir imagens de contêineres ou expor dados sensíveis no código-fonte.
Vamos entender como criar, utilizar e montar esses recursos em seus pods, além de discutir boas práticas para lidar com configurações em ambientes dinâmicos.
Separando config do código
O princípio de separar configuração do código é uma das bases do design de software moderno. Em vez de embutir valores como URLs de banco de dados, chaves de API ou parâmetros de ambiente diretamente no código-fonte, você os externaliza em arquivos de configuração, variáveis de ambiente ou serviços de gerenciamento de configuração. Isso traz benefícios como: a possibilidade de alterar o comportamento da aplicação sem recompilar o código, a facilidade de promover a mesma imagem de contêiner entre diferentes ambientes (desenvolvimento, teste, produção) e a redução de riscos de segurança ao evitar a exposição de dados sensíveis no repositório.
No contexto do Kubernetes, essa separação é alcançada principalmente por meio de dois objetos: ConfigMap e Secret. Ambos armazenam dados que podem ser injetados nos pods como variáveis de ambiente, argumentos de linha de comando ou arquivos montados em volumes. A diferença fundamental é que Secrets são destinados a dados sensíveis, como senhas e chaves, enquanto ConfigMaps são para configurações não sensíveis. Kubernetes também oferece criptografia básica para Secrets, embora a criptografia em repouso dependa da configuração do cluster.
ConfigMaps
Um ConfigMap é um objeto do Kubernetes que armazena dados não confidenciais em pares chave-valor. Ele permite que você mantenha a configuração do aplicativo separada da imagem do contêiner, facilitando a atualização de configurações sem precisar reconstruir imagens. Você pode criar um ConfigMap a partir de literais, arquivos ou diretórios, e depois referenciá-lo em seus pods.
Para criar um ConfigMap, você pode usar o comando kubectl create configmap. Por exemplo, para criar um ConfigMap chamado app-config com algumas variáveis:
kubectl create configmap app-config --from-literal=APP_COLOR=blue --from-literal=APP_MODE=productionVocê também pode criar a partir de arquivos de configuração:
kubectl create configmap app-config --from-file=application.propertiesDepois de criado, você pode usar o ConfigMap em um pod de várias maneiras. A mais comum é definir variáveis de ambiente a partir do ConfigMap. No manifesto YAML do pod, você pode usar valueFrom e configMapKeyRef:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: app-config
key: APP_COLORTambém é possível montar o ConfigMap como um volume, o que veremos na seção de montagem.
Secrets
Secrets são semelhantes aos ConfigMaps, mas são projetados para armazenar dados sensíveis, como senhas, tokens e chaves SSH. O Kubernetes armazena Secrets em formato base64, mas isso não é criptografia; qualquer pessoa com acesso ao cluster pode facilmente decodificá-los. Portanto, é importante usar mecanismos adicionais como criptografia em repouso e controle de acesso baseado em RBAC.
Para criar um Secret, use o comando kubectl create secret. Por exemplo, para criar um Secret chamado db-secret com uma senha:
kubectl create secret generic db-secret --from-literal=DB_PASSWORD=supersecretVocê também pode criar a partir de arquivos:
kubectl create secret generic db-secret --from-file=credentials.txtPara usar o Secret em um pod, você pode injetar como variável de ambiente:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: postgres
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORDLembre-se de que os valores dos Secrets são codificados em base64, mas você pode usar o valor diretamente no YAML se quiser, desde que esteja no formato correto.
Montagem
Além de injetar variáveis de ambiente, você pode montar ConfigMaps e Secrets como volumes nos pods. Isso é útil quando sua aplicação espera arquivos de configuração em um diretório específico, como /etc/config. Quando você monta um ConfigMap ou Secret como volume, cada chave se torna um arquivo no diretório de montagem, com o conteúdo sendo o valor correspondente.
Por exemplo, para montar o ConfigMap app-config no diretório /etc/config:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-configDa mesma forma, para Secrets, você pode montar como volume:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
volumes:
- name: secret-volume
secret:
secretName: db-secretUma vantagem de montar como volume é que as atualizações nos ConfigMaps/Secrets podem ser refletidas nos pods automaticamente (dependendo da configuração de sincronização), enquanto variáveis de ambiente não são atualizadas após a criação do pod.
Boas práticas
Ao trabalhar com ConfigMaps e Secrets, considere as seguintes boas práticas:
- Não inclua dados sensíveis em ConfigMaps; use Secrets para isso.
- Limite o acesso a Secrets usando RBAC e namespaces.
- Considere usar ferramentas como Sealed Secrets ou External Secrets para gerenciar Secrets de forma mais segura.
- Prefira montar volumes para configurações que podem mudar durante a vida útil do pod.
- Use nomes descritivos e organize seus ConfigMaps/Secrets por aplicação ou namespace.
Exercícios
- Crie um ConfigMap chamado
meu-configcom as chavesCOR=azuleMODO=testeusando kubectl. Qual comando você usaria? - Escreva um manifesto YAML para um pod que use o ConfigMap
meu-configpara definir a variável de ambienteCOR. - Crie um Secret chamado
meu-secretcom a chaveSENHA=123456usando kubectl e depois visualize o valor codificado em base64. - Monte o Secret
meu-secretcomo volume no caminho/etc/segredoem um pod. Escreva o YAML. - Explique a diferença entre usar ConfigMaps/Secrets como variáveis de ambiente e como volumes, e quando preferir cada um.
kubectl create configmap meu-config --from-literal=COR=azul --from-literal=MODO=testeapiVersion: v1
kind: Pod
metadata:
name: meu-pod
spec:
containers:
- name: meu-container
image: nginx
env:
- name: COR
valueFrom:
configMapKeyRef:
name: meu-config
key: CORkubectl create secret generic meu-secret --from-literal=SENHA=123456Para ver:
kubectl get secret meu-secret -o yaml e observe o valor em base64 (MTIzNDU2).apiVersion: v1
kind: Pod
metadata:
name: pod-com-secret
spec:
containers:
- name: container
image: nginx
volumeMounts:
- name: segredo-volume
mountPath: /etc/segredo
volumes:
- name: segredo-volume
secret:
secretName: meu-secret