Aller au contenu

Harbor — Registre de conteneurs

Harbor est le registre de conteneurs utilisé par AKKO pour stocker ses images Docker personnalisées et son chart Helm (au format OCI). Il est déployé de manière indépendante du release AKKO, avec son propre PostgreSQL et son propre stockage, afin qu'AKKO puisse être désinstallé, réinstallé ou déplacé sans jamais avoir à reconstruire d'images.


Vue d'ensemble

Harbor est un registre de conteneurs open-source diplômé de la CNCF. AKKO l'utilise pour héberger :

  • Les 12 images personnalisées d'AKKO (akko-postgres, akko-spark, akko-notebook, akko-cockpit, akko-trino, akko-ai-service, akko-mlflow, akko-airflow, akko-dbt, akko-mcp-trino, akko-mcp-openmetadata).
  • Le chart Helm umbrella AKKO, empaqueté et publié en tant qu'artefact OCI.

Harbor fournit également nativement le scan de vulnérabilités Trivy, la signature d'images, la réplication, les comptes robots, et un RBAC au niveau projet.


Architecture

Harbor est indépendant d'AKKO par conception :

Dimension Harbor AKKO
Namespace harbor akko
PostgreSQL Embarqué (dans le namespace harbor) akko-postgresql (dans le namespace akko)
Stockage objet PVC local-path object storage
Release Helm harbor akko
Cycle de vie Infra pérenne Release applicative

Conséquences :

  • helm uninstall akko laisse Harbor (et toutes les images) intact.
  • kubectl delete namespace akko ne touche pas à Harbor.
  • Harbor peut être mis à jour sans impacter les workloads AKKO.
  • AKKO peut être redéployé à tout moment en tirant exactement les mêmes tags d'images figés depuis Harbor.

Cette séparation est obligatoire dès que la machine de build, le registre et le cluster d'exécution ont des cycles de vie différents.


Installation

Un seul script déploie Harbor avec des valeurs par défaut adaptées à AKKO :

bash helm/scripts/deploy-harbor.sh

Le script :

  1. Crée le namespace harbor.
  2. Ajoute le dépôt Helm officiel de Harbor.
  3. Installe le chart officiel de Harbor avec PostgreSQL embarqué et PVCs local-path.
  4. Crée le projet akko dans lequel toutes les images AKKO seront publiées.

L'installation complète prend environ 3 minutes sur une machine de type ordinateur portable.

Déployer Harbor avant AKKO

En production, déployez toujours Harbor avant la première installation d'AKKO. Ainsi helm install akko peut tirer les images depuis Harbor dès le premier jour, et le cluster n'a jamais besoin que la machine de build soit accessible.


Accès à Harbor

Surface Point d'entrée
Interface web http://harbor.<domaine>:30500
Docker / Helm localhost:30500 (depuis le nœud du cluster)
Admin par défaut admin / akko-harbor-admin-2026

Changer le mot de passe par défaut en production

Le mot de passe par défaut akko-harbor-admin-2026 est destiné au développement local k3d. En production, faites une rotation du mot de passe admin avant qu'une image soit poussée. Voir Durcissement de la sécurité.

Authentification Docker

docker login localhost:30500
# Utilisateur : admin
# Mot de passe : akko-harbor-admin-2026

Authentification Helm (OCI)

helm registry login localhost:30500 \
  --username admin \
  --password akko-harbor-admin-2026

Publier des images

Après avoir construit les images AKKO en local avec helm/scripts/build-images.sh, taguez-les et poussez-les vers Harbor :

docker tag akko-cockpit:2026.04 localhost:30500/akko/cockpit:2026.04
docker push localhost:30500/akko/cockpit:2026.04

Pour pousser les 12 images en une seule fois, utilisez le flag AKKO_REGISTRY du script de build :

AKKO_REGISTRY=localhost:30500/akko \
AKKO_PARALLEL=4 \
  bash helm/scripts/build-images.sh

Le script construit toutes les images personnalisées en parallèle et pousse l'ensemble dans le projet akko. Les tags suivent la convention YYYY.MM (par exemple 2026.04). Le registre ne contient jamais de tag latest.


Tirer des images (k3s / k3d)

Les nœuds Kubernetes doivent s'authentifier auprès de Harbor pour tirer les images AKKO.

k3s :

# /etc/rancher/k3s/registries.yaml
mirrors:
  "localhost:30500":
    endpoint:
      - "http://localhost:30500"
configs:
  "localhost:30500":
    auth:
      username: admin
      password: akko-harbor-admin-2026

Puis redémarrez l'agent k3s pour qu'il prenne en compte la configuration :

systemctl restart k3s

