Pular para o conteúdo
NyverraNyverra
Artigos
⌘K
InícioArtigosSite institucional
🇧🇷

Nyverra

Canal editorial

Artigos sobre tecnologia, operações e parceiros — infraestrutura, monitoramento e ambientes críticos.

Explorar

  • Início
  • Artigos
  • Categorias
  • Tags
  • Autores
  • Sobre
  • Contato
  • RSS
  • Site institucional

© 2026 Nyverra. Todos os direitos reservados.

blog.nyverra.com

  1. Início
  2. Kubernetes
  3. Curso Kubernetes 24 — CI/CD: imagens imutáveis e SBOM
Kubernetes
#K8S#Kubernetes#Curso Kubernetes

Curso Kubernetes 24 — CI/CD: imagens imutáveis e SBOM

Wedson LopesWedson Lopes
30 de outubro de 20264 min de leitura

O deploy falha menos por Kubernetes e mais por artefato: imagem com tag mutável, build diferente por ambiente, dependência sem rastro. Este capítulo é sobre tornar o artefato confiável e rastreável.

Regra que resolve a maior parte: construa uma vez, promova o mesmo digest.

Selo do curso: testado com GitHub Actions, GHCR e Kubernetes 1.35.

Tag mutável é o problema

portal-backend:latest e até :v5 podem apontar para imagens diferentes amanhã. O pod rodando não é o pod que você testou.

Use:

  • sha-<commit> como tag principal.
  • Digest (@sha256:...) no deploy.
  • Sem latest em produção.
docker build -t ghcr.io/example/portal-backend:sha-$GIT_SHA .
docker push ghcr.io/example/portal-backend:sha-$GIT_SHA
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' ghcr.io/example/portal-backend:sha-$GIT_SHA | cut -d@ -f2)
echo "$DIGEST"

No manifest:

image: ghcr.io/example/portal-backend@sha256:2f0c...c91

Digest é imutável por construção.

Separe build de deploy

Etapa O que roda Ambiente
build teste, lint, imagem, scan runner
publish push + SBOM + assinatura runner
deploy homolog atualiza digest no GitOps ArgoCD
promove prod PR com o mesmo digest ArgoCD

O pipeline de prod não compila. Ele só troca o digest no repositório GitOps. Isso elimina "funcionou em homolog" por diferença de build.

Pipeline mínimo

