Ubuntu 22 : Harbor

Edit 14/11/23 : ajout de Trivy pour le scan de vulnérabilité
Edit 20/09/24 : ajout de l'update du certificat

Bonjour,

Aujourd'hui, un billet portant sur la mise en place d'un Harbor, sur Ubuntu 22.04 hebergé sur Proxmox, afin de pouvoir y stocker des images docker custom et de pouvoir les utiliser dans le cluster K8S.

En premier, on a besoin de quelques packages :

apt install apt-transport-https ca-certificates curl software-properties-common git

La méthode d'installation pour Harbor est via docker donc il faut
ajouter son repo :

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg
add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Installation de docker :

apt update
apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-compose

J'ai modifié le dossier data de docker afin de mettre ça sur une partition custom avec plus d'espace disque via le fichier /etc/docker/daemon.json :

{ 
   "data-root": "/srv/docker"
}

Certificat

Afin de pouvoir faire du https, j'ai mis les certificats service et de la rootCA dans le dossier docker :

mkdir -p /etc/docker/certs.d/adm.securmail.fr

Et j'y copie les fichiers relatifs à Harbor et à la rootCA :

root@harbor:/etc/docker# tree
.
├── certs.d
│   └── adm.securmail.fr
│       ├── harbor.adm.securmail.fr.chained.cert
│       ├── harbor.adm.securmail.fr.chained.crt
│       ├── harbor.adm.securmail.fr.key
│       └── rootCA.crt
└── daemon.json

Pour que docker utilise le certificat, il faut qu'il ai l'extension .cert et pas uniquement .crt, le contenu reste le même.

On peut redémarrer docker pour la prise en compte :

systemctl restart docker
systemctl status docker

Installation

Maintenant on passe à l'installation d'Harbor à proprement parlé.

Il faut auparavant créer le dossier dédié pour les data de l'Harbor :

mkdir /srv/data

On récupère l'archive :

cd /tmp
wget https://github.com/goharbor/harbor/releases/download/v2.7.3/harbor-online-installer-v2.7.3.tgz
tar xzvf harbor-online-installer-v2.7.3.tgz

Copie du template de configuration d'harbor :

cp harbor.yml.tmpl harbor.yml

Modification du template harbor.yml afin de pouvoir renseigner les valeurs qu'il faut pour le service :

hostname: harbor.adm.securmail.fr
certificate: /etc/docker/certs.d/adm.securmail.fr/harbor.adm.securmail.fr.chained.crt
private_key: /etc/docker/certs.d/adm.securmail.fr/harbor.adm.securmail.fr.key
harbor_admin_password: nvMTb6JsZcMKcCDvaryb
password: N3sPdLEKfMsQ3un1RcvZ
data_volume: /srv/data

Ensuite, on passe à l'installation :

./prepare
./install.sh --with-trivy

Si vous ne voulez pas de scanner ou utiliser un autre, il suffit de retirer l'option.

Et la mise en place des images qui vont bien avec un clean en amont pour être sur :

docker-compose down -v
docker-compose up -d

On peut vérifier la bonne présence des images :

root@harbor:/tmp/harbor# docker images
REPOSITORY                    TAG       IMAGE ID       CREATED       SIZE
goharbor/redis-photon         v2.7.3    68ef52d98298   3 weeks ago   120MB
goharbor/harbor-registryctl   v2.7.3    0adcdbbc67c8   3 weeks ago   140MB
goharbor/registry-photon      v2.7.3    91fa7c3c922c   3 weeks ago   78.7MB
goharbor/nginx-photon         v2.7.3    a780e583d37f   3 weeks ago   116MB
goharbor/harbor-log           v2.7.3    48a9ddf4a380   3 weeks ago   128MB
goharbor/harbor-jobservice    v2.7.3    265eda6d72aa   3 weeks ago   260MB
goharbor/harbor-core          v2.7.3    1a415c050c9c   3 weeks ago   222MB
goharbor/harbor-portal        v2.7.3    9a0f808a9eed   3 weeks ago   125MB
goharbor/harbor-db            v2.7.3    731c8c0fe6ca   3 weeks ago   174MB
goharbor/prepare              v2.7.3    36fd5b190502   3 weeks ago   168MB

On peut également vérifier que les process tournent bien :

