Harbor Registry

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.