|
| 1 | +--- |
| 2 | +title: ConfigMaps |
| 3 | +content_type: concept |
| 4 | +weight: 20 |
| 5 | +--- |
| 6 | + |
| 7 | +<!-- overview --> |
| 8 | + |
| 9 | +{{< glossary_definition term_id="configmap" prepend="Um ConfigMap é" length="all" >}} |
| 10 | + |
| 11 | +{{< caution >}} |
| 12 | +O ConfigMap não oferece confidencialidade ou encriptação. |
| 13 | +Se os dados que você deseja armazenar são confidenciais, utilize |
| 14 | +{{< glossary_tooltip term_id="secret" >}} ao invés de um ConfigMap, |
| 15 | +ou utilize ferramentas adicionais (de terceiros) para manter seus dados privados. |
| 16 | +{{< /caution >}} |
| 17 | + |
| 18 | + |
| 19 | +<!-- body --> |
| 20 | +## Motivação |
| 21 | + |
| 22 | +Utilize um ConfigMap para manter a configuração separada do código da aplicação. |
| 23 | + |
| 24 | +Por exemplo, imagine que você esteja desenvolvendo uma aplicação que pode ser executada |
| 25 | +no seu computador local (para desenvolvimento) e na nuvem (para manipular tráfego real). |
| 26 | +Você escreve código para ler a variável de ambiente chamada `DATABASE_HOST`. |
| 27 | +No seu ambiente local, você configura essa variável com o valor `localhost`. Na nuvem, você |
| 28 | +configura essa variável para referenciar um {{< glossary_tooltip text="serviço" term_id="service" >}} |
| 29 | +do Kubernetes que expõe o componente do banco de dados ao seu cluster. |
| 30 | +Isto permite que você baixe uma imagem de contêiner que roda na nuvem e depure o exato |
| 31 | +mesmo código localmente se necessário. |
| 32 | + |
| 33 | +Um ConfigMap não foi planejado para conter grandes quantidades de dados. Os dados armazenados |
| 34 | +em um ConfigMap não podem exceder 1 MiB. Se você precisa armazenar configurações que são maiores |
| 35 | +que este limite, considere montar um volume ou utilizar um serviço separado de banco de dados |
| 36 | +ou de arquivamento de dados. |
| 37 | + |
| 38 | +## Objeto ConfigMap |
| 39 | + |
| 40 | +Um ConfigMap é um [objeto](/docs/concepts/overview/working-with-objects/kubernetes-objects/) |
| 41 | +da API que permite o armazenamento de configurações para consumo por outros objetos. Diferentemente |
| 42 | +de outros objetos do Kubernetes que contém um campo `spec`, o ConfigMap contém os campos `data` e |
| 43 | +`binaryData`. Estes campos aceitam pares chave-valor como valores. Ambos os campos `data` e `binaryData` |
| 44 | +são opcionais. O campo `data` foi pensado para conter sequências de bytes UTF-8, enquanto o campo `binaryData` |
| 45 | +foi planejado para conter dados binários em forma de strings codificadas em base64. |
| 46 | + |
| 47 | +É obrigatório que o nome de um ConfigMap seja um |
| 48 | +[subdomínio DNS válido](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names). |
| 49 | + |
| 50 | +Cada chave sob as seções `data` ou `binaryData` pode conter quaisquer caracteres alfanuméricos, |
| 51 | +`-`, `_` e `.`. As chaves armazenadas na seção `data` não podem colidir com as chaves armazenadas |
| 52 | +na seção `binaryData`. |
| 53 | + |
| 54 | +A partir da versão v1.19 do Kubernetes, é possível adicionar o campo `immutable` a uma definição de ConfigMap |
| 55 | +para criar um [ConfigMap imutável](#configmap-immutable). |
| 56 | + |
| 57 | +## ConfigMaps e Pods |
| 58 | + |
| 59 | +Você pode escrever uma `spec` para um Pod que se refere a um ConfigMap e configurar o(s) contêiner(es) |
| 60 | +neste Pod baseados em dados do ConfigMap. O Pod e o ConfigMap devem estar no mesmo |
| 61 | +{{< glossary_tooltip text="namespace" term_id="namespace" >}}. |
| 62 | + |
| 63 | +{{< note >}} |
| 64 | +A `spec` de um {{< glossary_tooltip text="Pod estático" term_id="static-pod" >}} não pode se referir a um |
| 65 | +ConfigMap ou a quaisquer outros objetos da API. |
| 66 | +{{< /note >}} |
| 67 | + |
| 68 | +Exemplo de um ConfigMap que contém algumas chaves com valores avulsos e outras chaves com valores semelhantes |
| 69 | +a fragmentos de arquivos de configuração: |
| 70 | +```yaml |
| 71 | +apiVersion: v1 |
| 72 | +kind: ConfigMap |
| 73 | +metadata: |
| 74 | + name: game-demo |
| 75 | +data: |
| 76 | + # chaves com valores de propriedades; cada chave mapeia para um valor avulso |
| 77 | + player_initial_lives: "3" |
| 78 | + ui_properties_file_name: "user-interface.properties" |
| 79 | + |
| 80 | + # chaves semelhantes a fragmentos de arquivos |
| 81 | + game.properties: | |
| 82 | + enemy.types=aliens,monsters |
| 83 | + player.maximum-lives=5 |
| 84 | + user-interface.properties: | |
| 85 | + color.good=purple |
| 86 | + color.bad=yellow |
| 87 | + allow.textmode=true |
| 88 | +``` |
| 89 | +
|
| 90 | +Existem quatro formas diferentes para consumo de um ConfigMap na configuração de um |
| 91 | +contêiner dentro de um Pod: |
| 92 | +
|
| 93 | +1. Dentro de um comando de contêiner e seus argumentos. |
| 94 | +1. Variáveis de ambiente para um contêiner. |
| 95 | +1. Criando um arquivo em um volume somente leitura, para consumo pela aplicação. |
| 96 | +1. Escrevendo código para execução dentro do Pod que utilize a API do Kubernetes para ler um ConfigMap. |
| 97 | +
|
| 98 | +Os diferentes métodos de consumo oferecem diferentes formas de modelar os dados sendo consumidos. |
| 99 | +Para os três primeiros métodos, o {{< glossary_tooltip text="kubelet" term_id="kubelet" >}} utiliza |
| 100 | +os dados de um ConfigMap quando o(s) contêiner(es) do Pod são inicializados. |
| 101 | +
|
| 102 | +O quarto método envolve escrita de código para leitura do ConfigMap e dos seus dados. No entanto, |
| 103 | +como a API do Kubernetes está sendo utilizada diretamente, a aplicação pode solicitar atualizações |
| 104 | +sempre que o ConfigMap for alterado e reagir quando isso ocorre. Acessar a API do Kubernetes |
| 105 | +diretamente também permite ler ConfigMaps em outros namespaces. |
| 106 | +
|
| 107 | +Exemplo de um Pod que utiliza valores do ConfigMap `game-demo` para configurar um Pod: |
| 108 | + |
| 109 | +```yaml |
| 110 | +apiVersion: v1 |
| 111 | +kind: Pod |
| 112 | +metadata: |
| 113 | + name: configmap-demo-pod |
| 114 | +spec: |
| 115 | + containers: |
| 116 | + - name: demo |
| 117 | + image: alpine |
| 118 | + command: ["sleep", "3600"] |
| 119 | + env: |
| 120 | + # Define as variáveis de ambiente |
| 121 | + - name: PLAYER_INITIAL_LIVES # Note que aqui a variável está definida em caixa alta, |
| 122 | + # diferente da chave no ConfigMap. |
| 123 | + valueFrom: |
| 124 | + configMapKeyRef: |
| 125 | + name: game-demo # O ConfigMap de onde esse valor vem. |
| 126 | + key: player_initial_lives # A chave que deve ser buscada. |
| 127 | + - name: UI_PROPERTIES_FILE_NAME |
| 128 | + valueFrom: |
| 129 | + configMapKeyRef: |
| 130 | + name: game-demo |
| 131 | + key: ui_properties_file_name |
| 132 | + volumeMounts: |
| 133 | + - name: config |
| 134 | + mountPath: "/config" |
| 135 | + readOnly: true |
| 136 | + volumes: |
| 137 | + # Volumes são definidos no escopo do Pod, e os pontos de montagem são definidos |
| 138 | + # nos contêineres dentro dos pods. |
| 139 | + - name: config |
| 140 | + configMap: |
| 141 | + # Informe o nome do ConfigMap que deseja montar. |
| 142 | + name: game-demo |
| 143 | + # Uma lista de chaves do ConfigMap para serem criadas como arquivos. |
| 144 | + items: |
| 145 | + - key: "game.properties" |
| 146 | + path: "game.properties" |
| 147 | + - key: "user-interface.properties" |
| 148 | + path: "user-interface.properties" |
| 149 | +``` |
| 150 | + |
| 151 | +ConfigMaps não diferenciam entre propriedades com valores simples ou valores complexos, |
| 152 | +que ocupam várias linhas. O importante é a forma que Pods e outros objetos consumem tais valores. |
| 153 | + |
| 154 | +Para este exemplo, definir um volume e montar ele dentro do container `demo` no caminho `/config` |
| 155 | +cria dois arquivos: `/config/game.properties` e `/config/user-interface.properties`, embora existam |
| 156 | +quatro chaves distintas no ConfigMap. Isso se deve ao fato de que a definição do Pod contém uma lista |
| 157 | +`items` na seção `volumes`. |
| 158 | +Se a lista `items` for omitida, cada chave do ConfigMap torna-se um arquivo cujo nome é a sua chave |
| 159 | +correspondente, e quatro arquivos serão criados. |
| 160 | + |
| 161 | +## Usando ConfigMaps |
| 162 | + |
| 163 | +ConfigMaps podem ser montados como volumes de dados. ConfigMaps também podem ser utilizados |
| 164 | +por outras partes do sistema sem serem diretamente expostos ao Pod. Por exemplo, ConfigMaps |
| 165 | +podem conter dados que outras partes do sistema devem usar para configuração. |
| 166 | + |
| 167 | +A forma mais comum de utilização de ConfigMaps é a configuração de contêineres executando em |
| 168 | +Pods no mesmo namespace. Você também pode utilizar um ConfigMap separadamente. |
| 169 | + |
| 170 | +Por exemplo, existem {{< glossary_tooltip text="complementos" term_id="addons" >}} ou |
| 171 | +{{< glossary_tooltip text="operadores" term_id="operator-pattern" >}} que adaptam seus comportamentos |
| 172 | +de acordo com dados de um ConfigMap. |
| 173 | + |
| 174 | +### Utilizando ConfigMaps como arquivos em um Pod |
| 175 | + |
| 176 | +Para consumir um ConfigMap em um volume em um Pod: |
| 177 | +1. Crie um ConfigMap ou utilize um ConfigMap existente. Múltiplos Pods |
| 178 | + podem referenciar o mesmo ConfigMap. |
| 179 | +1. Modifique sua definição de Pod para adicionar um volume em |
| 180 | + `.spec.volumes[]`. Escolha um nome qualquer para o seu volume, e |
| 181 | + referencie o seu objeto ConfigMap no campo |
| 182 | + `.spec.volumes[].configMap.name`. |
| 183 | +1. Adicione um campo `.spec.containers[].volumeMounts[]` a cada um dos |
| 184 | + contêineres que precisam do ConfigMap. Especifique |
| 185 | + `.spec.containers[].volumeMounts[].readOnly = true` e informe no campo |
| 186 | + `.spec.containers[].volumeMounts[].mountPath` um caminho de um diretório |
| 187 | + não utilizado onde você deseja que este ConfigMap apareça. |
| 188 | +1. Modifique sua imagem ou linha de comando de modo que o programa procure |
| 189 | + por arquivos no diretório especificado no passo anterior. Cada chave no |
| 190 | + campo `data` do ConfigMap será transformado em um nome de arquivo no |
| 191 | + diretório especificado por `mountPath`. |
| 192 | + |
| 193 | +Exemplo de um Pod que monta um ConfigMap em um volume: |
| 194 | +```yaml |
| 195 | +apiVersion: v1 |
| 196 | +kind: Pod |
| 197 | +metadata: |
| 198 | + name: mypod |
| 199 | +spec: |
| 200 | + containers: |
| 201 | + - name: mypod |
| 202 | + image: redis |
| 203 | + volumeMounts: |
| 204 | + - name: foo |
| 205 | + mountPath: "/etc/foo" |
| 206 | + readOnly: true |
| 207 | + volumes: |
| 208 | + - name: foo |
| 209 | + configMap: |
| 210 | + name: myconfigmap |
| 211 | +``` |
| 212 | + |
| 213 | +Cada ConfigMap que você deseja utilizar precisa ser referenciado em |
| 214 | +`.spec.volumes`. |
| 215 | + |
| 216 | +Se houver múltiplos contêineres no Pod, cada contêiner deve ter seu |
| 217 | +próprio bloco `volumeMounts`, mas somente uma instância de `.spec.volumes` |
| 218 | +é necessária por ConfigMap. |
| 219 | + |
| 220 | +### ConfigMaps montados são atualizados automaticamente |
| 221 | + |
| 222 | +Quando um ConfigMap que está sendo consumido em um volume é atualizado, as chaves projetadas são |
| 223 | +eventualmente atualizadas também. O Kubelet checa se o ConfigMap montado está atualizado em cada |
| 224 | +sincronização periódica. |
| 225 | +No entanto, o kubelet utiliza o cache local para buscar o valor atual do ConfigMap. |
| 226 | +O tipo de cache é configurável utilizando o campo `ConfigMapAndSecretChangeDetectionStrategy` na |
| 227 | +[configuração do Kubelet (KubeletConfiguration)](/docs/reference/config-api/kubelet-config.v1beta1/). |
| 228 | +Um ConfigMap pode ter sua propagação baseada em um _watch_ (comportamento padrão), que é o sistema |
| 229 | +de propagação de mudanças incrementais em objetos do Kubernetes; baseado em TTL (_time to live_, |
| 230 | +ou tempo de expiração); ou redirecionando todas as requisições diretamente para o servidor da API. |
| 231 | +Como resultado, o tempo decorrido total entre o momento em que o ConfigMap foi atualizado até o momento |
| 232 | +quando as novas chaves são projetadas nos Pods pode ser tão longo quanto o tempo de sincronização |
| 233 | +do kubelet somado ao tempo de propagação do cache, onde o tempo de propagação do cache depende do |
| 234 | +tipo de cache escolhido: o tempo de propagação pode ser igual ao tempo de propagação do _watch_, |
| 235 | +TTL do cache, ou zero, de acordo com cada um dos tipos de cache. |
| 236 | + |
| 237 | +ConfigMaps que são consumidos como variáveis de ambiente não atualizam automaticamente e requerem uma |
| 238 | +reinicialização do pod. |
| 239 | + |
| 240 | +## ConfigMaps imutáveis {#configmap-immutable} |
| 241 | + |
| 242 | +{{< feature-state for_k8s_version="v1.21" state="stable">}} |
| 243 | + |
| 244 | +A funcionalidade _Secrets e ConfigMaps imutáveis_ do Kubernetes fornece uma opção |
| 245 | +para marcar Secrets e ConfigMaps individuais como imutáveis. Para clusters que utilizam |
| 246 | +ConfigMaps extensivamente (ao menos centenas de milhares de mapeamentos únicos de |
| 247 | +ConfigMaps para Pods), prevenir alterações dos seus dados traz as seguintes vantagens: |
| 248 | + |
| 249 | +- protege de atualizações acidentais ou indesejadas que podem causar disrupção na execução |
| 250 | + de aplicações |
| 251 | +- melhora o desempenho do cluster através do fechamento de _watches_ de ConfigMaps marcados |
| 252 | + como imutáveis, diminuindo significativamente a carga no kube-apiserver |
| 253 | + |
| 254 | +Essa funcionalidade é controlada pelo [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) |
| 255 | +`ImmutableEphemeralVolumes`. É possível criar um ConfigMap imutável adicionando o campo |
| 256 | +`immutable` e marcando seu valor com `true`. |
| 257 | +Por exemplo: |
| 258 | + |
| 259 | +```yaml |
| 260 | +apiVersion: v1 |
| 261 | +kind: ConfigMap |
| 262 | +metadata: |
| 263 | + ... |
| 264 | +data: |
| 265 | + ... |
| 266 | +immutable: true |
| 267 | +``` |
| 268 | + |
| 269 | +Após um ConfigMap ser marcado como imutável, _não_ é possível reverter a alteração, nem |
| 270 | +alterar o conteúdo dos campos `data` ou `binaryData`. É possível apenas apagar e recriar |
| 271 | +o ConfigMap. Como Pods existentes que consomem o ConfigMap em questão mantém um ponto de |
| 272 | +montagem que continuará referenciando este objeto após a remoção, é recomendado recriar |
| 273 | +estes pods. |
| 274 | + |
| 275 | +## {{% heading "whatsnext" %}} |
| 276 | + |
| 277 | +* Leia sobre [Secrets](/docs/concepts/configuration/secret/) (em inglês). |
| 278 | +* Leia [Configure a Pod to Use a ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/) (em inglês). |
| 279 | +* Leia [The Twelve-Factor App](https://12factor.net/) (em inglês) para entender a motivação da separação de código |
| 280 | +e configuração. |
0 commit comments