Comment configurer un registre Docker privé sur Rocky Linux 8
Si tu travailles pour une organisation et que tu veux garder tes images docker en interne pour un déploiement rapide, l’hébergement d’un dépôt Docker privé est parfait. Avoir un registre docker privé te permet de posséder ton pipeline de distribution d’images et d’avoir un contrôle plus strict sur le stockage et la distribution des images. Tu peux intégrer ton registre à ton système CI/CD en améliorant ton flux de travail.
Ce tutoriel t’apprendra à configurer et à utiliser un registre Docker privé sur un serveur basé sur Rocky Linux 8 en utilisant Amazon S3 comme emplacement de stockage.
Conditions préalables
- Deux serveurs Linux avec Rocky Linux 8. Un serveur fera office d’hôte du registre, tandis que l’autre sera utilisé comme client pour envoyer des demandes et recevoir des images de l’hôte.
- Un nom de domaine enregistré pointant vers le serveur hôte. Nous utiliserons
registry.example.com
pour notre tutoriel. - Un utilisateur non-root avec des privilèges sudo sur les deux machines.
Étape 1 – Configurer le pare-feu
La première étape consiste à configurer le pare-feu. Rocky Linux utilise le pare-feu Firewalld. Vérifie l’état du pare-feu.
$ sudo firewall-cmd --state running
Le pare-feu fonctionne avec différentes zones, et la zone publique est celle que nous utiliserons par défaut. Fais la liste de tous les services et ports actifs sur le pare-feu.
$ sudo firewall-cmd --permanent --list-services
Il devrait afficher la sortie suivante.
cockpit dhcpv6-client ssh
Autorise les ports HTTP et HTTPS.
$ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https
Vérifie à nouveau l’état du pare-feu.
$ sudo firewall-cmd --permanent --list-services
Tu devrais voir une sortie similaire.
cockpit dhcpv6-client http https ssh
Recharge le pare-feu pour activer les modifications.
$ sudo firewall-cmd --reload
Étape 2 – Installe Docker et Docker Compose
Cette étape est requise à la fois sur le serveur et sur les machines clientes.
Installe le dépôt officiel de Docker.
$ sudo dnf install yum-utils $ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
Installe Docker.
$ sudo dnf install docker-ce docker-ce-cli containerd.io
Active et exécute le démon Docker.
$ sudo systemctl enable docker --now
Ajoute ton utilisateur système au groupe Docker pour éviter d’utiliser sudo
pour exécuter les commandes Docker.
$ sudo usermod -aG docker $(whoami)
Connecte-toi à nouveau à ton serveur après t’être déconnecté pour activer le changement.
Télécharge et installe la dernière version stable de Docker Compose.
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Applique les autorisations d’exécution au fichier binaire téléchargé.
$ sudo chmod +x /usr/local/bin/docker-compose
Installe le script de complétion Bash de Docker-compose.
$ sudo curl \ -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose \ -o /etc/bash_completion.d/docker-compose
Recharge les paramètres de ton profil pour que la complétion bash fonctionne.
$ source ~/.bashrc
Étape 3 – Configurer le registre Docker
Crée des répertoires d’utilisateurs
Crée un répertoire pour la configuration du registre.
$ mkdir ~/docker-registry
Passe dans le répertoire docker-registry
.
$ cd ~/docker-registry
Crée un répertoire pour stocker le mot de passe d’authentification HTTP, les fichiers de configuration Nginx et les certificats SSL.
$ mkdir auth
Crée un autre répertoire pour stocker les journaux de Nginx.
$ mkdir logs
Créer un seau Amazon S3
Tu peux stocker les données du registre et les images sur ton serveur ou utiliser un service d’hébergement en nuage. Pour notre tutoriel, nous utiliserons le service de cloud Amazon S3.
L’étape suivante consiste à définir le fichier de configuration avec quelques paramètres importants. Ces paramètres peuvent aussi être définis dans le fichier docker-compose.yml
, mais avoir un fichier séparé est bien mieux.
Crée un seau avec les paramètres suivants.
- L’ACL doit être désactivé.
- L’accès public au seau doit être désactivé.
- Le versioning du seau doit être désactivé.
- Active le cryptage du seau en utilisant les clés gérées par Amazon S3. (SSE-S3)
- Le verrouillage des objets doit être désactivé.
Crée un utilisateur IAM avec la politique suivante.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation", "s3:ListBucketMultipartUploads" ], "Resource": "arn:aws:s3:::S3_BUCKET_NAME" }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload" ], "Resource": "arn:aws:s3:::S3_BUCKET_NAME/*" } ] }
Remplace l’adresse S3_BUCKET_NAME
par le nom de ton seau S3.
Note la clé secrète, la valeur secrète et la région de ton seau qui seront utilisées plus tard.
Crée le fichier Docker Compose
Crée le fichier docker-compose.yml
et ouvre-le pour le modifier.
$ nano docker-compose.yml
Colle le code suivant dans ce fichier.
version: '3.3' services: registry: image: registry:2 restart: always environment: - REGISTRY_STORAGE=s3 - REGISTRY_STORAGE_S3_REGION=us-west-2 - REGISTRY_STORAGE_S3_BUCKET=hf-docker-registry - REGISTRY_STORAGE_S3_ENCRYPT=true - REGISTRY_STORAGE_S3_CHUNKSIZE=5242880 - REGISTRY_STORAGE_S3_SECURE=true - REGISTRY_STORAGE_S3_ACCESSKEY=AKIA3FIG4NVFCJ6STMUA - REGISTRY_STORAGE_S3_SECRETKEY=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 - REGISTRY_STORAGE_S3_V4AUTH=true - REGISTRY_STORAGE_S3_ROOTDIRECTORY=/image-registry - REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR=inmemory - REGISTRY_HEALTH_STORAGEDRIVER_ENABLED=false nginx: image: "nginx:alpine" ports: - 443:443 links: - registry:registry volumes: - ./auth:/etc/nginx/conf.d - ./auth/nginx.conf:/etc/nginx/nginx.conf:ro - ./logs:/var/log/nginx - /etc/letsencrypt:/etc/letsencrypt
Enregistre le fichier en appuyant sur Ctrl + X et en saisissant Y lorsque tu y es invité.
Passons en revue ce que nous avons mis en place dans notre fichier compose.
La première étape consiste à récupérer la dernière image de la version 2 du registre Docker depuis le hub. Nous n’utilisons pas la dernière balise car elle peut poser des problèmes en cas de mise à jour majeure de la version. Le paramétrer sur 2 te permet de saisir toutes les mises à jour 2.x tout en évitant d’être mis à niveau automatiquement vers la prochaine version majeure, ce qui peut introduire des changements cassants.
Le conteneur de registre est configuré pour redémarrer toujours en cas de panne ou d’arrêt inattendu.
Nous avons défini diverses variables d’environnement pour le stockage Amazon S3. Passons-les en revue rapidement.
- REGISTRY_STORAGE définit le type de stockage. Nous avons choisi s3 puisque nous utilisons Amazon S3.
- REGISTRY_STORAGE_S3_REGION définit la région de ton seau S3.
- REGISTRY_STORAGE_S3_BUCKET définit le nom de ton seau S3.
- REGISTRY_STORAGE_S3_ENCRYPT– donne la valeur true si tu as activé le cryptage du seau.
- REGISTRY_STORAGE_S3_CHUNKSIZE définit la taille des chunks de téléchargement. Elle doit être supérieure à 5MB (5 * 1024 * 1024).
- REGISTRY_STORAGE_S3_SECURE– mets-le sur true si tu vas utiliser HTTPS.
- REGISTRY_STORAGE_S3_ACCESSKEY et REGISTRY_STORAGE_S3_SECRETKEY – Les informations d’identification de l’utilisateur que tu as récupérées après avoir créé ton utilisateur IAM.
- REGISTRY_STORAGE_S3_V4AUTH – mets-le sur true si tu utilises la v4 de l’authentification AWS. Si tu obtiens des erreurs liées à la connexion S3, mets-le sur false.
- REGISTRY_STORAGE_S3_ROOTDIRECTORY – définit le répertoire racine de ton seau sous lequel tes données de registre seront stockées.
- REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR – définit l’emplacement du cache. Dans notre cas, nous le stockons en mémoire. Tu peux aussi le définir pour utiliser Redis.
- REGISTRY_HEALTH_STORAGEDRIVER_ENABLED – Donne la valeur false pour désactiver le service de contrôle de la santé du stockage du Registre. Il y a un bug avec le Registre qui peut causer des problèmes si tu ne le mets pas à false.
Le registre de Docker communique via le port 5000, qui est celui que nous avons exposé dans notre serveur à Docker.
./auth:/etc/nginx/conf.d
Le mappage garantit que tous les paramètres de Nginx sont disponibles dans le conteneur../auth/nginx.conf:/etc/nginx/nginx.conf:ro
met en correspondance le fichier de paramètres Nginx du système avec celui du conteneur en mode lecture seule../logs:/var/log/nginx
permet d’accéder aux journaux de Nginx sur le système en établissant une correspondance avec le répertoire des journaux de Nginx dans le conteneur.Les paramètres du registre Docker sont stockés dans le fichier
/etc/docker/registry/config.yml
dans le conteneur, et nous l’avons mappé vers le fichierconfig.yml
dans le répertoire actuel, que nous allons créer à l’étape suivante.
Configurer l’authentification
Pour configurer l’authentification HTTP, tu dois installer le paquet httpd-tools
.
$ sudo dnf install httpd-tools
Crée le fichier de mot de passe dans le répertoire ~/docker-registry/auth
.
$ htpasswd -Bc ~/docker-registry/auth/nginx.htpasswd user1 New password: Re-type new password: Adding password for user user1
Le drapeau -c
indique à la commande de créer un nouveau fichier, et le drapeau -B
permet d’utiliser l’algorithme bcrypt pris en charge par Docker. Remplace user1
par un nom d’utilisateur de ton choix.
Si tu veux ajouter d’autres utilisateurs, exécute à nouveau la commande, mais sans le drapeau -c
.
$ htpasswd -B ~/docker-registry/auth/registry.password user2
Maintenant, le fichier sera mappé au conteneur de registre pour l’authentification.
Étape 4 – Installer SSL
Pour installer un certificat SSL à l’aide de Let’s Encrypt, nous devons télécharger l’outil Certbot, qui est disponible dans le référentiel Epel.
Installe le dépôt EPEL et Certbot.
$ sudo dnf install epel-release $ sudo dnf install certbot
Génère un certificat SSL.
$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d registry.example.com
La commande ci-dessus téléchargera un certificat dans le répertoire /etc/letsencrypt/live/registry.example.com
sur ton serveur.
Génère un certificat de groupe Diffie-Hellman.
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
Teste le renouvellement du certificat.
$ sudo certbot renew --dry-run
Si le test à sec réussit, cela signifie que tes certificats seront automatiquement renouvelés.
Copie le fichier Dhparam dans le conteneur
Copie le certificat du groupe Diffie-Hellman dans le répertoire ~/docker-registry/auth
, qui sera mappé au conteneur.
$ sudo cp /etc/ssl/certs/dhparam.pem ~/docker-registry/auth
Étape 5 – Configurer Nginx
L’étape suivante consiste à configurer le serveur Nginx en tant que proxy frontal pour le serveur du registre Docker. Le registre Docker est livré avec un serveur intégré fonctionnant sur le port 5000. Nous allons le placer derrière Nginx.
Crée et ouvre le fichier ~/docker-registry/auth/nginx.conf
pour le modifier.
$ sudo nano ~/docker-registry/auth/nginx.conf
Colle le code suivant dans ce fichier.
events { worker_connections 1024; } http { upstream docker-registry { server registry:5000; } ## Set a variable to help us decide if we need to add the ## 'Docker-Distribution-Api-Version' header. ## The registry always sets this header. ## In the case of nginx performing auth, the header is unset ## since nginx is auth-ing before proxying. map $upstream_http_docker_distribution_api_version $docker_distribution_api_version { '' 'registry/2.0'; } server { listen 443 ssl http2; server_name registry.example.com; # SSL ssl_certificate /etc/letsencrypt/live/registry.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/registry.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/registry.example.com/chain.pem; access_log /var/log/nginx/registry.access.log; error_log /var/log/nginx/registry.error.log; # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers on; ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1; ssl_session_cache shared:SSL:10m; ssl_dhparam /etc/nginx.d/conf.d/dhparam.pem; resolver 8.8.8.8; # disable any limits to avoid HTTP 413 for large image uploads client_max_body_size 0; # required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486) chunked_transfer_encoding on; location /v2/ { # Do not allow connections from docker 1.5 and earlier # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { return 404; } # To add basic authentication to v2 use auth_basic setting. auth_basic "Registry realm"; auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd; ## If $docker_distribution_api_version is empty, the header is not added. ## See the map directive above where this variable is defined. add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always; proxy_pass http://docker-registry; proxy_set_header Host $http_host; # required for docker client's sake proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 900; } } }
Enregistre le fichier en appuyant sur Ctrl + X et en saisissant Y lorsque tu y es invité une fois terminé.
Configure SELinux pour autoriser les connexions réseau pour le Private Docker Registry.
$ sudo setsebool -P httpd_can_network_connect on
Étape 6 – Lance Docker Registry
Passe dans le répertoire du registre Docker.
$ cd ~/docker-registry
Lance le conteneur Docker.
$ docker-compose up -d
Vérifie l’état des conteneurs.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 88d6addc1687 nginx:alpine "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp docker-registry_nginx_1 2b112edc1c72 registry:2 "/entrypoint.sh /etc…" 5 minutes ago Up 5 minutes 5000/tcp docker-registry_registry_1
Connecte-toi au registre Docker.
$ docker login -u=testuser -p=testpassword https://registry.example.com
Tu peux aussi ouvrir l’URL https://registry.example.com/v2/
dans ton navigateur, et il te demandera un nom d’utilisateur et un mot de passe. Tu devrais voir une page vide avec {} dessus.
Tu peux vérifier l’URL sur le terminal en utilisant curl
.
$ curl -u testuser -X GET https://registry.nspeaks.xyz/v2/ Enter host password for user 'testuser': {}
Télécharge la dernière image docker Ubuntu.
$ docker pull ubuntu:latest
Marque cette image pour le registre privé.
$ docker tag ubuntu:latest registry.example.com/ubuntu2004
Pousse l’image vers le registre.
$ docker push registry.example.com/ubuntu2004
Vérifie si le push a réussi.
$ curl -u testuser -X GET https://registry.nspeaks.xyz/v2/_catalog Enter host password for user 'testuser': {"repositories":["ubuntu2004"]}
Saisis ton mot de passe d’authentification Nginx lorsque tu y es invité, et tu verras la liste des référentiels disponibles via le registre.
Vérifie la liste des images Docker actuellement disponibles pour être utilisées.
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry 2 d3241e050fc9 5 days ago 24.2MB nginx alpine 53722defe627 5 days ago 23.4MB httpd 2 118b6abfbf55 5 days ago 144MB ubuntu latest ff0fea8310f3 2 weeks ago 72.8MB registry.nspeaks.xyz/ubuntu2004 latest ff0fea8310f3 2 weeks ago 72.8MB
Étape 7 – Accéder et utiliser le registre Docker depuis la machine cliente
Connecte-toi à ton client-serveur. À l’étape 1, nous avons installé Docker sur la machine cliente.
Connecte-toi au registre privé de Docker depuis la machine cliente.
$ docker login -u=testuser -p=testpassword https://registry.example.com
Tire l’image Ubuntu du registre.
$ docker pull registry.example.com/ubuntu2004
Répertorie toutes les images sur ta machine cliente.
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry.nspeaks.xyz/ubuntu2004 latest ff0fea8310f3 2 weeks ago 72.8MB
Crée et lance un conteneur en utilisant l’image téléchargée.
$ docker run -it registry.example.com/ubuntu2004 /bin/bash
Tu seras connecté au Shell à l’intérieur du conteneur Ubuntu.
root@a2da49fdbea9:
Exécute la commande suivante pour vérifier la version de Linux.
root@a2da49fdbea9$ cat /etc/os-release NAME="Ubuntu" VERSION="20.04.4 LTS (Focal Fossa)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 20.04.4 LTS" VERSION_ID="20.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=focal UBUNTU_CODENAME=focal
Maintenant, tu peux commencer à utiliser ton registre Docker depuis tes machines clientes.
Conclusion
Ceci conclut notre tutoriel sur la configuration d’un registre Docker privé sur un serveur basé sur Rocky Linux 8 qui utilise Amazon S3 comme stockage. Si tu as des questions, poste-les dans les commentaires ci-dessous.