Ir para o conteúdo principal

secret.yml

Descrição: este arquivo cria um Secret no Kubernetes.

Um Secret é usado para armazenar dados sensíveis, como senhas, tokens, chaves, certificados e credenciais, para que Pods e aplicações possam consumir essas informações sem que elas fiquem gravadas diretamente na imagem do container ou no manifesto do Deployment.

Secret é parecido com ConfigMap na forma de consumo, mas tem finalidade diferente: ConfigMap é para configuração não sensível; Secret é para dados sensíveis.

No arquivo de referência do cluster, o recurso aparece como:

Recurso: secrets
Tipo: Secret
Versão: v1

TIPO:       Secret
VERSÃO:    v1

DESCRIÇÃO:
    Secret contém dados secretos de um determinado tipo. O total de bytes dos valores no
    campo Data deve ser menor que MaxSecretSize bytes.

Quando usar Secret

Use Secret quando a aplicação precisa consumir dados sensíveis, como:

  • senha de banco de dados;
  • usuário de banco de dados;
  • token de API;
  • token OAuth;
  • chave privada;
  • certificado TLS;
  • chave TLS;
  • credencial de registry privado;
  • credencial SSH;
  • credencial de autenticação básica;
  • arquivo pequeno com informação sensível;
  • configuração sensível que não deve ficar em ConfigMap;
  • segredo usado por Pods, Deployments, Ingresses ou ServiceAccounts.

Exemplos comuns:

  • DB_PASSWORD;
  • DB_USER;
  • API_TOKEN;
  • JWT_SECRET;
  • OAUTH_CLIENT_SECRET;
  • tls.crt;
  • tls.key;
  • .dockerconfigjson;
  • ssh-privatekey;
  • username;
  • password.

Quando Secret não é o recurso indicado

Secret não é o melhor recurso quando o problema exige outro tipo de controle.

Necessidade Recurso mais indicado Motivo
Guardar configuração não sensível ConfigMap ConfigMap é o recurso próprio para configuração comum.
Executar aplicação Deployment Secret apenas armazena dados sensíveis.
Criar endereço interno estável para Pods Service Secret não expõe aplicação na rede.
Publicar por domínio HTTP/HTTPS Ingress Ingress publica Services por hostname e path.
Persistir dados da aplicação PersistentVolumeClaim Secret não é armazenamento persistente de aplicação.
Controlar CPU/memória ResourceQuota, LimitRange ou resources Secret não controla recursos computacionais.
Isolar rede entre aplicações NetworkPolicy Secret não controla tráfego.
Rodar tarefa pontual Job Secret não executa tarefas.
Rodar tarefa agendada CronJob Secret não agenda execução.
Guardar arquivo grande PVC, storage externo ou cofre próprio Secret tem limite de tamanho e não é repositório de arquivos.
Gerenciar segredos com rotação avançada e auditoria externa Cofre de segredos ou controlador específico Secret nativo é objeto Kubernetes; rotação externa depende de ferramenta adicional.

Uso em cenário de universidade

Em uma universidade, um Secret pode ser usado para proteger credenciais usadas por sistemas acadêmicos, administrativos, laboratoriais e de pesquisa.

Exemplos:

  • senha de banco de dados de um sistema interno;
  • token de API usado por uma aplicação de laboratório;
  • certificado TLS usado por um Ingress;
  • credencial para baixar imagem de registry privado;
  • chave SSH usada por uma automação específica;
  • credencial de integração entre sistemas;
  • segredo de sessão de uma aplicação web;
  • senha temporária de ambiente de homologação;
  • credencial de serviço para aplicação de pesquisa.

Uso recomendado em ambiente universitário:

  • um Namespace por projeto, sistema, disciplina, laboratório ou ambiente;
  • um Secret por aplicação ou finalidade;
  • um ConfigMap separado para dados não sensíveis;
  • um Deployment consumindo o Secret por env, envFrom ou volume;
  • um Ingress referenciando Secret TLS quando usar HTTPS;
  • imagePullSecrets para registry privado;
  • RBAC restritivo para leitura de Secrets;
  • evitar dar permissão ampla de get, list e watch em Secrets;
  • evitar colocar Secret em repositório Git em texto puro;
  • usar solução segura para GitOps com segredos quando o ambiente exigir;
  • habilitar criptografia em repouso no cluster quando possível;
  • usar tokens de ServiceAccount de curta duração quando aplicável;
  • usar immutable: true quando o segredo não deve mudar em runtime.

