Harbor na Prática — Parte 5 Proxy Cache
Nesta parte, vamos configurar o Harbor como proxy cache para registries externos como Docker Hub, GCR e ECR — eliminando rate limits, acelerando pulls e reduzindo dependência de conectividade externa.
O problema que o Proxy Cache resolve
Quem trabalha com Kubernetes em escala já se deparou com estes cenários:
- Rate limit do Docker Hub — a partir de 100 pulls por 6 horas para IPs não autenticados (e 200 para contas gratuitas). Em clusters com muitos pods, isso causa falhas aleatórias no deploy.
- Latência — baixar a mesma imagem
python:3.12-slimrepetidamente do Docker Hub, da GCR ou da ECR é lento e desperdiça banda. - Dependência externa — se o Docker Hub tiver instabilidade (e acontece), seus deploys param.
O Harbor Proxy Cache resolve os três problemas de uma vez.
Como funciona
Pod no Kubernetes faz pull de python:3.12-slim
│
▼
harbor.empresa.com/dockerhub-proxy/library/python:3.12-slim
│
├── Se imagem está em cache no Harbor → retorna imediatamente
│
└── Se não está em cache → Harbor busca no Docker Hub,
armazena localmente e retorna para o pod
Na segunda vez que qualquer pod pedir a mesma imagem, ela vem do Harbor — sem sair da rede interna.
Passo 1 — Configurar o endpoint do registry externo
Acesse Administration → Registries → New Endpoint.
Docker Hub
| Campo | Valor |
|---|---|
| Provider | Docker Hub |
| Name | dockerhub |
| Endpoint URL | https://hub.docker.com |
| Access ID | seu usuário Docker Hub (opcional, mas aumenta o rate limit) |
| Access Secret | sua senha ou token Docker Hub |
Google Container Registry (GCR)
| Campo | Valor |
|---|---|
| Provider | Google GCR |
| Name | gcr |
| Endpoint URL | https://gcr.io |
| Access ID | _json_key |
| Access Secret | conteúdo do JSON da service account GCP |
Amazon ECR
| Campo | Valor |
|---|---|
| Provider | AWS ECR |
| Name | ecr-prod |
| Endpoint URL | https://<account-id>.dkr.ecr.<region>.amazonaws.com |
| Access ID | AWS Access Key ID |
| Access Secret | AWS Secret Access Key |
GitHub Container Registry (GHCR)
| Campo | Valor |
|---|---|
| Provider | Github GHCR |
| Name | ghcr |
| Endpoint URL | https://ghcr.io |
| Access ID | seu usuário GitHub |
| Access Secret | Personal Access Token com escopo read:packages |
Após preencher, clique em Test Connection para validar antes de salvar.
Passo 2 — Criar o projeto de proxy cache
Cada registry externo precisa de um projeto dedicado no Harbor. Acesse Projects → New Project.
| Campo | Valor |
|---|---|
| Project Name | dockerhub-proxy |
| Access Level | Public (recomendado para facilitar o uso no cluster) |
| Proxy Cache | ✅ Habilitado |
| Registry | selecione o endpoint dockerhub criado no passo anterior |
Repita para cada registry externo que quiser cachear.
Passo 3 — Usar o proxy cache
A partir de agora, em vez de usar o endereço original do Docker Hub:
# Antes — direto no Docker Hub
docker pull python:3.12-slim
docker pull nginx:1.27-alpine
docker pull postgres:17
Use o endereço do proxy no Harbor:
# Depois — via proxy cache do Harbor
docker pull harbor.empresa.com/dockerhub-proxy/library/python:3.12-slim
docker pull harbor.empresa.com/dockerhub-proxy/library/nginx:1.27-alpine
docker pull harbor.empresa.com/dockerhub-proxy/library/postgres:17
Para imagens de usuários/organizações no Docker Hub:
# Docker Hub: bitnami/postgresql:17
docker pull harbor.empresa.com/dockerhub-proxy/bitnami/postgresql:17
# Docker Hub: grafana/grafana:11.0.0
docker pull harbor.empresa.com/dockerhub-proxy/grafana/grafana:11.0.0
Para outras fontes:
# GCR
docker pull harbor.empresa.com/gcr-proxy/google-containers/pause:3.9
# GHCR
docker pull harbor.empresa.com/ghcr-proxy/cert-manager/cert-manager-controller:v1.14.0
Configurando no Kubernetes
Para que todos os pods do cluster usem automaticamente o proxy cache do Harbor, você pode usar um admission webhook ou configurar o containerd em todos os nodes.
Opção 1 — Configurar o containerd nos nodes (recomendado)
Edite o arquivo de configuração do containerd em cada node:
# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://harbor.empresa.com/v2/dockerhub-proxy"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]
endpoint = ["https://harbor.empresa.com/v2/gcr-proxy"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
endpoint = ["https://harbor.empresa.com/v2/ghcr-proxy"]
Reinicie o containerd:
sudo systemctl restart containerd
Com isso, qualquer pull de python:3.12-slim nos pods do cluster será automaticamente redirecionado para o Harbor, sem precisar alterar os manifests do Kubernetes.
Opção 2 — Referenciar explicitamente nos manifests
Mais simples, porém exige atualizar todos os manifests:
# deployment.yaml
spec:
containers:
- name: api
image: harbor.empresa.com/dockerhub-proxy/library/python:3.12-slim
Verificando o cache em funcionamento
Após o primeiro pull via proxy, a imagem estará visível no projeto de proxy:
# Via API
curl -s "https://harbor.empresa.com/api/v2.0/projects/dockerhub-proxy/repositories" \
-u "admin:suasenha" | jq '.[].name'
Você verá os repositórios cacheados listados como:
library/python
library/nginx
bitnami/postgresql
Comportamento do cache
| Situação | Comportamento |
|---|---|
| Imagem não está no cache | Harbor busca no registry externo, armazena e retorna |
| Imagem está no cache | Harbor retorna imediatamente sem contato externo |
| Registry externo indisponível | Se imagem está no cache, continua funcionando |
| Registry externo indisponível | Se imagem não está no cache, o pull falha |
Tag mutável (ex: latest) | Harbor verifica se houve atualização no registry externo |
Boas práticas
- Autentique no Docker Hub mesmo para o proxy — aumenta o rate limit de 100 para 200 pulls/6h por IP, e para 5000 com conta paga.
- Use projetos públicos para o proxy cache — facilita o uso no Kubernetes sem configurar imagePullSecrets para imagens públicas.
- Configure o containerd nos nodes em vez de alterar os manifests — transparente para os desenvolvedores.
- Monitore o uso de storage — imagens cacheadas ocupam espaço. Configure uma política de retenção no projeto de proxy para remover imagens não utilizadas há mais de X dias.
Próximo artigo
Na Parte 6, vamos configurar políticas de retenção para controlar quantas imagens ficam armazenadas por repositório — e configurar quotas para limitar o uso de storage por projeto.