Download do Terraform

Aula 12 – K8S – Gerenciamento de Configuração e Secrets no Kubernetes

Introdução

ConfigMaps são objetos da API do Kubernetes usados para armazenar dados de configuração não confidenciais em formato de pares chave-valor. Eles são projetados para desacoplar as configurações da aplicação, do código da aplicação, permitindo maior portabilidade e flexibilidade. Secrets são objetos da API do Kubernetes criados para armazenar e gerenciar dados sensíveis, como senhas, tokens OAuth e chaves SSH. Diferentemente dos ConfigMaps, que são usados para guardar informações não confidenciais, os Secrets são utilizados para manter informações que, se expostas, poderiam causar danos significativos à segurança ou à integridade de um sistema. Os Secrets são especialmente projetados para controlar o acesso a dados sensíveis, oferecendo mecanismos para limitar a exposição acidental ou não autorizada. Eles também permitem a aplicação de políticas de segurança, como criptografia em repouso, garantindo que os dados sensíveis sejam armazenados de forma segura no etcd, o armazenamento de dados do Kubernetes. Esta abordagem ajuda a desacoplar dados sensíveis do código da aplicação, contribuindo para a portabilidade e flexibilidade dos aplicativos sem comprometer a segurança. Além disso, a gestão de Secrets no Kubernetes facilita a rotação segura e a atualização de credenciais sem a necessidade de reconstruir imagens de contêineres ou reiniciar contêineres, o que é crucial para manter a segurança e a disponibilidade em ambientes de produção dinâmicos.

Problemas que ConfigMaps e Secrets Resolvem

Ao desenvolver e implantar aplicações em Kubernetes, frequentemente enfrentamos dois desafios principais:
  1. Gerenciamento de Configurações
  2. Proteção de Dados Sensíveis

Gerenciamento de Configurações

Imagine que você está implantando um aplicativo Python, que exibe mensagens e utiliza dados sensíveis, em diferentes ambientes: desenvolvimentoteste e produção. Cada ambiente pode requerer configurações ligeiramente diferentes, tais como:
  • URLs de serviços externos: Dependendo do ambiente, você pode querer conectar-se a diferentes endpoints de APIs ou serviços externos.
  • Níveis de logging: Em desenvolvimento, você pode preferir um nível de logging detalhado (debug), enquanto em produção, apenas warnings e errors são mais apropriados.
  • Parâmetros do aplicativo: Como variáveis que influenciam o comportamento do aplicativo, por exemplo, frequência de atualizações ou parâmetros específicos relacionados ao ambiente.
  • Configurações de banco de dados: Conexões com bancos de dados podem variar, utilizando diferentes credenciais ou apontando para diferentes servidores.
Sem uma solução adequada, você poderia:
  • Codificar essas configurações diretamente no código-fonte, o que dificulta mudanças e cria a necessidade de rebuilds frequentes.
  • Usar variáveis de ambiente, que podem se tornar difíceis de gerenciar à medida que crescem em número e complexidade.
É aqui que os ConfigMaps entram. Eles permitem:
  • Separar configurações do código
  • Gerenciar configurações de forma centralizada
  • Atualizar configurações sem reconstruir imagens de contêiner

Proteção de Dados Sensíveis

Agora, pense em dados que não devem ser expostos publicamente:
  • Senhas de banco de dados
  • Tokens de API
  • Chaves de criptografia
  • Certificados SSL
Armazenar esses dados de forma insegura pode levar a:
  • Vazamentos de segurança se o código ou as configurações forem expostos
  • Dificuldade em rotacionar credenciais regularmente
  • Problemas de conformidade em auditorias de segurança
Os Secrets do Kubernetes resolvem esses problemas ao:
  • Fornecer um objeto específico para dados sensíveis
  • Oferecer criptografia em repouso (depende da configuração do cluster)
  • Permitir controle de acesso granular
  • Facilitar a rotação de credenciais

Exemplo Prático

Para gerenciar essas configurações, você pode criar ConfigMaps e Secrets específicos para cada ambiente. Aqui está como você poderia configurar os diferentes ambientes: ConfigMap para Desenvolvimento
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config-dev
data:
  API_URL: "https://dev.api.service.com"
  LOG_LEVEL: "DEBUG"
  REFRESH_RATE: "10"
