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 * * 0para 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→ ilimitado10→ máximo de 10 GB50→ 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
| Campo | Valor |
|---|---|
| Name | kubernetes-pull |
| Expiration | 365 dias (ou conforme política da empresa) |
| Permissions | apenas 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ção | Valor sugerido | Objetivo |
|---|---|---|
| Retenção por repositório | últimas 10 imagens | Evitar acúmulo |
| Retenção de tags de release | sempre (v*..) | Preservar versões em produção |
| Retenção de branches | últimas 3 | Limpeza de feature branches |
| GC agendado | todo domingo às 2h | Recuperar espaço regularmente |
| Imutabilidade | v*.. | Proteger releases |
| Quota por projeto | conforme necessidade | Evitar monopolização do storage |
| Robot Account CI/CD | push + pull, 365 dias | Pipeline |
| Robot Account Kubernetes | pull apenas, 365 dias | Cluster |
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.