name: build
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: ghcr.io/${{ github.repository }}:sha-${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Cache de build reduz minutos e, mais importante, torna o build reprodutível.

Scan de vulnerabilidade

trivy image --severity HIGH,CRITICAL --exit-code 1 \
  ghcr.io/example/portal-backend:sha-$GIT_SHA

Estruture o gate:

  • CRITICAL com correção disponível: bloqueia.
  • CRITICAL sem correção: registra e acompanha.
  • HIGH: alerta, não bloqueia no início.

Bloquear tudo no primeiro dia paralisa o time. O objetivo é reduzir, não travar.

SBOM

SBOM é a lista de componentes da imagem. Sem ela, você não responde "estamos afetados por Log4Shell?" em minutos.

syft ghcr.io/example/portal-backend:sha-$GIT_SHA -o spdx-json > sbom.spdx.json

Com Trivy:

trivy image --format spdx-json -o sbom.spdx.json ghcr.io/example/portal-backend:sha-$GIT_SHA

Publique o SBOM como artefato do pipeline e referencie no release. Formatos comuns: SPDX e CycloneDX.

Assinatura e proveniência

  • cosign assina a imagem.
  • SLSA provenance registra como ela foi construída.
  • Admission controller (Kyverno/cosign policy) recusa imagem não assinada.
cosign sign --yes ghcr.io/example/portal-backend@sha256:2f0c...c91
cosign verify ghcr.io/example/portal-backend@sha256:2f0c...c91 \
  --certificate-identity-regexp '.*' --certificate-oidc-issuer https://token.actions.githubusercontent.com

Isso fecha a cadeia: commit → build → assinatura → deploy.

O erro de segurança que já vimos

Um build passou porque o MinIO usava minioadmin como credencial padrão. O pipeline não validava configuração — só compilava. Resultado: deploy quebrado no cluster com INF-SEC-01.

Lição: o pipeline precisa de um gate de configuração, não só de teste unitário:

grep -rE 'minioadmin|changeme|password.*=.*(admin|123)' deploy/ && exit 1

Simples, e teria evitado o incidente.

Rastreabilidade: do pod ao commit

Padronize labels:

metadata:
  labels:
    app.kubernetes.io/name: portal-backend
    app.kubernetes.io/version: sha-3f9c1a
    org.opencontainers.image.revision: 3f9c1a...

Com isso:

kubectl -n portal get pod -l app.kubernetes.io/version=sha-3f9c1a

Você responde "qual pod roda o commit X" em segundos — e o inverso também.

Laboratório

  1. Configure um pipeline que gera sha-<commit> e faz push.
  2. Rode Trivy e veja o relatório.
  3. Gere o SBOM em SPDX e inspecione dependências.
  4. Troque o deploy para usar digest e confirme imageID no pod:
kubectl -n portal get pod -o jsonpath='{.items[*].status.containerStatuses[*].imageID}'
  1. Faça um commit que introduz uma credencial falsa e veja o gate falhar.
  2. Promova o mesmo digest de homolog para prod sem rebuild.

Erros comuns

Sintoma Causa
Prod diferente de homolog build separado por ambiente
ImagePullBackOff credencial de registry ou tag inexistente
Deploy “funcionou” e quebrou tag mutável reutilizada
SBOM não gerado etapa falhou silenciosamente
Scan bloqueia tudo severidade sem política de exceção
Imagem sem assinatura aceita falta admission policy
Rastreabilidade perdida imagem sem label de revisão

Checklist

  • [ ] Build único por commit.
  • [ ] Tag sha-<commit> e deploy por digest.
  • [ ] Nenhum latest em produção.
  • [ ] Scan com severidade e política definidas.
  • [ ] SBOM gerado e arquivado.
  • [ ] Assinatura e verificação (cosign/Kyverno).
  • [ ] Gate de configuração (credenciais padrão).
  • [ ] Labels de versão/revisão nos pods.
  • [ ] Promoção por PR no repo GitOps.

Glossário

  • digest: hash imutável da imagem.
  • SBOM: inventário de componentes.
  • SLSA: framework de integridade de build.
  • provenance: registro de como o artefato foi construído.
  • cosign: ferramenta de assinatura.
  • gate: etapa que bloqueia o pipeline.

Próximo

Artefato confiável e rastreável. Agora endurecer o cluster: RBAC, Pod Security Admission, NetworkPolicy e gestão de segredos.

Próximo: Curso Kubernetes 25 — Segurança: RBAC, PSA, NetworkPolicy e secrets

Compartilhar

Continuar a ler

Leia também

  • Kubernetes de Verdade — do zero ao cluster em produção
    Kubernetes

    Kubernetes de Verdade — do zero ao cluster em produção

    Uma trilha prática para entender, montar e operar um cluster Kubernetes — do primeiro pod ao failover do Postgres.

    30 de outubro de 20264 min de leitura
  • Curso Kubernetes 28 — DR e capstone: provar que o cluster volta
    Kubernetes

    Curso Kubernetes 28 — DR e capstone: provar que o cluster volta

    RPO, RTO e drills reais: cenários de desastre, runbook, restore medido e o capstone que fecha o curso com um cluster que se recupera.

    30 de outubro de 20265 min de leitura
  • Curso Kubernetes 27 — SLO/SLI, on-call e postmortem blameless
    Kubernetes

    Curso Kubernetes 27 — SLO/SLI, on-call e postmortem blameless

    O que prometer, como medir e o que fazer quando o erro estoura: SLI, SLO, error budget, alertas que acordam alguém e postmortem sem caça às bruxas.

    30 de outubro de 20264 min de leitura

Comentários

Ainda sem comentários

Seja o primeiro a compartilhar sua opinião sobre este artigo.

Deixe um comentário

Newsletter

Receba novos artigos

Inscreva-se para receber publicações do blog Nyverra no seu e-mail. Enviaremos um link de confirmação.

​