EKS / GKE / AKS / OpenShift : utilisez plutôt imagePullSecrets. Créez un secret de type docker-registry dans le namespace akko et référencez-le via global.imagePullSecrets dans les values Helm. Un compte robot (droit minimal, lecture seule) doit être utilisé à la place du compte admin.


Publier le chart Helm (OCI)

Le chart Helm AKKO est lui-même publié dans Harbor en tant qu'artefact OCI, afin que le cluster d'exécution puisse exécuter helm install sans avoir besoin d'accéder au dépôt Git :

helm package helm/akko/
helm push akko-2026.04.tgz oci://localhost:30500/akko

Installation depuis Harbor :

helm install akko oci://localhost:30500/akko/akko --version 2026.04 \
  -n akko --create-namespace \
  -f values-dev.yaml \
  -f values-domain.yaml \
  -f values-dev-secrets.yaml \
  --set-file akko-keycloak.realm.data=realm-domain.json

Sauvegarde

Harbor possède deux éléments d'état à sauvegarder :

PVC Contenu Stratégie de sauvegarde
harbor-database PostgreSQL (projets, utilisateurs, scans, politiques) pg_dump nocturne via un CronJob
harbor-registry Couches d'images réelles (blobs) rsync nocturne vers un stockage externe

Exemple de pg_dump nocturne :

kubectl exec -n harbor deploy/harbor-database -- \
  pg_dumpall -U postgres > /backups/harbor-$(date +%F).sql

Exemple de synchronisation du registre (blob store) :

kubectl -n harbor cp harbor-registry-0:/storage /backups/harbor-registry/
# ou rsync depuis le répertoire local-path du nœud
rsync -a /var/lib/rancher/k3s/storage/harbor-registry/ \
  backup-host:/backups/harbor-registry/

La restauration est l'opération inverse : psql < dump.sql + rsync du blob store, puis helm upgrade sur Harbor pour remettre la configuration en place.


Dépannage

unauthorized: authentication required au docker push

Le cache d'identifiants Docker est périmé.

docker logout localhost:30500
docker login localhost:30500

connection refused sur le port 30500

Vérifiez que le core Harbor et son ingress nginx tournent.

kubectl get pods -n harbor
kubectl get svc -n harbor

Si le service harbor n'est pas de type NodePort sur 30500, il faut réexécuter le script de déploiement.

project not found lors du push

Le projet akko n'a pas été créé (ou a été supprimé). Recréez-le via l'API Harbor :

curl -X POST \
  -u admin:akko-harbor-admin-2026 \
  -H "Content-Type: application/json" \
  -d '{"project_name":"akko","public":false}' \
  http://localhost:30500/api/v2.0/projects

Pod en CrashLoopBackOff

Inspectez les logs du composant fautif :

kubectl logs -n harbor deploy/harbor-core
kubectl logs -n harbor deploy/harbor-jobservice
kubectl logs -n harbor sts/harbor-database

La cause la plus fréquente en dev est un PVC de base de données plein — vérifiez avec kubectl describe pvc -n harbor.


Durcissement de la sécurité (production)

  • Faire la rotation du mot de passe admin. Changez harborAdminPassword à la fois dans les values Helm et via l'API Harbor (le mot de passe est stocké en base, la valeur Helm n'est qu'une graine initiale).
  • Activer TLS. Positionnez expose.tls.enabled: true et câblez un vrai certificat, idéalement via cert-manager avec un ClusterIssuer.
  • Utiliser des comptes robots. Ne laissez jamais la CI ou les clusters s'authentifier en tant que admin. Créez un compte robot pour le push (CI) et un pour le pull (chaque cluster cible), limités au seul projet akko.
  • Activer Trivy. Le scan de vulnérabilités est activé par défaut ; imposez un seuil de sévérité au niveau projet pour bloquer le pull des CVE critiques.
  • Activer la signature de contenu. La signature Notary / Cosign est désactivée par défaut — activez-la en production afin que les clusters ne tirent que des images signées.
  • Activer l'audit. Expédiez les logs d'audit Harbor vers logs layer (ou tout SIEM) via log shipper, aux côtés du reste de la piste d'audit AKKO.

Dimensionnement

PVC Taille par défaut Règle empirique
harbor-registry 100 Gi Un jeu complet d'images AKKO ≈ 15 Go → 100 Gi tient ~6 versions
harbor-database 20 Gi Confortable pour des millions de lignes de métadonnées
harbor-chartmuseum (si activé) 5 Gi Historique ; le push OCI ne le requiert pas
harbor-jobservice 1 Gi Répertoire des logs de scan

Pour un registre de longue durée, activez les politiques de rétention de tags sur le projet akko (UI Harbor → ProjectsakkoPolicyTag Retention) afin de conserver, par exemple, les 5 derniers tags de chaque dépôt, puis déclenchez une collecte des blobs non référencés chaque semaine.


Pour aller plus loin