Skip to main content

Harbor na Prática — Parte 6 Retenção de Imagens, Quotas e Token Apenas para Pull

Nesta parte, vamos configurar políticas de retenção para controlar a quantidade de imagens armazenadas, definir quotas de storage por projeto e criar tokens com permissão apenas de pull para uso seguro em clusters Kubernetes.


Por que limitar imagens e storage?

Sem nenhum controle, um registry cresce indefinidamente. Cada pipeline que roda cria uma nova tag — em projetos ativos, isso significa centenas de imagens por mês. Os problemas são:

  • Storage caro — imagens antigas que ninguém usa continuam ocupando espaço
  • Confusão operacional — difícil identificar qual versão usar quando há 300 tags
  • Segurança — imagens antigas têm mais vulnerabilidades conhecidas

As ferramentas para resolver isso no Harbor são: Políticas de Retenção, Imutabilidade de Tags e Quotas de Projeto.


Políticas de Retenção de Imagens

As políticas de retenção definem automaticamente quais imagens manter e quais remover. São configuradas por projeto.

Configurando via Interface Web

Acesse o projeto → Policy → Tag Retention → Add Rule.

Você pode criar múltiplas regras. O Harbor aplica todas e mantém qualquer imagem que seja preservada por ao menos uma regra.

Exemplos de regras comuns

Manter as últimas 10 versões de qualquer repositório:

Repositories matching: **
Tags matching: **
Rule: retain the most recently pushed # artifacts: 10

Manter apenas tags de release (v..*) indefinidamente:**

Repositories matching: **
Tags matching: v*.*.*
Rule: retain always

Manter as últimas 5 tags de branches de feature:

Repositories matching: **
Tags matching: feature-**
Rule: retain the most recently pushed # artifacts: 5

Manter imagens dos últimos 30 dias:

Repositories matching: **
Tags matching: **
Rule: retain artifacts pushed within the last 30 day(s)

Configurando via API

curl -X POST \
"https://harbor.empresa.com/api/v2.0/projects/backend/immutabletagrules" \
-H "Content-Type: application/json" \
-u "admin:suasenha" \
-d '{
"action": "retain",
"params": {
"latestPushedK": 10
},
"scope_selectors": {
"repository": [{"kind": "doublestar", "decoration": "repoMatches", "pattern": "**"}]
},
"tag_selectors": [
{"kind": "doublestar", "decoration": "matches", "pattern": "**"}
]
}'

Executando a política

A política pode ser executada:

  • Manualmente → Project → Policy → Tag Retention → Run Now
  • Agendada → configurando um cron na mesma tela (ex: 0 2 * * 0 para todo domingo às 2h)

⚠️ A execução da política de retenção marca as imagens para exclusão, mas não libera espaço imediatamente. O espaço só é recuperado após o Garbage Collection.

Garbage Collection

Acesse Administration → Garbage Collection → GC Now (ou configure agendamento).

O Garbage Collection remove os blobs órfãos — layers que não são mais referenciados por nenhum manifest. É seguro executar em produção; o Harbor bloqueia push/pull apenas durante os segundos de execução.

# Disparar GC via API
curl -X POST "https://harbor.empresa.com/api/v2.0/system/gc/schedule" \
-H "Content-Type: application/json" \
-u "admin:suasenha" \
-d '{"schedule": {"type": "Manual"}}'

Imutabilidade de Tags

A imutabilidade impede que uma tag existente seja sobrescrita por um novo push. Isso é crítico para tags de release — ninguém deve poder fazer docker push minha-api:v1.0.0 e substituir uma versão que já está em produção.

Configurando via Interface Web

Acesse o projeto → Policy → Tag Immutability → Add Rule.

Exemplo — proteger todas as tags de versão semântica:

Repositories matching: **
Tags matching: v*.*.*

Configurando via Terraform

resource "harbor_immutable_tag_rule" "releases" {
project_id = harbor_project.backend.id
repo_matching = "**"
tag_matching = "v*.*.*"
}

Quotas de Projeto

As quotas limitam o total de storage que um projeto pode consumir. Útil para evitar que um time monopolize o disco.

Configurando via Interface Web

Administration → Projects → clique no projeto → Edit → Storage Limit

  • -1 → ilimitado
  • 10 → máximo de 10 GB
  • 50 → máximo de 50 GB

Configurando via API

curl -X PUT "https://harbor.empresa.com/api/v2.0/quotas/<quota-id>" \
-H "Content-Type: application/json" \
-u "admin:suasenha" \
-d '{
"hard": {
"storage": 10737418240
}
}'

O valor é em bytes. Referência: 10 GB = 10737418240.

Verificar uso atual de quota

curl -s "https://harbor.empresa.com/api/v2.0/quotas?reference=project" \
-u "admin:suasenha" | jq '.[] | {project: .ref.name, used_gb: (.used.storage / 1073741824 | round), limit_gb: (.hard.storage / 1073741824 | round)}'

Token apenas para Pull — Robot Account com escopo mínimo

Esta é a configuração correta para o Kubernetes puxar imagens privadas do Harbor. O cluster não precisa de permissão de push — apenas pull.

Criar o Robot Account de pull

Via Interface Web:

Acesse o projeto → Robot Accounts → New Robot Account

CampoValor
Namekubernetes-pull
Expiration365 dias (ou conforme política da empresa)
Permissionsapenas Pull Repository

Via API:

curl -X POST \
"https://harbor.empresa.com/api/v2.0/projects/backend/robots" \
-H "Content-Type: application/json" \
-u "admin:suasenha" \
-d '{
"name": "kubernetes-pull",
"description": "Pull-only para clusters Kubernetes",
"duration": 365,
"permissions": [
{
"kind": "project",
"namespace": "backend",
"access": [
{"resource": "repository", "action": "pull"}
]
}
]
}'

Salve o name e o secret retornados — o secret não será exibido novamente.


Usando o token de pull no Kubernetes

Veja o próximo artigo (Parte 7) para a configuração completa. O resumo é:

# Criar o Secret no Kubernetes com as credenciais do Robot Account
kubectl create secret docker-registry harbor-pull-secret \
--docker-server=harbor.empresa.com \
--docker-username='robot$backend+kubernetes-pull' \
--docker-password='TOKEN_DO_ROBOT' \
--namespace=minha-app

Resumo das configurações recomendadas para produção

ConfiguraçãoValor sugeridoObjetivo
Retenção por repositórioúltimas 10 imagensEvitar acúmulo
Retenção de tags de releasesempre (v*..)Preservar versões em produção
Retenção de branchesúltimas 3Limpeza de feature branches
GC agendadotodo domingo às 2hRecuperar espaço regularmente
Imutabilidadev*..Proteger releases
Quota por projetoconforme necessidadeEvitar monopolização do storage
Robot Account CI/CDpush + pull, 365 diasPipeline
Robot Account Kubernetespull apenas, 365 diasCluster

Próximo artigo

Na Parte 7, vamos configurar a integração com o GitLab CI — fazendo login no Harbor dentro da pipeline, buildando imagens com Kaniko e fazendo push automaticamente a cada commit.