Exemplo completo: secret.yml

apiVersion: v1
kind: Secret

metadata:
  name: minha-aplicacao-secret
  namespace: meu-projeto
  labels:
    app: minha-aplicacao
    ambiente: homologacao
    componente: segredo
  annotations:
    descricao: "Secret exemplo para dados sensíveis da aplicação"

type: Opaque
immutable: false

stringData:
  DB_USER: "usuario_app"
  DB_PASSWORD: "senha-exemplo"
  API_TOKEN: "token-exemplo"

data:
  JWT_SECRET: "c2VncmVkby1qd3Q="

Explicação linha por linha

apiVersion: v1

Define a versão da API usada pelo manifesto.

Para Secret, normalmente é:

apiVersion: v1

Significado:

  • v1: versão estável da API core do Kubernetes.

Use exatamente v1 para Secret.


kind: Secret

Define o tipo de recurso que será criado.

kind: Secret

Significado:

  • Secret: recurso que armazena dados sensíveis para consumo por Pods e outros recursos.

Não confundir com:

  • ConfigMap: guarda configuração não sensível;
  • Deployment: cria e atualiza Pods;
  • Service: expõe Pods na rede;
  • Ingress: publica Services por HTTP/HTTPS;
  • PersistentVolumeClaim: fornece armazenamento persistente;
  • ServiceAccount: identidade usada por Pods para acessar a API Kubernetes.

metadata

metadata identifica e organiza o Secret.

metadata:
  name: minha-aplicacao-secret
  namespace: meu-projeto
  labels:
    app: minha-aplicacao
  annotations:
    descricao: "Secret exemplo"

metadata.name

Nome do Secret.

name: minha-aplicacao-secret

Uso:

  • identifica o recurso dentro do namespace;
  • aparece em kubectl get secrets;
  • é referenciado por Pods, Deployments, Ingresses e outros recursos;
  • deve ser único dentro do namespace.

Exemplos bons:

name: portal-academico-secret
name: api-pesquisa-secret
name: backend-laboratorio-secret
name: registry-credencial
name: app-web-tls

Regras práticas:

  • use letras minúsculas;
  • use hífen;
  • evite acentos;
  • evite espaços;
  • escolha nome curto e claro;
  • use sufixo -secret quando ajudar na padronização;
  • use sufixo -tls para certificado TLS quando fizer sentido.

metadata.namespace

Namespace onde o Secret será criado.

namespace: meu-projeto

Uso:

  • separa segredos por projeto;
  • evita mistura entre ambientes;
  • permite ter Secrets com o mesmo nome em namespaces diferentes;
  • ajuda em RBAC, isolamento e organização.

Regra importante:

  • o Pod, Deployment ou Ingress que consome o Secret normalmente precisa estar no mesmo namespace do Secret.

Se omitir:

  • Kubernetes usa o namespace atual do contexto;
  • em produção isso pode causar Secret no namespace errado.

Recomendação:

  • sempre declarar namespace.

metadata.labels

Labels são pares chave/valor usados para organização e filtros.

labels:
  app: minha-aplicacao
  ambiente: homologacao
  componente: segredo

Uso:

  • filtrar Secrets com kubectl;
  • organizar recursos;
  • permitir automações;
  • associar recursos ao mesmo sistema;
  • ajudar ferramentas de inventário e GitOps.

Exemplo:

kubectl get secrets -l app=minha-aplicacao

Boas labels:

app: minha-aplicacao
ambiente: producao
componente: segredo

Evite usar label com dado sensível.


metadata.annotations

Annotations são metadados livres.

annotations:
  descricao: "Secret da aplicação"

Uso:

  • documentação;
  • configuração de ferramentas;
  • automações;
  • rastreabilidade;
  • integração com GitOps ou controladores.

Diferença entre labels e annotations:

Campo Uso
labels seleção, filtro e organização
annotations informação extra e configuração de ferramentas

Cuidado:

  • não coloque senha, token ou chave em annotation;
  • annotations também ficam armazenadas no objeto Kubernetes.

Campos de metadata normalmente gerenciados pelo Kubernetes

O kubectl explain mostra vários campos de metadata, mas muitos são preenchidos pelo próprio cluster.

Normalmente você não escreve manualmente:

creationTimestamp:
deletionTimestamp:
resourceVersion:
uid:
generation:
managedFields:
selfLink:

Eles servem para controle interno do Kubernetes.


type

Define o tipo do Secret.

type: Opaque

O tipo informa ao Kubernetes e às ferramentas qual formato de dado aquele Secret representa.

Tipos comuns:

Opaque
kubernetes.io/service-account-token
kubernetes.io/dockercfg
kubernetes.io/dockerconfigjson
kubernetes.io/basic-auth
kubernetes.io/ssh-auth
kubernetes.io/tls
bootstrap.kubernetes.io/token

Opaque

Tipo genérico de Secret.

type: Opaque

Uso:

  • senha de banco;
  • token de API;
  • segredo de sessão;
  • chave de aplicação;
  • credenciais genéricas.

É o tipo mais comum para segredos de aplicação.

Exemplo:

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: meu-projeto
type: Opaque
stringData:
  DB_USER: "usuario"
  DB_PASSWORD: "senha"

kubernetes.io/tls

Tipo usado para certificado e chave TLS.

type: kubernetes.io/tls

Chaves esperadas:

tls.crt
tls.key

Uso:

  • TLS em Ingress;
  • certificado usado por aplicação;
  • certificado usado por outro recurso compatível.

Exemplo:

apiVersion: v1
kind: Secret
metadata:
  name: app-web-tls
  namespace: meu-projeto
type: kubernetes.io/tls
stringData:
  tls.crt: |
    -----BEGIN CERTIFICATE-----
    CONTEUDO_DO_CERTIFICADO
    -----END CERTIFICATE-----
  tls.key: |
    -----BEGIN PRIVATE KEY-----
    CONTEUDO_DA_CHAVE
    -----END PRIVATE KEY-----

Cuidado:

  • a chave privada é sensível;
  • não versionar em texto puro em repositório comum;
  • o certificado precisa corresponder ao hostname usado no Ingress.

kubernetes.io/dockerconfigjson

Tipo usado para credenciais de registry de container.

type: kubernetes.io/dockerconfigjson

Chave esperada:

.dockerconfigjson

Uso:

  • baixar imagem de registry privado;
  • autenticar em registry institucional;
  • autenticar em registry de CI/CD.

Exemplo conceitual:

apiVersion: v1
kind: Secret
metadata:
  name: registry-credencial
  namespace: meu-projeto
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: "BASE64_DO_CONFIG_JSON"

Consumo no Deployment:

imagePullSecrets:
  - name: registry-credencial

kubernetes.io/dockercfg

Tipo antigo para credencial Docker.

type: kubernetes.io/dockercfg

Chave esperada:

.dockercfg

Uso:

  • compatibilidade com formato antigo de configuração Docker.

Recomendação prática:

  • prefira kubernetes.io/dockerconfigjson em ambientes modernos.

kubernetes.io/basic-auth

Tipo usado para autenticação básica.

type: kubernetes.io/basic-auth

Chaves esperadas:

username
password

Exemplo:

apiVersion: v1
kind: Secret
metadata:
  name: basic-auth-secret
  namespace: meu-projeto
type: kubernetes.io/basic-auth
stringData:
  username: "usuario"
  password: "senha"

kubernetes.io/ssh-auth

Tipo usado para credencial SSH.

type: kubernetes.io/ssh-auth

Chave esperada:

ssh-privatekey

Exemplo:

apiVersion: v1
kind: Secret
metadata:
  name: ssh-secret
  namespace: meu-projeto
type: kubernetes.io/ssh-auth
stringData:
  ssh-privatekey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    CONTEUDO_DA_CHAVE
    -----END OPENSSH PRIVATE KEY-----

Cuidado:

  • chave privada SSH é altamente sensível;
  • evite armazenar em repositório;
  • limite rigidamente quem pode ler esse Secret.

kubernetes.io/service-account-token

Tipo usado para token de ServiceAccount.

type: kubernetes.io/service-account-token

Uso:

  • mecanismo legado para tokens de longa duração de ServiceAccount.

Cuidado:

  • em versões modernas, a recomendação é usar tokens de curta duração via TokenRequest API ou kubectl create token;
  • só crie Secret desse tipo quando houver necessidade real de token de longa duração e você aceitar o risco de segurança.

Exemplo conceitual:

