ConfigMaps & Secrets
Injete configurações e segredos em pods Node.js como variáveis de ambiente ou arquivos sem incorporar valores em imagens Docker.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
data:
LOG_LEVEL: info
API_BASE_URL: https://api.acme.dev
---
apiVersion: v1
kind: Secret
metadata:
name: api-secrets
type: Opaque
stringData:
DATABASE_URL: postgres://user:pass@db:5432/appcontainers:
- name: api
envFrom:
- configMapRef:
name: api-config
- secretRef:
name: api-secretsQuando usar isso: Toda Implantação Kubernetes. Configuração não secreta em ConfigMap; credenciais em Secret (ou operador de segredo externo).
Exemplo de Trabalho
# k8s/config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
data:
NODE_ENV: production
PORT: "3000"
LOG_LEVEL: info
FEATURE_EXPORT_CSV: "false"
---
apiVersion: v1
kind: Secret
metadata:
name: api-secrets
type: Opaque
stringData:
DATABASE_URL: postgres://app:CHANGE_ME@postgres:5432/app
JWT_SECRET: CHANGE_ME
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
template:
spec:
containers:
- name: api
image: ghcr.io/acme/api:sha-abc123
envFrom:
- configMapRef:
name: api-config
- secretRef:
name: api-secrets
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name// src/env.ts
import { z } from "zod";
const schema = z.object({
NODE_ENV: z.enum(["development", "production", "test"]),
PORT: z.coerce.number().default(3000),
LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
FEATURE_EXPORT_CSV: z.coerce.boolean().default(false),
POD_NAME: z.string().optional(),
});
export const env = schema.parse(process.env);O que isso demonstra:
- Alternadores não sensíveis em ConfigMap
- Segredos como variáveis de ambiente (simples) analisados por Zod na inicialização
- API Downward
POD_NAMEpara logs estruturados
Mergulho Profundo
Decisão Config vs Secret
| Dados | Armazenar em | Exemplo |
|---|---|---|
| Nível de log, flags de recursos | ConfigMap | LOG_LEVEL=info |
| URL do DB, chaves de API | Secret | DATABASE_URL |
| Certificados TLS | Secret (tipo tls) ou cert-manager | Ingress TLS |
| ID do cliente OAuth público | ConfigMap | id não sensível |
Nunca coloque segredos em ConfigMap (base64 não é criptografia).
Padrão de Montagem de Arquivo
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
volumes:
- name: config
projected:
sources:
- configMap:
name: api-config
- secret:
name: api-secretsimport { readFileSync } from "node:fs";
const jwtSecret = readFileSync("/app/config/JWT_SECRET", "utf8").trim();Arquivos evitam limites de tamanho de variável de ambiente e reduzem o log acidental de env. O aplicativo deve ler os arquivos na inicialização.
Operador de Segredos Externos
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: api-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-ssm
kind: ClusterSecretStore
target:
name: api-secrets
data:
- secretKey: DATABASE_URL
remoteRef:
key: /prod/api/DATABASE_URLSincroniza AWS SSM em K8s Secret automaticamente. Veja Gerenciadores de Segredos.
Equivalente ECS
"secrets": [
{
"name": "DATABASE_URL",
"valueFrom": "arn:aws:ssm:us-east-1:123:parameter/prod/api/DATABASE_URL"
}
]Cloud Run: --set-secrets DATABASE_URL=api-database-url:latest.
Armadilhas
- Segredo na
ENVda imagem - vazamento no histórico da camada. Correção: apenas injeção do orquestrador. - Log de
process.envna inicialização - vazamento de credenciais. Correção: registrar apenas chaves, nunca valores. - Mudança de ConfigMap sem rollout - pods mantêm env obsoleto até a reinicialização. Correção: Sidecar Reloader ou acionar rollout na alteração da configuração.
- ConfigMap gigante como env - limite de 1 MiB por fonte de env. Correção: montagens de arquivos ou divisão da configuração.
- Mesmo Secret para dev e prod - raio de explosão. Correção: segredos com escopo de namespace por ambiente.
- JWT em ConfigMap - tipo de armazenamento incorreto. Correção: Secret com RBAC limitado à conta de serviço.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| envFrom ConfigMap + Secret | Simples apps Node 12-factor | Árvores de configuração enormes |
| Volumes Projetados | Misturar arquivos + env | Pequenos serviços de env único |
| Operador de Segredos Externos | Fonte de verdade SSM/Vault | Sem administrador de cluster para CRDs |
| Doppler / Agente Vault | Plataforma de segredos centralizada | Lojas nativas de K8s apenas |
FAQs
Segredos do Kubernetes são criptografados?
A criptografia em repouso depende da configuração do cluster (envelope KMS). RBAC ainda é necessário; trate como sensível.
Como rotacionamos DATABASE_URL?
Atualize SSM/ExternalSecret, reinicie o Deployment em rollout. Use pools de conexão que se recuperam em erro de autenticação.
Flags de recursos em ConfigMap?
Sim para flags de env booleanas. Sistemas de flags complexos usam LaunchDarkly ou SDK semelhante, não ConfigMaps gigantes.
`.env` no dev local?
dotenv apenas para laptop. Produção usa nomes de paridade ConfigMap/Secret - Noções Básicas de Configuração.
NestJS ConfigModule pode ler arquivos?
Sim. ConfigModule.forRoot({ envFilePath: undefined }) depende de env injetado em produção.
Quem pode ler Segredos?
RBAC: apenas api ServiceAccount no namespace production via RoleBinding.
Relacionados
- Gerenciadores de Segredos - busca SSM e Vault
- Noções Básicas de Configuração - módulo de env Zod
- Implantação Kubernetes - montar em Implantação
- ECS Fargate & Cloud Run - injeção de segredo AWS/GCP
- Melhores Práticas de Implantação de Plataforma - lista de verificação da seção
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, e NestJS 11.