root@harbor:/tmp/harbor# docker ps
CONTAINER ID   IMAGE                                COMMAND                  CREATED       STATUS                 PORTS                                                                            NAMES
dd7daf5fc9a4   goharbor/harbor-jobservice:v2.7.3    "/harbor/entrypoint.…"   2 weeks ago   Up 2 weeks (healthy)                                                                                    harbor-jobservice
50f8d048c344   goharbor/nginx-photon:v2.7.3         "nginx -g 'daemon of…"   2 weeks ago   Up 2 weeks (healthy)   0.0.0.0:80->8080/tcp, :::80->8080/tcp, 0.0.0.0:443->8443/tcp, :::443->8443/tcp   nginx
a70f3d4beb18   goharbor/harbor-core:v2.7.3          "/harbor/entrypoint.…"   2 weeks ago   Up 2 weeks (healthy)                                                                                    harbor-core
45978d5a7c82   goharbor/harbor-db:v2.7.3            "/docker-entrypoint.…"   2 weeks ago   Up 2 weeks (healthy)                                                                                    harbor-db
cfec32af08d6   goharbor/harbor-registryctl:v2.7.3   "/home/harbor/start.…"   2 weeks ago   Up 2 weeks (healthy)                                                                                    registryctl
1292079c810c   goharbor/redis-photon:v2.7.3         "redis-server /etc/r…"   2 weeks ago   Up 2 weeks (healthy)                                                                                    redis
33082dfb72f1   goharbor/registry-photon:v2.7.3      "/home/harbor/entryp…"   2 weeks ago   Up 2 weeks (healthy)                                                                                    registry
d476e1d72d78   goharbor/harbor-portal:v2.7.3        "nginx -g 'daemon of…"   2 weeks ago   Up 2 weeks (healthy)                                                                                    harbor-portal
f754cecd1402   goharbor/harbor-log:v2.7.3           "/bin/sh -c /usr/loc…"   2 weeks ago   Up 2 weeks (healthy)   127.0.0.1:1514->10514/tcp                                                        harbor-log

On vérifie également que les ports sont bien en écoute :

root@harbor:~# ss -ltnp | egrep "80|443"
LISTEN 0      4096         0.0.0.0:80        0.0.0.0:*    users:(("docker-proxy",pid=61428,fd=4))  
LISTEN 0      4096         0.0.0.0:443       0.0.0.0:*    users:(("docker-proxy",pid=61408,fd=4))  
LISTEN 0      4096            [::]:80           [::]:*    users:(("docker-proxy",pid=61437,fd=4))  
LISTEN 0      4096            [::]:443          [::]:*    users:(("docker-proxy",pid=61414,fd=4))  

Harbor est bien accessible via le nom de domaine configuré dans le fichier harbor.yml via le password admin configuré.

Push image

De base, il y a un repo de créé en mode public. Je l'ai laissé tel quel car mon Harbor n'est pas exposé mais vous pouvez passer ce dépôt en privé ce qui impliquera de gérer l'authentification côté push d'images et pull côté k8s.

Il est maintenant possible de push une image custom après un build en local :

sudo docker tag puppetboard:1.1.4 harbor.adm.securmail.fr/library/puppetboard:1.1.4
sudo docker push harbor.adm.securmail.fr/library/puppetboard:1.1.4

On vérifie qu'on a bien l'image poussée sur l'Harbor :

docker images
REPOSITORY                                    TAG           IMAGE ID       CREATED       SIZE
harbor.adm.securmail.fr/library/puppetboard   1.1.4         454c44d73adf   13 days ago   249MB
puppetboard                                   1.1.4         454c44d73adf   13 days ago   249MB
python                                        3.11-alpine   b9b301ab01c2   5 weeks ago   52.1MB

Également côté Harbor via l'IHM :
Capture-d--cran-du-2023-09-29-13-37-53

Pour utiliser l'Harbor depuis k8s, il suffit de spécifier l'adresse dans le deployment.yaml comme cela :

      containers:
      - name: puppetboard
        image: harbor.adm.securmail.fr/library/puppetboard:1.1.4
        imagePullPolicy: IfNotPresent

Renouveller le certificat

Pour renouveller ce certificat une fois expiré :

  • Stopper Harbor : depuis le dossier d'installation, docker-compose -f docker-compose.yml down
  • Copier le nouveau certificat + key dans /etc/docker/certs.d/adm.securmail.fr
  • Lancer le script ./prepare
  • Démarrer Harbor depuis le dossier d'installation : docker-compose up -d

Normalement, vous avez un Harbor fonctionnel et utilisable par K8S.

Have fun.