apiVersion: v1
kind: Secret
metadata:
  name: token-service-account
  namespace: meu-projeto
  annotations:
    kubernetes.io/service-account.name: "minha-service-account"
type: kubernetes.io/service-account-token

bootstrap.kubernetes.io/token

Tipo usado para token de bootstrap de cluster.

type: bootstrap.kubernetes.io/token

Uso:

  • processos de bootstrap;
  • entrada de nós no cluster;
  • cenários administrativos específicos.

Não é usado normalmente por aplicações.


data

data armazena dados sensíveis codificados em base64.

data:
  DB_PASSWORD: "c2VuaGEtZXhlbXBsbw=="

Formato:

chave: valor-em-base64

Uso:

  • representar bytes;
  • armazenar conteúdo já codificado;
  • compatibilidade com YAML aplicado diretamente.

Regra importante:

base64 não é criptografia.

Base64 apenas codifica o valor para transporte/armazenamento no manifesto.

Exemplo:

echo -n "senha-exemplo" | base64

Resultado:

c2VuaGEtZXhlbXBsbw==

Manifesto:

data:
  DB_PASSWORD: "c2VuaGEtZXhlbXBsbw=="

Cuidado:

  • qualquer pessoa com acesso de leitura ao Secret consegue recuperar o valor;
  • use RBAC restritivo;
  • evite armazenar Secrets em Git em texto puro;
  • considere criptografia em repouso no cluster.

stringData

stringData permite escrever valores em texto claro no manifesto.

stringData:
  DB_USER: "usuario"
  DB_PASSWORD: "senha"

Uso:

  • facilitar criação manual;
  • evitar codificar base64 manualmente;
  • o Kubernetes converte os valores para data.

Cuidado:

  • stringData é uma conveniência de escrita;
  • ao consultar o Secret depois, o valor aparece em data codificado em base64;
  • não use stringData em repositório Git sem proteção adequada;
  • a documentação informa que stringData não funciona bem com server-side apply.

Exemplo:

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: meu-projeto
type: Opaque
stringData:
  DB_PASSWORD: "senha-exemplo"

Diferença entre data e stringData

Campo Como escreve Como o Kubernetes armazena
data base64 base64
stringData texto claro no manifesto convertido para data

Exemplo com stringData:

stringData:
  SENHA: "abc123"

Exemplo equivalente com data:

data:
  SENHA: "YWJjMTIz"

Recomendação prática:

  • para criação manual temporária, stringData é mais simples;
  • para manifesto gerado por ferramenta, data pode ser usado;
  • para GitOps, use ferramenta segura de gestão de Secrets, não segredo em texto puro.

immutable

Define se o conteúdo do Secret pode ser alterado depois de criado.

immutable: false

Valores:

immutable: true
immutable: false

immutable: false

Permite alterar data e stringData.

immutable: false

Uso:

  • segredo que pode mudar;
  • ambiente de desenvolvimento;
  • homologação;
  • Secrets simples.

Também pode ser omitido quando não houver necessidade de imutabilidade.


immutable: true

Impede alteração futura dos dados do Secret.

immutable: true

Uso:

  • segredo versionado;
  • produção;
  • evitar mudanças acidentais;
  • melhorar previsibilidade do ambiente;
  • reduzir risco de alteração indevida.

Cuidado:

  • depois de marcado como imutável, não é possível voltar para mutável;
  • não é possível alterar os dados do Secret;
  • para mudar o segredo, crie outro Secret ou delete e recrie o objeto;
  • Pods que montam o Secret antigo podem continuar referenciando o conteúdo antigo até serem atualizados/recriados.

kind

O campo kind já aparece no topo do manifesto.

kind: Secret

Ele indica que este objeto é um Secret.


apiVersion

O campo apiVersion já aparece no topo do manifesto.

apiVersion: v1

Ele indica que este objeto usa a API core v1.


Como consumir Secret em um Deployment

Um Secret sozinho não altera uma aplicação.

Ele precisa ser consumido por um Pod, normalmente dentro de um Deployment.


Consumo com env

Use env quando quiser escolher chaves específicas.

env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: minha-aplicacao-secret
        key: DB_PASSWORD

Uso:

  • importar uma chave específica;
  • controlar exatamente quais segredos entram no container;
  • evitar expor mais dados do que a aplicação precisa.

Consumo com envFrom

Use envFrom quando quiser importar todas as chaves como variáveis de ambiente.

