Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 66

ConfigMaps for Application Configuration

Recommended resources

Olá! Bem-vindo de volta ao nosso módulo de Fundamentos do Kubernetes.

Na lição anterior, você aprendeu a expor sua aplicação ao mundo exterior usando Services, criando um ponto de acesso de rede estável para seus Pods efêmeros. No entanto, há uma questão de boas práticas que ainda não abordamos: tanto a imagem Nginx que usamos quanto sua configuração padrão estão contidas na mesma imagem de contêiner. Em um ambiente de produção real, queremos separar a configuração (como URLs de API, chaves de recursos, ou níveis de log) da imagem do contêiner. Isso torna nossas aplicações mais portáteis e fáceis de gerenciar em diferentes ambientes (desenvolvimento, homologação, produção), um princípio fundamental do The Twelve-Factor App.

Nesta lição, vamos abordar exatamente isso. O objetivo de hoje é: Gerenciar a configuração da aplicação usando ConfigMaps.

Você aprenderá o que são ConfigMaps, como criá-los e, mais importante, as diferentes maneiras de consumi-los em seus Pods, com foco especial nas implicações de cada método para atualizações de configuração em tempo real.

O que é um ConfigMap?

Um ConfigMap é um objeto da API do Kubernetes usado para armazenar dados de configuração não confidenciais em pares chave-valor. Pense nele como um local centralizado no seu cluster para guardar variáveis de ambiente, argumentos de linha de comando ou até mesmo arquivos de configuração inteiros que seus Pods podem usar no momento da execução.

Kubernetes Configmaps Explained for beginners

Para começar, este vídeo do canal That DevOps Guy oferece uma introdução clara ao conceito de ConfigMaps, explicando seu propósito e distinguindo-os de Kubernetes Secrets, que abordaremos na próxima lição.

Assista do início até 02:22. Concentre-se em entender que ConfigMaps são para dados não confidenciais e as três formas principais como os Pods podem consumi-los (variáveis de ambiente, argumentos de linha de comando e arquivos de configuração).

A principal vantagem é o desacoplamento: sua imagem de contêiner pode ser genérica e agnóstica ao ambiente, enquanto a configuração específica é injetada pelo Kubernetes dependendo de onde o Pod está sendo executado.


Criando e Inspecionando um ConfigMap

Como outros objetos do Kubernetes, os ConfigMaps são tipicamente definidos declarativamente usando um manifesto YAML.

Kubernetes ConfigMap Definition and Management Commands
Este diagrama ilustra um manifesto YAML de exemplo para um ConfigMap e os comandos `kubectl` mais comuns para gerenciá-lo.

A estrutura é simples:

  • apiVersion: v1
  • kind: ConfigMap
  • metadata: Contém o nome do ConfigMap.
  • data: Um dicionário onde cada entrada é um par chave-valor. O valor é sempre uma string.

Vamos criar um ConfigMap simples para uma aplicação hipotética.

  1. Crie o arquivo app-configmap.yaml:

    # app-configmap.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-app-config
    data:
      # Configuração como pares chave-valor simples
      LOG_LEVEL: "info"
      API_URL: "http://my-api-service.default.svc.cluster.local"
    
      # Configuração como um arquivo de propriedades inteiro
      app.properties: |
        feature.flag.new.ui=true
        cache.size=256
        database.pool.size=10
    

    Note o uso do caractere pipe (|) para app.properties. Isso permite que você insira um bloco de texto de várias linhas como o valor de uma única chave, o que é extremamente útil para arquivos de configuração inteiros.

  2. Aplique o manifesto ao seu cluster:

    kubectl apply -f app-configmap.yaml
    
  3. Inspecione o ConfigMap:

    Você pode verificar se o ConfigMap foi criado e ver seu conteúdo.

    # Listar todos os ConfigMaps
    kubectl get configmaps
    
    # Descrever o ConfigMap específico para ver suas chaves e valores
    kubectl describe configmap my-app-config
    

Consumindo Dados do ConfigMap em Pods

Agora que nosso ConfigMap existe no cluster, como fazemos para que nossa aplicação o utilize? Existem duas maneiras principais de injetar esses dados em um Pod.