Este ConfigMap é utilizado para manter as configurações externas ao código do aplicativo, facilitando ajustes sem necessidade de novas compilações ou implantações, promovendo agilidade e flexibilidade no desenvolvimento. Ele é chamado deapp-config-dev contém três pares chave-valor:
  • API_URL: Define a URL da API que o aplicativo deve utilizar em desenvolvimento, neste caso, “https://dev.api.service.com“.
  • LOG_LEVEL: Configura o nível de log como “DEBUG“, o que geralmente proporciona uma saída de log mais detalhada, útil durante o desenvolvimento para rastrear erros e o fluxo de dados.
  • REFRESH_RATE: Especifica a taxa de atualização, “10“, que pode ser usada para definir a frequência com que o aplicativo atualiza dados ou verifica mudanças, ou seja, o REFRESH_RATE determina quão frequentemente o aplicativo consulta uma fonte externa (como uma API) para obter novos dados, ou mudanças em arquivos, configurações ou outros tipos de dados, ou à taxa com que a interface do usuário é atualizada ou re-renderizada com novos dados.
OBS. Os intervalos de tempo não é sempre explicitamente definida no valor da configuração. Isso significa que, dependendo do contexto do aplicativo, “10” pode representar segundos, milissegundos, minutos, ou qualquer outra unidade de tempo que o desenvolvedor decida usar.   ConfigMap para Teste
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config-test
data:
  API_URL: "https://test.api.service.com"
  LOG_LEVEL: "INFO"
  REFRESH_RATE: "30"
Esse ConfigMap chamado app-config-test é utilizado para armazenar configurações específicas do ambiente de teste de um aplicativo. Ele contém três pares chave-valor importantes:
  • API_URL: Especifica a URL da API de teste que o aplicativo deve acessar, neste caso, “https://test.api.service.com”. Essa URL é geralmente diferente da usada em ambientes de desenvolvimento ou produção para garantir que o ambiente de teste seja isolado.
  • LOG_LEVEL: Estabelece o nível de log como “INFO”. Este nível é um meio-termo entre os detalhes completos fornecidos por “DEBUG” e a visibilidade restrita de “ERROR”, equilibrando visibilidade e performance. É adequado para testes, pois fornece informações suficientes para entender o comportamento do aplicativo sem o overhead de logs muito detalhados.
  • REFRESH_RATE: Define a frequência, “30”, com que o aplicativo deve atualizar dados ou verificar mudanças. Esta configuração pode influenciar como o aplicativo lida com operações que dependem do tempo, como atualizações de status ou sincronização de dados. A unidade de tempo (segundos, minutos, etc.) depende da implementação específica do aplicativo.
Assim como outros ConfigMaps, o app-config-test ajuda a separar as configurações específicas do ambiente de teste do código do aplicativo, aumentando a portabilidade e facilitando ajustes sem necessidade de recompilações ou reinicializações do aplicativo. ConfigMap para Produção
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config-prod
data:
  API_URL: "https://prod.api.service.com"
  LOG_LEVEL: "ERROR"
  REFRESH_RATE: "60"
ConfigMap chamado app-config-prod é projetado para armazenar configurações críticas para o ambiente de produção de um aplicativo. Ele inclui três configurações chave-valor:
  • API_URL: Aponta para a URL “https://prod.api.service.com”, que é a interface de produção para serviços externos ou APIs que o aplicativo consome. Esta URL é configurada para o ambiente de produção, garantindo que todas as interações sejam realizadas com sistemas destinados ao uso real e operacional.
  • LOG_LEVEL: Configurado para “ERROR”, este nível de log é escolhido para registrar apenas erros graves que precisam de atenção imediata. Isso ajuda a minimizar a quantidade de dados de log gerados em um ambiente onde o desempenho e a estabilidade são críticos, ao mesmo tempo que garante que problemas significativos sejam capturados e registrados.
  • REFRESH_RATE: Definido como “60”, esta configuração determina a frequência com que o aplicativo verifica atualizações ou muda seu estado, com base nas necessidades operacionais. A taxa de atualização em um ambiente de produção geralmente é configurada para ser menos frequente para garantir estabilidade e reduzir a carga no servidor ou na rede.
Utilizando este ConfigMap, o ambiente de produção é otimizado para desempenho e estabilidade, mantendo configurações separadas das do código do aplicativo e facilitando a manutenção e as atualizações sem interrupções no serviço. Secret para Banco de Dados (comum a todos ambientes mas com credenciais diferentes) Para produção:
apiVersion: v1
kind: Secret
metadata:
  name: db-secret-prod
type: Opaque
data:
  DB_USER: $(echo -n "user_prod" | base64)
  DB_PASSWORD: $(echo -n "pass_prod" | base64)
Secret chamado db-secret-prod é utilizado para armazenar de forma segura as credenciais do banco de dados que são específicas para o ambiente de produção. A estrutura desse Secret inclui:
  • DB_USER: Armazena o nome de usuário do banco de dados, que é codificado em base64. No exemplo dado, o nome de usuário real seria “user_prod”. A codificação base64 não é uma forma de criptografia ou hashing, mas simplesmente ofusca os dados para que não sejam expostos em texto claro nos manifestos do Kubernetes.
  • DB_PASSWORD: Armazena a senha do banco de dados, também codificada em base64. A senha real correspondente a este exemplo seria “pass_prod”.