envFrom:
  - secretRef:
      name: minha-aplicacao-secret

Uso:

  • várias variáveis sensíveis;
  • aplicações que já leem configuração por ambiente.

Cuidado:

  • todas as chaves viram variáveis de ambiente;
  • pode expor mais segredos do que o necessário;
  • processos e ferramentas internas podem conseguir listar variáveis de ambiente dependendo do ambiente.

Consumo como volume

Use volume quando a aplicação espera arquivo sensível.

volumes:
  - name: segredo
    secret:
      secretName: minha-aplicacao-secret

containers:
  - name: app
    volumeMounts:
      - name: segredo
        mountPath: /app/secret
        readOnly: true

Uso:

  • certificado;
  • chave privada;
  • arquivo de credencial;
  • configuração sensível em arquivo.

Resultado dentro do container:

/app/secret/DB_PASSWORD
/app/secret/API_TOKEN

Consumo como imagePullSecrets

Use imagePullSecrets quando o Secret serve para autenticar em registry privado.

imagePullSecrets:
  - name: registry-credencial

Uso:

  • baixar imagem privada;
  • autenticar em registry institucional;
  • autenticar em registry usado pelo CI/CD.

O Secret normalmente é do tipo:

type: kubernetes.io/dockerconfigjson

Consumo por Ingress TLS

Use Secret TLS quando o Ingress precisa servir HTTPS.

Secret:

apiVersion: v1
kind: Secret
metadata:
  name: app-web-tls
  namespace: meu-projeto
type: kubernetes.io/tls
stringData:
  tls.crt: |
    -----BEGIN CERTIFICATE-----
    CONTEUDO_DO_CERTIFICADO
    -----END CERTIFICATE-----
  tls.key: |
    -----BEGIN PRIVATE KEY-----
    CONTEUDO_DA_CHAVE
    -----END PRIVATE KEY-----

Ingress:

tls:
  - hosts:
      - app-web.exemplo.local
    secretName: app-web-tls

Regra importante:

  • o Secret TLS precisa estar no mesmo namespace do Ingress.

Observações sobre atualização

Alterar um Secret não significa que toda aplicação consumidora será reiniciada automaticamente.

Quando usado como variável de ambiente

Se o Secret é consumido por env ou envFrom:

  • o valor é definido na criação do Pod;
  • Pods existentes não recebem automaticamente a nova variável;
  • normalmente é necessário reiniciar o Deployment ou recriar os Pods.

Comando comum:

kubectl rollout restart deployment/minha-aplicacao -n meu-projeto

Quando usado como volume

Se o Secret é montado como volume:

  • o conteúdo projetado no volume pode ser atualizado pelo kubelet;
  • a aplicação precisa ser capaz de reler o arquivo;
  • se a aplicação só lê o arquivo na inicialização, pode ser necessário reiniciar o Pod.

Cuidado:

  • Secret montado usando subPath não recebe atualizações automáticas do volume projetado.

Limite de tamanho

Secret não deve ser usado para dados grandes.

Regra prática:

  • use Secret para segredos pequenos;
  • evite arquivos grandes;
  • evite dumps;
  • evite binários grandes;
  • para arquivos grandes, use solução própria de armazenamento ou cofre de segredos.

O limite documentado para um Secret individual é de até 1 MiB.


Segurança

Secret melhora a separação entre aplicação e credencial, mas não elimina a necessidade de segurança no cluster.

Boas práticas:

  • restringir RBAC;
  • evitar permissões amplas de get, list e watch em Secrets;
  • limitar acesso por namespace;
  • evitar colocar Secret em repositório Git em texto puro;
  • habilitar criptografia em repouso no cluster quando possível;
  • usar tokens de curta duração quando possível;
  • evitar montar todos os Secrets em todos os Pods;
  • consumir apenas as chaves necessárias;
  • usar automountServiceAccountToken: false quando o Pod não precisa acessar a API Kubernetes;
  • rotacionar credenciais periodicamente;
  • revisar quem consegue ler Secrets no cluster.

Cuidado importante:

Qualquer usuário, ServiceAccount ou processo com permissão para ler um Secret pode obter seu conteúdo.

status

Secret não possui uma seção status no manifesto de referência.

Você normalmente trabalha com:

apiVersion
kind
metadata
data
stringData
immutable
type

Para ver o objeto aplicado:

kubectl get secret minha-aplicacao-secret -n meu-projeto -o yaml