Kubernetes ConfigMap Consumption Methods
Como mostra esta imagem, um ConfigMap pode ser consumido como arquivos em um volume, como variáveis de ambiente, ou como argumentos de linha de comando.

Método 1: Como Variáveis de Ambiente

Esta é a abordagem mais direta. Você pode mapear chaves do ConfigMap diretamente para variáveis de ambiente dentro do seu contêiner.

Kubernetes ConfigMap - What It is, How to Use & Examples

Este artigo do Spacelift mostra exemplos claros de como montar ConfigMaps como variáveis de ambiente usando envFrom (para todas as chaves) e valueFrom (para chaves individuais).

Leia a seção "Example 3: Mounting ConfigMaps into Pods as environment variables". Preste atenção nos dois exemplos de YAML, um usando envFrom para injetar todas as chaves e outro usando env e valueFrom para injetar e renomear uma chave específica.

Aqui está um exemplo de manifesto de Deployment que consome nosso my-app-config:

# nginx-deployment-with-env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        env:
          # Injetando uma única chave do ConfigMap
          - name: NGINX_LOG_LEVEL
            valueFrom:
              configMapKeyRef:
                name: my-app-config  # Nome do ConfigMap
                key: LOG_LEVEL      # Chave a ser usada

        # Injetando todas as chaves do ConfigMap como variáveis de ambiente
        envFrom:
          - configMapRef:
              name: my-app-config

Método 2: Como Arquivos em um Volume

Para configurações maiores, como o app.properties que criamos, ou quando você não quer depender de variáveis de ambiente, a melhor abordagem é montar o ConfigMap como um volume. Quando você faz isso, cada chave no campo data do ConfigMap se torna um arquivo no diretório montado, e o conteúdo do arquivo é o valor da chave.

Isso é análogo a montar um diretório do host em um contêiner com docker run -v, um conceito com o qual você já deve estar familiarizado.

Kubernetes Configmaps Explained for beginners

O mesmo vídeo do That DevOps Guy agora explica em detalhes como funcionam os volumes e volumeMounts para injetar ConfigMaps como arquivos.

Assista do timestamp 12:25 a 16:23. O vídeo faz uma ótima analogia com os volumes do Docker e detalha a sintaxe YAML necessária no manifesto do Pod/Deployment.

Vamos adaptar nosso Deployment para usar este método:

# nginx-deployment-with-volume.yaml
apiVersion: apps/v1
kind: Deployment
# ... metadata, spec.replicas, spec.selector ...
  template:
    # ... metadata ...
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: app-config-volume   # Nome do volume a ser montado
          mountPath: /etc/config   # Diretório dentro do contêiner
      
      # Define o volume
      volumes:
      - name: app-config-volume      # Deve corresponder ao nome em volumeMounts
        configMap:
          name: my-app-config      # O nome do ConfigMap a ser usado

Se você aplicar este manifesto e executar kubectl exec para entrar no Pod, encontrará os seguintes arquivos em /etc/config: LOG_LEVEL, API_URL e app.properties, cada um contendo o valor correspondente.


Atualizações de ConfigMap: O Ponto Crucial

Aqui está uma das partes mais importantes e que muitas vezes causa confusão: o que acontece quando você atualiza um ConfigMap que já está em uso? A resposta depende de como ele está sendo consumido.

DAY-41 | KUBERNETES LIVE PROJECT | CONFIGMAPS & SECRETS | HOW TO USE CONFIGMAPS & SECRETS INSIDE POD

Este vídeo de Abhishek Veeramalla demonstra de forma prática e brilhante a diferença no comportamento de atualização. É fundamental assistir a ambas as partes para entender as implicações de cada método.

Assista a estas duas seções em sequência: Primeiro (16:31 a 25:33): Veja como ele injeta uma variável de ambiente, atualiza o ConfigMap e mostra que o valor NÃO muda dentro do Pod em execução. Segundo (25:33 a 33:06): Veja como ele muda para uma montagem de volume, atualiza o ConfigMap novamente e, após um curto período, o valor do arquivo dentro do Pod É atualizado automaticamente, sem reiniciar o Pod.