Os Secrets são essenciais para gerenciar dados sensíveis e garantir que informações críticas, como credenciais de banco de dados, não sejam expostas ou manipuladas inapropriadamente. No Kubernetes, Secrets são utilizados para injetar essas credenciais em contêineres de forma segura durante o tempo de execução, sem expô-las nos scripts de configuração ou no código fonte. Para desenvolvimento:
apiVersion: v1
kind: Secret
metadata:
  name: db-secret-dev
type: Opaque
data:
  DB_USER: $(echo -n "user_dev" | base64)
  DB_PASSWORD: $(echo -n "pass_dev" | base64)
Secret chamado db-secret-dev é projetado para armazenar de forma segura as credenciais do banco de dados usadas no ambiente de desenvolvimento. Este Secret contém:
  • DB_USER: Guarda o nome de usuário do banco de dados, codificado em base64. Neste exemplo, o nome de usuário real é “user_dev”. Embora a codificação em base64 não ofereça segurança real, ela protege a informação de ser exposta em texto claro nos arquivos de configuração do Kubernetes.
  • DB_PASSWORD: Armazena a senha do banco de dados, também em formato base64. A senha real para este exemplo seria “pass_dev”.
Os Secrets no Kubernetes são fundamentais para a proteção de dados sensíveis, como credenciais, permitindo que estas informações sejam utilizadas pelos pods de forma segura e sem que sejam expostas em scripts ou no código fonte. Este mecanismo é particularmente importante em ambientes de desenvolvimento onde configurações frequentemente mudam e o risco de exposição acidental pode ser maior. Uso no Deployment Você pode ajustar o arquivo de Deployment para utilizar o ConfigMap e o Secret apropriados, baseando-se no ambiente em que o aplicativo está sendo implantado. Isso é feito especificando o nome do ConfigMap e do Secret correspondente no campo env ou envFrom do spec do container. O exemplo a seguir usa um Deployment para um aplicativo que roda em um contêiner e usa configurações de um ConfigMap e credenciais sensíveis de um Secret.

Exemplo de Deployment no Kubernetes

Suponha que você tenha um aplicativo que precisa de configurações específicas e credenciais de banco de dados para se conectar a um serviço externo. Aqui está como você pode configurar o Deployment para injetar esses dados no contêiner usando ConfigMap e Secret.

Arquivo de Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: meu-aplicativo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: meu-aplicativo
  template:
    metadata:
      labels:
        app: meu-aplicativo
    spec:
      containers:
      - name: meu-container
        image: minha-imagem
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: app-config-dev  # Este nome deve ser alterado conforme o ambiente (dev, test, prod)
        - secretRef:
            name: db-secret-dev  # Este nome também deve mudar com o ambiente

Explicação:

ConfigMapRef: O envFrom com configMapRef especifica que todas as configurações definidas no ConfigMap chamado app-config-dev serão automaticamente disponibilizadas como variáveis de ambiente dentro do contêiner. Você substituiria app-config-dev por app-config-test ou app-config-prod dependendo do ambiente em que o aplicativo está sendo implantado. SecretRef: Da mesma forma, secretRef garante que todos os dados dentro do Secret chamado db-secret-dev sejam expostos como variáveis de ambiente. Isso é útil para manter dados sensíveis, como nomes de usuário e senhas de banco de dados, seguros e separados do código e outras configurações. Assim como o ConfigMap, o nome do Secret deve ser alterado conforme o ambiente para refletir o Secret apropriado (por exemplo, db-secret-prod em produção).

Uso em Produção:

Quando estiver pronto para mover seu aplicativo para o ambiente de produção, você simplesmente alteraria as referências no arquivo de Deployment para apontar para o ConfigMap e Secret de produção:
        - configMapRef:
            name: app-config-prod
        - secretRef:
            name: db-secret-prod 
Esse método permite uma transição suave entre diferentes ambientes sem a necessidade de alterar o código do aplicativo ou suas imagens de contêiner, facilitando a manutenção e atualizações.

Conclusão

Utilizando ConfigMaps e Secrets, você pode facilmente modularizar e segregar as configurações por ambiente, mantendo a flexibilidade e a segurança das informações sensíveis. Esse método permite uma transição suave entre os ambientes sem a necessidade de recriar ou modificar a imagem do Docker, promovendo práticas consistentes e seguras de DevOps.

Por essa aula é só.

Até a próxima!