Manifesto mínimo funcional

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: meu-projeto
type: Opaque
stringData:
  DB_PASSWORD: "senha-exemplo"

Aplicar:

kubectl apply -f secret.yml

Verificar:

kubectl get secret app-secret -n meu-projeto
kubectl describe secret app-secret -n meu-projeto

Manifesto recomendado para aplicação web simples

apiVersion: v1
kind: Secret
metadata:
  name: app-web-secret
  namespace: meu-projeto
  labels:
    app: app-web
    componente: segredo
type: Opaque
stringData:
  DB_USER: "usuario_app"
  DB_PASSWORD: "senha-exemplo"
  API_TOKEN: "token-exemplo"

Este modelo é adequado para uma aplicação web/API que recebe credenciais por variáveis de ambiente ou arquivos montados.

Cuidado:

  • este exemplo usa valores fictícios;
  • em produção, não grave segredos reais em repositório Git sem proteção adequada.

Manifesto usando data

apiVersion: v1
kind: Secret
metadata:
  name: app-web-secret
  namespace: meu-projeto
type: Opaque
data:
  DB_USER: "dXN1YXJpb19hcHA="
  DB_PASSWORD: "c2VuaGEtZXhlbXBsbw=="

Neste formato, os valores precisam estar em base64.

Gerar base64:

echo -n "senha-exemplo" | base64

Decodificar para conferir:

echo "c2VuaGEtZXhlbXBsbw==" | base64 -d

Manifesto com Secret imutável

apiVersion: v1
kind: Secret
metadata:
  name: app-web-secret-v1
  namespace: meu-projeto
  labels:
    app: app-web
type: Opaque
immutable: true
stringData:
  DB_PASSWORD: "senha-exemplo"

Uso:

  • segredo versionado;
  • produção;
  • evitar alteração acidental.

Para mudar:

  • crie outro Secret, por exemplo app-web-secret-v2;
  • atualize o Deployment para usar o novo nome;
  • faça rollout da aplicação;
  • remova o Secret antigo quando não estiver mais em uso.

Manifesto Secret TLS

apiVersion: v1
kind: Secret
metadata:
  name: app-web-tls
  namespace: meu-projeto
type: kubernetes.io/tls
stringData:
  tls.crt: |
    -----BEGIN CERTIFICATE-----
    CONTEUDO_DO_CERTIFICADO
    -----END CERTIFICATE-----
  tls.key: |
    -----BEGIN PRIVATE KEY-----
    CONTEUDO_DA_CHAVE
    -----END PRIVATE KEY-----

Uso comum:

  • Ingress HTTPS;
  • aplicação que precisa ler certificado e chave;
  • terminação TLS feita pelo Ingress Controller.

Manifesto Secret para registry privado

apiVersion: v1
kind: Secret
metadata:
  name: registry-credencial
  namespace: meu-projeto
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: "BASE64_DO_DOCKER_CONFIG_JSON"

Consumo no Deployment:

imagePullSecrets:
  - name: registry-credencial

Comando comum para criar esse tipo de Secret:

kubectl create secret docker-registry registry-credencial \
  -n meu-projeto \
  --docker-server=REGISTRY_EXEMPLO \
  --docker-username=USUARIO \
  --docker-password=SENHA \
  --docker-email=EMAIL

Cuidado:

  • comandos com senha podem ficar no histórico do shell;
  • prefira métodos seguros de criação em ambiente real.

Manifesto Secret de autenticação básica

apiVersion: v1
kind: Secret
metadata:
  name: basic-auth-secret
  namespace: meu-projeto
type: kubernetes.io/basic-auth
stringData:
  username: "usuario"
  password: "senha"

Uso:

  • cenários que esperam Secret com usuário e senha;
  • integrações específicas;
  • controladores que entendem esse tipo de Secret.

Manifesto Secret SSH

apiVersion: v1
kind: Secret
metadata:
  name: ssh-secret
  namespace: meu-projeto
type: kubernetes.io/ssh-auth
stringData:
  ssh-privatekey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    CONTEUDO_DA_CHAVE
    -----END OPENSSH PRIVATE KEY-----

Uso:

  • autenticação SSH;
  • integração específica que espera chave SSH.

Cuidado:

  • chave privada SSH deve ser rigidamente protegida;
  • limite quem pode ler esse Secret.