Resumindo a demonstração do vídeo:

  • Variáveis de Ambiente: São imutáveis. Elas são injetadas no contêiner no momento em que ele é criado. Alterações posteriores no ConfigMap não serão refletidas nos Pods em execução. Você precisaria reiniciar os Pods para que eles peguem os novos valores.
  • Volumes Montados: São dinâmicos. O Kubernetes atualiza periodicamente os arquivos montados quando o ConfigMap associado muda. Há um pequeno atraso (geralmente até um minuto), mas as alterações são propagadas para os Pods em execução sem a necessidade de reiniciá-los.
Teste seu entendimento!

Você precisa fornecer um token de acesso de curta duração que é atualizado a cada hora para sua aplicação. Qual método de consumo de ConfigMap você escolheria e por quê?

Show answer

O método de montagem de volume seria o ideal. Como os arquivos montados a partir de um ConfigMap são atualizados dinamicamente, a aplicação pode simplesmente reler o arquivo do disco periodicamente para obter o novo token. Se você usasse variáveis de ambiente, precisaria reiniciar o Pod a cada hora, o que é ineficiente e causaria interrupções. (Nota: para um token real, usaríamos um Kubernetes Secret, mas o princípio de atualização é o mesmo).


Aplicação Prática: Hot-Reloading em .NET

Apenas porque o Kubernetes atualiza o arquivo no disco, não significa que sua aplicação .NET irá automaticamente recarregar a configuração. Dado seu background em .NET, vamos ver como conectar essas duas peças.

O IConfiguration do .NET tem mecanismos para observar mudanças em arquivos, mas há um detalhe importante ao trabalhar com volumes de ConfigMap do Kubernetes.

Hot-Reload .NET Configuration in Kubernetes with ConfigMaps

Este excelente artigo de Thorsten Hans é direcionado especificamente para desenvolvedores .NET. Ele mostra exatamente como configurar sua aplicação para recarregar automaticamente a configuração de um ConfigMap montado.

Leia as seções "ConfigMap to control ILogger" e "Feeding .NET IConfiguration". O ponto chave está na combinação do método AddKeyPerFile com a variável de ambiente DOTNET_USE_POLLING_FILE_WATCHER.

Os passos essenciais para habilitar o "hot-reloading" em sua aplicação .NET são:

  1. Montar o ConfigMap como um volume no seu manifesto de Deployment (como vimos no Método 2).
  2. No Program.cs da sua aplicação, usar o provedor de configuração AddKeyPerFile:
    builder.Configuration.AddKeyPerFile("/etc/config", optional: true, reloadOnChange: true);
    
    Isso instrui o .NET a carregar cada arquivo no diretório /etc/config como uma chave de configuração e a observar mudanças.
  3. Adicionar a seguinte variável de ambiente ao manifesto do seu contêiner:
    env:
      - name: DOTNET_USE_POLLING_FILE_WATCHER
        value: "true"
    
    Isso é necessário porque o Kubernetes usa symlinks para atualizar os arquivos do ConfigMap, e o observador de arquivos padrão do .NET pode não detectar essas alterações de forma confiável. O modo de "polling" garante que o .NET verifique ativamente os arquivos em intervalos regulares, capturando as atualizações feitas pelo Kubernetes.

Conclusão

Parabéns! Você aprendeu a separar a configuração do código da sua aplicação usando ConfigMaps, um passo crucial para construir aplicações robustas e portáteis no Kubernetes.

Principais Pontos:

  • ConfigMaps desacoplam a configuração: Eles permitem que você gerencie configurações não confidenciais externamente à sua imagem de contêiner.
  • Dois métodos de consumo: Você pode injetar dados como variáveis de ambiente ou como arquivos em um volume.
  • O comportamento de atualização é a chave: Variáveis de ambiente são estáticas e exigem um reinício do Pod para serem atualizadas. Volumes montados são dinâmicos e se atualizam automaticamente.
  • Para hot-reloading em .NET: Use a montagem de volume, AddKeyPerFile com reloadOnChange: true, e a variável de ambiente DOTNET_USE_POLLING_FILE_WATCHER.

Próxima Lição:
Nós enfatizamos que ConfigMaps são para dados não confidenciais. Mas e quanto a senhas de banco de dados, chaves de API e certificados TLS? Armazená-los em texto plano em um ConfigMap é uma péssima prática de segurança. Na próxima lição, "Gerenciar dados sensíveis usando Secrets", veremos a solução do Kubernetes para este problema.