Skip to main content

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-slim repetidamente 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

CampoValor
ProviderDocker Hub
Namedockerhub
Endpoint URLhttps://hub.docker.com
Access IDseu usuário Docker Hub (opcional, mas aumenta o rate limit)
Access Secretsua senha ou token Docker Hub

Google Container Registry (GCR)

CampoValor
ProviderGoogle GCR
Namegcr
Endpoint URLhttps://gcr.io
Access ID_json_key
Access Secretconteúdo do JSON da service account GCP

Amazon ECR

CampoValor
ProviderAWS ECR
Nameecr-prod
Endpoint URLhttps://<account-id>.dkr.ecr.<region>.amazonaws.com
Access IDAWS Access Key ID
Access SecretAWS Secret Access Key

GitHub Container Registry (GHCR)

CampoValor
ProviderGithub GHCR
Nameghcr
Endpoint URLhttps://ghcr.io
Access IDseu usuário GitHub
Access SecretPersonal 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.

CampoValor
Project Namedockerhub-proxy
Access LevelPublic (recomendado para facilitar o uso no cluster)
Proxy Cache✅ Habilitado
Registryselecione 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çãoComportamento
Imagem não está no cacheHarbor busca no registry externo, armazena e retorna
Imagem está no cacheHarbor retorna imediatamente sem contato externo
Registry externo indisponívelSe imagem está no cache, continua funcionando
Registry externo indisponívelSe 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.