Exemplo de Deployment consumindo Secret por env

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-web
  namespace: meu-projeto
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-web
  template:
    metadata:
      labels:
        app: app-web
    spec:
      containers:
        - name: app
          image: registry.exemplo.local/projeto/app-web:1.0.0
          env:
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: app-web-secret
                  key: DB_PASSWORD

Exemplo de Deployment consumindo Secret por envFrom

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-web
  namespace: meu-projeto
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-web
  template:
    metadata:
      labels:
        app: app-web
    spec:
      containers:
        - name: app
          image: registry.exemplo.local/projeto/app-web:1.0.0
          envFrom:
            - secretRef:
                name: app-web-secret

Exemplo de Deployment consumindo Secret como volume

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-web
  namespace: meu-projeto
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-web
  template:
    metadata:
      labels:
        app: app-web
    spec:
      containers:
        - name: app
          image: registry.exemplo.local/projeto/app-web:1.0.0
          volumeMounts:
            - name: segredo
              mountPath: /app/secret
              readOnly: true
      volumes:
        - name: segredo
          secret:
            secretName: app-web-secret

Comandos úteis

Aplicar

kubectl apply -f secret.yml

Ver Secrets

kubectl get secrets -n meu-projeto

Ver Secret específico

kubectl get secret minha-aplicacao-secret -n meu-projeto

Ver detalhes

kubectl describe secret minha-aplicacao-secret -n meu-projeto

Ver YAML real aplicado

kubectl get secret minha-aplicacao-secret -n meu-projeto -o yaml

Criar Secret genérico por literal

kubectl create secret generic minha-aplicacao-secret \
  -n meu-projeto \
  --from-literal=DB_USER=usuario \
  --from-literal=DB_PASSWORD=senha

Cuidado:

  • valores passados por linha de comando podem ficar no histórico do shell.

Criar Secret a partir de arquivo

kubectl create secret generic minha-aplicacao-secret \
  -n meu-projeto \
  --from-file=credencial.txt

Criar Secret TLS

kubectl create secret tls app-web-tls \
  -n meu-projeto \
  --cert=certificado.pem \
  --key=chave.pem

Criar Secret para registry privado

kubectl create secret docker-registry registry-credencial \
  -n meu-projeto \
  --docker-server=REGISTRY_EXEMPLO \
  --docker-username=USUARIO \
  --docker-password=SENHA \
  --docker-email=EMAIL

Decodificar uma chave de Secret

kubectl get secret minha-aplicacao-secret \
  -n meu-projeto \
  -o jsonpath='{.data.DB_PASSWORD}' | base64 -d

Reiniciar Deployment após mudança em Secret

kubectl rollout restart deployment/minha-aplicacao -n meu-projeto

Ver quem pode ler Secrets

kubectl auth can-i get secrets -n meu-projeto
kubectl auth can-i list secrets -n meu-projeto

Relação com outros manifestos

Um Secret normalmente faz parte de um conjunto de manifestos.

Uso típico:

Namespace
  ├── ConfigMap
  ├── Secret
  ├── ServiceAccount
  ├── Deployment
  ├── Service
  ├── Ingress
  ├── NetworkPolicy
  ├── ResourceQuota
  └── LimitRange

Secret + Deployment

Secret fornece dados sensíveis.

Deployment consome esses dados nos Pods.

Secret + ConfigMap

Secret guarda dados sensíveis.

ConfigMap guarda dados não sensíveis.

Secret + Ingress

Secret TLS guarda certificado e chave.

Ingress referencia esse Secret em spec.tls.secretName.

Secret + imagePullSecrets

Secret do tipo kubernetes.io/dockerconfigjson permite baixar imagem privada.

Deployment referencia o Secret em imagePullSecrets.

Secret + Volume

Secret pode ser montado como arquivos dentro do container.

Secret + env/envFrom

Secret pode virar variável de ambiente no container.

Secret + RBAC

RBAC controla quem pode ler, listar, observar, criar, alterar ou apagar Secrets.


Erros comuns

Colocar segredo em ConfigMap

Errado:

kind: ConfigMap
data:
  DB_PASSWORD: "senha"

Correto:

kind: Secret
stringData:
  DB_PASSWORD: "senha"

Achar que base64 é criptografia

Errado:

Está em base64, então está seguro.

Correto:

Base64 é apenas codificação. Quem pode ler o Secret pode decodificar o valor.

Secret no namespace errado

