Harbor est un registry de conteneurs open source développé initialement par VMware, diplômé CNCF en 2020. Il étend l'implémentation de référence OCI (Distribution) avec une interface web, du RBAC par projet, un scan de vulnérabilités (Trivy par défaut), un proxy cache vers les registries publics, et la réplication entre instances Harbor ou vers d'autres registries OCI.
Idéal pour : clusters Kubernetes en production nécessitant un registry privé centralisé, équipes souhaitant un contrôle d'accès par projet, conformité sécurité avec scan d'images et signature.
Informations essentielles
Origine : VMware → CNCF graduated (2020) · Licence : Apache 2.0 · Architectures : x86_64, ARM64
Liens : Site officiel · Documentation · GitHub · Releases
Support : Les 2 dernières versions mineures sont maintenues. Cycle de release trimestriel environ.
Architecture
| Composant | Rôle |
|---|---|
| Core | API REST, authentification, RBAC, webhooks |
| Registry | Distribution OCI - stockage effectif des images |
| Portal | Interface web Angular |
| JobService | Tâches asynchrones (réplication, scan, GC) |
| PostgreSQL | Base de données (métadonnées, RBAC, audit) |
| Redis | Cache et file de messages |
| Trivy | Scanner de vulnérabilités (intégré depuis Harbor 2.2) |
Prérequis
Déploiement Kubernetes (recommandé)
- Kubernetes 1.20+
- Helm 3.x
- StorageClass avec provisionnement dynamique (pour les PVCs)
- Ingress controller (nginx, traefik...)
- Certificat TLS (cert-manager recommandé)
Installation via Helm
1. Ajouter le chart Harbor
helm repo add harbor https://helm.goharbor.io
helm repo update
# Voir les valeurs disponibles
helm show values harbor/harbor > harbor-values.yaml
2. Configurer les valeurs
# harbor-values.yaml (configuration minimale production)
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: harbor-tls
ingress:
hosts:
core: registry.example.com
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0" # pas de limite de taille
externalURL: https://registry.example.com
# Changer le mot de passe admin par défaut (Harbor12345 par défaut !)
harborAdminPassword: "MonMotDePasseSecurise"
persistence:
enabled: true
persistentVolumeClaim:
registry:
size: 50Gi
database:
size: 5Gi
redis:
size: 2Gi
# Scanner de vulnérabilités Trivy (activé par défaut)
trivy:
enabled: true
3. Déployer
kubectl create namespace harbor
helm install harbor harbor/harbor \
--namespace harbor \
--values harbor-values.yaml
# Suivre le déploiement
kubectl -n harbor get pods -w
4. Vérifier
# Tous les pods doivent être Running
kubectl -n harbor get pods
# Tester l'accès
curl -I https://registry.example.com/api/v2.0/ping
# HTTP/2 200
Premier login
# CLI Docker
docker login registry.example.com
# Username: admin
# Password: MonMotDePasseSecurise
# Pousser une image
docker tag nginx:alpine registry.example.com/library/nginx:alpine
docker push registry.example.com/library/nginx:alpine
Changer le mot de passe admin dès le premier login via l'interface web ou l'API. Le mot de passe par défaut est
Harbor12345.
Projets et RBAC
Harbor organise les images en projets. Chaque projet a ses propres membres avec des rôles.
| Rôle | Permissions |
|---|---|
| Project Admin | Gérer le projet, les membres, les configurations |
| Maintainer | Push, pull, supprimer des artifacts |
| Developer | Push, pull |
| Guest | Pull uniquement |
| Limited Guest | Pull avec restrictions |
# Via API REST - créer un projet
curl -u admin:MonMotDePasseSecurise \
-X POST https://registry.example.com/api/v2.0/projects \
-H "Content-Type: application/json" \
-d '{"project_name": "mon-projet", "public": false}'
Proxy cache
Harbor peut servir de proxy cache vers des registries publics (Docker Hub, GCR, GHCR...). Les images sont mises en cache localement pour éviter les rate limits et améliorer la disponibilité.
Configurer via l'interface web
- Administration > Registries → Ajouter
https://registry-1.docker.io(Docker Hub) - Projects → Nouveau projet → cocher "Proxy Cache" → sélectionner le registry
- Les pulls passent ensuite via Harbor :
docker pull registry.example.com/dockerhub-proxy/nginx:alpine
Réplication
Harbor peut répliquer vers/depuis d'autres instances Harbor ou registries OCI.
# Via API - créer une règle de réplication
curl -u admin:MonMotDePasseSecurise \
-X POST https://registry.example.com/api/v2.0/replication/policies \
-H "Content-Type: application/json" \
-d '{
"name": "sync-to-dr",
"src_registry": {"id": 1},
"dest_registry": {"id": 2},
"filters": [{"type": "name", "value": "mon-projet/**"}],
"trigger": {"type": "scheduled", "trigger_settings": {"cron": "0 0 * * *"}}
}'
Scan de vulnérabilités
Trivy est disponible comme scanner depuis Harbor v1.10 et est le scanner recommandé par défaut dans les versions 2.x (Clair a été déprécié).
# Déclencher un scan via CLI
curl -u admin:MonMotDePasseSecurise \
-X POST "https://registry.example.com/api/v2.0/projects/mon-projet/repositories/mon-app/artifacts/latest/scan"
# Voir les résultats
curl -u admin:MonMotDePasseSecurise \
"https://registry.example.com/api/v2.0/projects/mon-projet/repositories/mon-app/artifacts/latest/additions/vulnerabilities"
Politique de déploiement : Harbor peut bloquer le pull d'images avec des CVE critiques via les Deployment Security Policies (Administration > Configuration > Security).
Robot accounts (CI/CD)
Pour les pipelines CI/CD, utiliser des Robot Accounts plutôt que les credentials utilisateur.
- Projet > Robot Accounts > Add Robot Account
- Sélectionner les permissions (push/pull/scan)
- Récupérer le nom et le secret générés
# Utiliser le robot account dans un pipeline
docker login registry.example.com \
-u "robot$mon-projet+ci-robot" \
-p "<secret-généré>"
Mise à jour
# Vérifier la version actuelle
helm list -n harbor
# Mettre à jour
helm repo update
helm upgrade harbor harbor/harbor \
--namespace harbor \
--values harbor-values.yaml \
--version <nouvelle-version>
# Vérifier
kubectl -n harbor get pods
Toujours lire les notes de release avant de mettre à jour - certaines versions nécessitent des migrations de schéma.
Troubleshooting
Pod en CrashLoopBackOff
kubectl -n harbor describe pod <pod>
kubectl -n harbor logs <pod> --previous
# Problème fréquent : PVC non provisionné
kubectl -n harbor get pvc
Erreur "unauthorized" au push
# Vérifier que le projet existe et que l'utilisateur a les droits
curl -u user:password https://registry.example.com/api/v2.0/projects/<projet>
# Vérifier la config Docker
cat ~/.docker/config.json | grep registry.example.com
Garbage collection (libérer l'espace disque)
# Via l'interface web : Administration > Garbage Collection > GC Now
# Ou via API (déclenche une tâche asynchrone)
curl -u admin:password \
-X POST https://registry.example.com/api/v2.0/system/gc/schedule \
-H "Content-Type: application/json" \
-d '{"schedule": {"type": "Manual"}}'
Commandes utiles
# Healthcheck
curl https://registry.example.com/api/v2.0/ping
# Lister les projets
curl -u admin:password https://registry.example.com/api/v2.0/projects
# Lister les artifacts d'un dépôt
curl -u admin:password \
"https://registry.example.com/api/v2.0/projects/<projet>/repositories/<repo>/artifacts"
# Pods Harbor
kubectl -n harbor get pods
kubectl -n harbor get pvc
Ressources
- Site officiel : https://goharbor.io
- Documentation : https://goharbor.io/docs/
- GitHub : https://github.com/goharbor/harbor
- Helm chart values : https://github.com/goharbor/harbor-helm/blob/main/values.yaml
- API REST : https://editor.swagger.io/?url=https://raw.githubusercontent.com/goharbor/harbor/main/api/v2.0/swagger.yaml