Harbor container registry: complete gids voor Kubernetes en OpenShift
Harbor is een open-source container registry gebouwd door VMware en sinds 2020 een CNCF graduated project. Het is de standaardkeuze voor organisaties die container images on-premises of in een private cloud willen opslaan, beveiligen en beheren β met ingebouwde vulnerability scanning, image signing, RBAC en replicatie naar andere registries. Dit artikel legt uit wat Harbor is, hoe het werkt en hoe je het inzet in een Kubernetes of OpenShift omgeving.
Wat is Harbor en waarom zou je het gebruiken?
Docker Hub is handig voor publieke images, maar voor productieomgevingen wil je meer controle. Harbor biedt wat publieke registries niet bieden:
- Data sovereignty β images blijven binnen jouw infrastructuur, geen afhankelijkheid van externe diensten
- Vulnerability scanning β automatisch scannen van images op bekende kwetsbaarheden (CVEs) via Trivy of Clair
- Image signing β verifieer dat images niet zijn gemanipuleerd (Notary/Cosign)
- RBAC β fijnmazige toegangscontrole per project, per gebruiker of robotaccount
- Replicatie β synchroniseer images tussen meerdere registries, datacenters of cloudregio’s
- Auditlogging β volledige geschiedenis van alle pull- en push-operaties
- Quota’s β beperk opslaggebruik per project
Harbor is relevant voor iedereen die werkt met Kubernetes, OpenShift, of CI/CD pipelines β en is een onderwerp dat terugkomt in het CKA- en EX380-examen.
Architectuur β hoe werkt Harbor?
Harbor bestaat uit meerdere componenten die samenwerken:
- Core β de centrale API en businesslogica
- Registry β de daadwerkelijke image-opslag (gebouwd op Docker Distribution)
- Portal β de webinterface
- Database β PostgreSQL voor metadata, gebruikers en beleid
- Redis β caching en jobqueue
- Trivy adapter β vulnerability scanner
- Notary β image signing (optioneel)
- JobService β asynchone taken zoals replicatie en scanning
Harbor installeren op Kubernetes met Helm
# Voeg de Harbor Helm repository toe
helm repo add harbor https://helm.goharbor.io
helm repo update
# Maak een namespace aan
kubectl create namespace harbor
# Installeer Harbor met basisinstellingen
helm install harbor harbor/harbor \
--namespace harbor \
--set expose.type=ingress \
--set expose.ingress.hosts.core=harbor.voorbeeld.nl \
--set expose.tls.enabled=true \
--set expose.tls.certSource=secret \
--set externalURL=https://harbor.voorbeeld.nl \
--set harborAdminPassword=WijzigDitWachtwoord123
# Status controleren
kubectl get pods -n harbor
# Harbor is bereikbaar op https://harbor.voorbeeld.nl
# Standaard inloggegevens: admin / WijzigDitWachtwoord123
Productie-instelling: values.yaml
# values.yaml voor productie
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: harbor-tls
ingress:
hosts:
core: harbor.voorbeeld.nl
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
externalURL: https://harbor.voorbeeld.nl
# Externe database (aanbevolen voor productie)
database:
type: external
external:
host: postgres.voorbeeld.nl
port: 5432
username: harbor
password: DbWachtwoord
coreDatabase: harbor_core
sslmode: verify-full
# Externe Redis (aanbevolen voor HA)
redis:
type: external
external:
addr: redis.voorbeeld.nl:6379
password: RedisWachtwoord
# Persistente opslag
persistence:
enabled: true
resourcePolicy: keep
persistentVolumeClaim:
registry:
size: 100Gi
storageClass: fast-ssd
# Trivy vulnerability scanner
trivy:
enabled: true
autoUpdate: true
harborAdminPassword: SterkWachtwoord123!
Harbor gebruiken β basisbewerkingen
Inloggen via Docker CLI
# Inloggen op Harbor
docker login harbor.voorbeeld.nl
# Image taggen voor Harbor
docker tag mijn-app:latest harbor.voorbeeld.nl/mijn-project/mijn-app:1.0.0
# Image pushen
docker push harbor.voorbeeld.nl/mijn-project/mijn-app:1.0.0
# Image pullen
docker pull harbor.voorbeeld.nl/mijn-project/mijn-app:1.0.0
Robotaccounts aanmaken voor CI/CD
# Via de Harbor API
curl -X POST "https://harbor.voorbeeld.nl/api/v2.0/robots" \
-H "Content-Type: application/json" \
-u "admin:WachtwoordHier" \
-d '{
"name": "ci-pipeline",
"description": "Robot account voor CI/CD pipeline",
"duration": 365,
"level": "project",
"permissions": [
{
"kind": "project",
"namespace": "mijn-project",
"access": [
{"resource": "repository", "action": "push"},
{"resource": "repository", "action": "pull"},
{"resource": "artifact", "action": "read"}
]
}
]
}'
Vulnerability scanning
# Scan handmatig triggeren via API
curl -X POST "https://harbor.voorbeeld.nl/api/v2.0/projects/mijn-project/repositories/mijn-app/artifacts/sha256:abc123/scan" \
-u "admin:WachtwoordHier"
# Scan resultaten opvragen
curl "https://harbor.voorbeeld.nl/api/v2.0/projects/mijn-project/repositories/mijn-app/artifacts/sha256:abc123/additions/vulnerabilities" \
-u "admin:WachtwoordHier"
# Automatisch scannen bij push inschakelen (via UI of API)
curl -X PUT "https://harbor.voorbeeld.nl/api/v2.0/projects/mijn-project" \
-H "Content-Type: application/json" \
-u "admin:WachtwoordHier" \
-d '{"metadata": {"auto_scan": "true"}}'
Beleid: geblokkeerde images met kritieke kwetsbaarheden
Via de Harbor-webinterface kun je een CVE-beleid instellen dat voorkomt dat images met kritieke kwetsbaarharen worden gepulled. Ga naar Project β Configuratie β Beveiliging en schakel “Prevent vulnerable images from running” in op het gewenste ernstniveau (Critical, High, etc.).
Harbor koppelen aan Kubernetes
ImagePullSecret aanmaken
# Secret aanmaken voor Harbor authenticatie
kubectl create secret docker-registry harbor-secret \
--docker-server=harbor.voorbeeld.nl \
--docker-username=robot\$ci-pipeline \
--docker-password=RobotToken123 \
--namespace=mijn-namespace
# Secret gebruiken in een Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mijn-app
spec:
template:
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: mijn-app
image: harbor.voorbeeld.nl/mijn-project/mijn-app:1.0.0
Global ImagePullSecret via ServiceAccount
# Voeg pullsecret toe aan de default ServiceAccount
kubectl patch serviceaccount default \
-p '{"imagePullSecrets": [{"name": "harbor-secret"}]}' \
-n mijn-namespace
Harbor koppelen aan OpenShift
# In OpenShift gebruik je oc secrets
oc create secret docker-registry harbor-secret \
--docker-server=harbor.voorbeeld.nl \
--docker-username=robot\$ci-pipeline \
--docker-password=RobotToken123 \
-n mijn-project
# Koppel het secret aan de serviceaccount
oc secrets link default harbor-secret --for=pull -n mijn-project
oc secrets link builder harbor-secret -n mijn-project
# Verifieer
oc get serviceaccount default -o yaml -n mijn-project
Replicatie β images synchroniseren
# Replicatieregel via API aanmaken
curl -X POST "https://harbor.voorbeeld.nl/api/v2.0/replication/policies" \
-H "Content-Type: application/json" \
-u "admin:WachtwoordHier" \
-d '{
"name": "sync-naar-dr",
"src_registry": {
"id": 1
},
"dest_registry": {
"id": 2
},
"dest_namespace": "gespiegeld",
"filters": [
{"type": "name", "value": "productie/**"},
{"type": "tag", "value": "v*"}
],
"trigger": {
"type": "scheduled",
"trigger_settings": {
"cron": "0 2 * * *"
}
},
"deletion": false,
"override": true,
"enabled": true
}'
Harbor in een CI/CD pipeline (GitLab voorbeeld)
# .gitlab-ci.yml
variables:
HARBOR_REGISTRY: harbor.voorbeeld.nl
HARBOR_PROJECT: productie
IMAGE_NAME: mijn-app
stages:
- build
- scan
- deploy
build:
stage: build
script:
- docker login -u $HARBOR_USER -p $HARBOR_PASS $HARBOR_REGISTRY
- docker build -t $HARBOR_REGISTRY/$HARBOR_PROJECT/$IMAGE_NAME:$CI_COMMIT_SHA .
- docker push $HARBOR_REGISTRY/$HARBOR_PROJECT/$IMAGE_NAME:$CI_COMMIT_SHA
scan:
stage: scan
script:
# Wacht op scan resultaat via Harbor API
- |
STATUS=""
while [ "$STATUS" != "Success" ]; do
STATUS=$(curl -s -u "$HARBOR_USER:$HARBOR_PASS" \
"$HARBOR_REGISTRY/api/v2.0/projects/$HARBOR_PROJECT/repositories/$IMAGE_NAME/artifacts/$CI_COMMIT_SHA" \
| jq -r '.scan_overview."application/vnd.security.vulnerability.report; version=1.1".scan_status')
sleep 10
done
# Faal als er kritieke kwetsbaarheden zijn
- |
CRITICAL=$(curl -s -u "$HARBOR_USER:$HARBOR_PASS" \
"$HARBOR_REGISTRY/api/v2.0/projects/$HARBOR_PROJECT/repositories/$IMAGE_NAME/artifacts/$CI_COMMIT_SHA/additions/vulnerabilities" \
| jq '.["application/vnd.security.vulnerability.report; version=1.1"].summary.summary.Critical // 0')
if [ "$CRITICAL" -gt "0" ]; then
echo "GEBLOKKEERD: $CRITICAL kritieke kwetsbaarheden gevonden"
exit 1
fi
Garbage collection
# Handmatige garbage collection starten
curl -X POST "https://harbor.voorbeeld.nl/api/v2.0/system/gc/schedule" \
-H "Content-Type: application/json" \
-u "admin:WachtwoordHier" \
-d '{
"schedule": {
"type": "Manual"
}
}'
# Geplande GC instellen (dagelijks om 02:00)
curl -X POST "https://harbor.voorbeeld.nl/api/v2.0/system/gc/schedule" \
-H "Content-Type: application/json" \
-u "admin:WachtwoordHier" \
-d '{
"schedule": {
"type": "Scheduled",
"cron": "0 2 * * *"
}
}'
Harbor in relatie tot certificeringen
Harbor-kennis is relevant bij meerdere certificeringen:
- CKA β private registry configureren en ImagePullSecrets beheren
- CKAD β images uit een private registry gebruiken in Deployments
- EX380 β enterprise OpenShift met private registry integratie
- CGOA β Harbor als image source in een GitOps workflow met ArgoCD
Veelgestelde vragen
Wat is het verschil tussen Harbor en Docker Hub?
Docker Hub is een gehoste publieke registry van Docker Inc. Harbor is een self-hosted, open-source registry die je op eigen infrastructuur draait. Harbor biedt meer beveiligingsfuncties (vulnerability scanning, image signing, RBAC) en geeft volledige controle over waar images worden opgeslagen.
Wat is het verschil tussen Harbor en Quay?
Quay is de container registry van Red Hat, geΓ―ntegreerd in OpenShift. Harbor is vendor-onafhankelijk en werkt met elke Kubernetes-distributie. Voor reine OpenShift-omgevingen is Quay vaak de standaardkeuze; voor multi-cloud of vendor-onafhankelijke omgevingen is Harbor een sterke keuze.
Is Harbor gratis?
Ja β Harbor is volledig open-source onder de Apache 2.0 licentie. Er zijn geen licentiekosten. Je betaalt alleen voor de infrastructuur waarop je het draait.