Sintoma:

  • Deployment referencia Secret;
  • Pod não inicia;
  • evento mostra Secret não encontrado.

Verificar:

kubectl get secret -A | grep minha-aplicacao-secret
kubectl describe pod -n meu-projeto POD

Correção:

  • criar o Secret no mesmo namespace do Deployment/Pod;
  • ou corrigir o namespace do manifesto.

Chave inexistente

Errado:

env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: app-secret
        key: DB_PASS

Mas no Secret existe:

stringData:
  DB_PASSWORD: "senha"

Correção:

key: DB_PASSWORD

Alterar Secret e esperar que env mude em Pods já existentes

Quando o Secret é consumido como variável de ambiente, Pods existentes não recebem automaticamente o novo valor.

Depois de alterar:

kubectl rollout restart deployment/minha-aplicacao -n meu-projeto

TLS Secret com chaves erradas

Para kubernetes.io/tls, as chaves esperadas são:

tls.crt
tls.key

Errado:

stringData:
  certificado: "..."
  chave: "..."

Correto:

stringData:
  tls.crt: "..."
  tls.key: "..."

Docker registry Secret com chave errada

Para kubernetes.io/dockerconfigjson, a chave esperada é:

.dockerconfigjson

Errado:

data:
  dockerconfigjson: "..."

Correto:

data:
  .dockerconfigjson: "..."

Usar subPath esperando atualização automática

Quando Secret é montado com subPath, atualizações do Secret não são refletidas automaticamente naquele arquivo montado.

Se precisa atualização dinâmica:

  • monte o Secret como volume normal;
  • ou reinicie os Pods após alteração.

Criar Secret imutável e tentar editar depois

Se immutable: true, não é possível alterar os dados do Secret.

Solução:

  • criar novo Secret com outro nome;
  • atualizar o Deployment;
  • fazer rollout;
  • remover o Secret antigo quando não estiver mais em uso.

Dar permissão ampla para Secrets

Cuidado com permissões como:

resources:
  - secrets
verbs:
  - get
  - list
  - watch

Essas permissões podem permitir leitura ampla de dados sensíveis.

Recomendação:

  • conceder apenas o mínimo necessário;
  • evitar list e watch quando não forem essenciais;
  • limitar por namespace;
  • revisar Roles e RoleBindings.

Checklist para uso em produção

Antes de aplicar um Secret em ambiente compartilhado:

  • namespace definido;
  • name claro;
  • labels claras;
  • contém apenas dados realmente sensíveis;
  • configuração não sensível foi colocada em ConfigMap;
  • type adequado ao uso;
  • chaves de data estão em base64 válido;
  • stringData não será versionado em texto puro sem proteção;
  • Secret está no mesmo namespace do Pod/Deployment/Ingress que o usa;
  • Deployment referencia o Secret correto;
  • Ingress TLS referencia Secret TLS correto;
  • Secret TLS usa tls.crt e tls.key;
  • registry Secret usa .dockerconfigjson;
  • Secret não ultrapassa limite de tamanho;
  • RBAC restringe leitura de Secrets;
  • ServiceAccounts têm permissões mínimas;
  • tokens de longa duração foram evitados quando possível;
  • criptografia em repouso foi considerada no cluster;
  • estratégia de rotação de segredo existe;
  • mudança em Secret tem estratégia de rollout;
  • immutable: true foi usado apenas quando faz sentido;
  • o segredo real não foi exposto em commit, log ou histórico de shell.

Resumo

Use Secret para armazenar dados sensíveis consumidos por Pods e outros recursos Kubernetes.

O Secret controla:

  • pares chave/valor sensíveis;
  • dados codificados em base64 no campo data;
  • escrita simplificada em texto pelo campo stringData;
  • tipos específicos de segredo pelo campo type;
  • imutabilidade opcional com immutable;
  • consumo por variáveis de ambiente;
  • consumo por arquivos em volume;
  • credenciais de registry privado;
  • certificados TLS para Ingress.

Para aplicação web comum, o conjunto mínimo geralmente é:

Namespace + ConfigMap + Secret + Deployment + Service + Ingress

Para ambiente institucional compartilhado, o conjunto recomendado é:

Namespace + ResourceQuota + LimitRange + ServiceAccount + Role/RoleBinding
+ ConfigMap + Secret + Deployment + Service + Ingress + NetworkPolicy + PDB