L'auteur a sélectionné lesFree and Open Source Fund pour recevoir un don dans le cadre du programmeWrite for DOnations.
introduction
UnDocker registry est un système de stockage et de livraison de contenu pour les images Docker nommées, qui sont la norme de l'industrie pour les applications conteneurisées. Un registre privé Docker vous permet de partager en toute sécurité vos images au sein de votre équipe ou de votre entreprise avec plus de flexibilité et de contrôle par rapport aux images publiques. En hébergeant votre registre privé Docker directement dans votre cluster Kubernetes, vous pouvez atteindre des vitesses plus élevées, réduire le temps de latence et améliorer la disponibilité, tout en contrôlant le registre.
Le stockage de registre sous-jacent est délégué à des pilotes externes. Le système de stockage par défaut est le système de fichiers local, mais vous pouvez l'échanger contre un pilote de stockage basé sur un nuage. DigitalOcean Spaces est un stockage d'objets compatible S3 conçu pour les équipes de développeurs et les entreprises qui souhaitent un moyen évolutif, simple et abordable de stocker et de servir de grandes quantités de données, et convient parfaitement au stockage d'images Docker. Son réseau CDN intégré permet de réduire considérablement la latence lorsqu’on accède fréquemment à des images.
Dans ce didacticiel, vous déploierez votre registre Docker privé sur votre clusterDigitalOcean Kubernetes à l'aide deHelm, sauvegardé par DigitalOcean Spaces pour stocker les données. Vous allez créer des clés API pour votre espace désigné, installer le registre Docker sur votre cluster avec une configuration personnalisée, configurer Kubernetes pour s’authentifier correctement sur celui-ci et le tester en exécutant un exemple de déploiement sur le cluster. À la fin de ce didacticiel, un registre Docker privé et sécurisé est installé sur votre cluster DigitalOcean Kubernetes.
Conditions préalables
Avant de commencer ce tutoriel, vous aurez besoin de:
-
Docker installé sur la machine à partir de laquelle vous allez accéder à votre cluster. Pour Ubuntu 18.04, visitezHow To Install and Use Docker on Ubuntu 18.04. Vous devez seulement compléter la première étape. Sinon, visitez leswebsite de Docker pour d’autres distributions.
-
Un cluster DigitalOcean Kubernetes avec votre configuration de connexion configurée comme
kubectl
par défaut. Les instructions sur la façon de configurerkubectl
sont affichées sous l'étapeConnect to your Cluster affichée lorsque vous créez votre cluster. Pour savoir comment créer un cluster Kubernetes sur DigitalOcean, consultezKubernetes Quickstart. -
Un espace DigitalOcean avec des clés API (accès et secret). Pour savoir comment créer un espace DigitalOcean et des clés API, consultezHow To Create a DigitalOcean Space and API Key.
-
Le gestionnaire de paquets Helm installé sur votre ordinateur local et Tiller installé sur votre cluster. Effectuez les étapes 1 et 2 desHow To Install Software on Kubernetes Clusters with the Helm Package Manager. Il vous suffit de compléter les deux premières étapes.
-
Nginx Ingress Controller et Cert-Manager installés sur le cluster. Pour obtenir un guide sur la façon de procéder, consultezHow to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes.
-
Un nom de domaine avec deux enregistrements DNS A indiquait l’équilibreur de charge DigitalOcean utilisé par l’Ingress. Si vous utilisez DigitalOcean pour gérer les enregistrements DNS de votre domaine, consultezHow to Manage DNS Records pour créer des enregistrements A. Dans ce didacticiel, nous désignerons les enregistrements A comme étant
registry.example.com
etk8s-test.example.com
.
[[step-1 -—- configuration-and-installation-the-docker-registry]] == Étape 1 - Configuration et installation du registre Docker
Dans cette étape, vous allez créer un fichier de configuration pour le déploiement du registre et installer le registre Docker sur votre cluster avec la configuration donnée à l'aide du gestionnaire de packages Helm.
Au cours de ce didacticiel, vous utiliserez un fichier de configuration appeléchart_values.yaml
pour remplacer certains des paramètres par défaut du registre Docker Helmchart. Helm appelle ses paquets, ses cartes; Ce sont des ensembles de fichiers qui décrivent une sélection connexe de ressources Kubernetes. Vous modifierez les paramètres pour spécifier DigitalOcean Spaces en tant que système de stockage sous-jacent et pour activer l'accès HTTPS en connectant les certificats Let’s Encrypt TLS.
Dans le cadre du prérequis, vous auriez créé les servicesecho1
etecho2
et une entréeecho_ingress
à des fins de test; vous n'en aurez pas besoin dans ce didacticiel, vous pouvez donc les supprimer.
Commencez par supprimer l'entrée en exécutant la commande suivante:
kubectl delete -f echo_ingress.yaml
Ensuite, supprimez les deux services de test:
kubectl delete -f echo1.yaml && kubectl delete -f echo2.yaml
La commande kubectldelete
accepte le fichier à supprimer lorsqu'elle est passée au paramètre-f
.
Créez un dossier qui servira d’espace de travail:
mkdir ~/k8s-registry
Accédez-y en exécutant:
cd ~/k8s-registry
Maintenant, en utilisant votre éditeur de texte, créez votre fichierchart_values.yaml
:
nano chart_values.yaml
Ajoutez les lignes suivantes en vous assurant de remplacer les lignes en surbrillance par vos détails:
chart_values.yaml
ingress:
enabled: true
hosts:
- registry.example.com
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-body-size: "30720m"
tls:
- secretName: letsencrypt-prod
hosts:
- registry.example.com
storage: s3
secrets:
htpasswd: ""
s3:
accessKey: "your_space_access_key"
secretKey: "your_space_secret_key"
s3:
region: your_space_region
regionEndpoint: your_space_region.digitaloceanspaces.com
secure: true
bucket: your_space_name
Le premier bloc,ingress
, configure l'entrée Kubernetes qui sera créée dans le cadre du déploiement du graphique Helm. L'objet Ingress fait que les itinéraires HTTP / HTTPS extérieurs pointent vers des services internes du cluster, permettant ainsi la communication depuis l'extérieur. Les valeurs remplacées sont:
-
enabled
: défini surtrue
pour activer l'entrée. -
hosts
: une liste d'hôtes à partir desquels l'Ingress acceptera le trafic. -
annotations
: une liste de métadonnées qui fournit des indications supplémentaires aux autres parties de Kubernetes sur la façon de traiter l'entrée. Vous définissez le contrôleur d'entrée surnginx
, l'émetteur du cluster Let's Encrypt sur la variante de production (letsencrypt-prod
), et dites au contrôleurnginx
d'accepter les fichiers d'une taille maximale de 30 Go, ce qui est une limite raisonnable même pour les plus grandes images Docker. -
tls
: cette sous-catégorie configure Let’s Encrypt HTTPS. Vous remplissez la listehosts
qui définit à partir de quels hôtes sécurisés cette entrée acceptera le trafic HTTPS avec notre exemple de nom de domaine.
Ensuite, vous définissez le stockage du système de fichiers surs3
- l'autre option disponible seraitfilesystem
. Ici,s3
indique l'utilisation d'un système de stockage distant compatible avec l'API Amazon S3 standard de l'industrie, que DigitalOcean Spaces remplit.
Dans le bloc suivant,secrets
, vous configurez des clés pour accéder à votre espace DigitalOcean sous la sous-catégories3
. Enfin, dans le blocs3
, vous configurez les paramètres spécifiant votre espace.
Enregistrez et fermez votre fichier.
Maintenant, si vous ne l’avez pas déjà fait, configurez vos enregistrements A pour qu'ils pointent vers l’équilibreur de charge que vous avez créé dans le cadre de l’installation de Nginx Ingress Controller dans le didacticiel préalable. Pour savoir comment configurer votre DNS sur DigitalOcean, consultezHow to Manage DNS Records.
Ensuite, assurez-vous que votre espace n’est pas vide. Le registre Docker ne fonctionnera pas du tout si vous n’avez aucun fichier dans votre espace. Pour résoudre ce problème, téléchargez un fichier. Accédez à l'onglet Espaces, recherchez votre espace, cliquez sur le boutonUpload File et importez le fichier de votre choix. Vous pouvez télécharger le fichier de configuration que vous venez de créer.
Avant d'installer quoi que ce soit via Helm, vous devez actualiser son cache. Cela mettra à jour les dernières informations sur votre référentiel de cartes. Pour ce faire, exécutez la commande suivante:
helm repo update
Vous allez maintenant déployer le tableau de registre Docker avec cette configuration personnalisée via Helm en exécutant:
helm install stable/docker-registry -f chart_values.yaml --name docker-registry
Vous verrez le résultat suivant:
OutputNAME: docker-registry
...
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
docker-registry-config 1 1s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
docker-registry-54df68fd64-l26fb 0/1 ContainerCreating 0 1s
==> v1/Secret
NAME TYPE DATA AGE
docker-registry-secret Opaque 3 1s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
docker-registry ClusterIP 10.245.131.143 5000/TCP 1s
==> v1beta1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
docker-registry 0/1 1 0 1s
==> v1beta1/Ingress
NAME HOSTS ADDRESS PORTS AGE
docker-registry registry.example.com 80, 443 1s
NOTES:
1. Get the application URL by running these commands:
https://registry.example.com/
Helm répertorie toutes les ressources créées à la suite du déploiement du graphique de registre Docker. Le registre est maintenant accessible à partir du nom de domaine que vous avez spécifié précédemment.
Vous avez configuré et déployé un registre Docker sur votre cluster Kubernetes. Vous allez ensuite tester la disponibilité du registre Docker récemment déployé.
[[step-2 -—- testing-pushing-and-pulling]] == Étape 2 - Test de la poussée et de la traction
Au cours de cette étape, vous allez tester votre registre Docker récemment déployé en y insérant et en extrayant des images. Actuellement, le registre est vide. Pour avoir quelque chose à pousser, vous devez avoir une image disponible sur la machine sur laquelle vous travaillez. Utilisons l'image Docker demysql
.
Commencez par extrairemysql
du Docker Hub:
sudo docker pull mysql
Votre sortie ressemblera à ceci:
OutputUsing default tag: latest
latest: Pulling from library/mysql
27833a3ba0a5: Pull complete
...
e906385f419d: Pull complete
Digest: sha256:a7cf659a764732a27963429a87eccc8457e6d4af0ee9d5140a3b56e74986eed7
Status: Downloaded newer image for mysql:latest
Vous avez maintenant l'image disponible localement. Pour indiquer à Docker où le pousser, vous devez le baliser avec le nom d’hôte, comme suit:
sudo docker tag mysql registry.example.com/mysql
Ensuite, poussez l'image dans le nouveau registre:
sudo docker push registry.example.com/mysql
Cette commande s'exécutera avec succès et indiquera que votre nouveau registre est correctement configuré et accepte le trafic, y compris la transmission de nouvelles images. Si vous voyez une erreur, vérifiez vos étapes par rapport aux étapes 1 et 2.
Pour tester l'extraction propre du registre, supprimez d'abord les images localesmysql
avec la commande suivante:
sudo docker rmi registry.example.com/mysql && sudo docker rmi mysql
Ensuite, retirez-le du registre:
sudo docker pull registry.example.com/mysql
Cette commande prendra quelques secondes. Si cela fonctionne, cela signifie que votre registre fonctionne correctement. Si cela indique une erreur, vérifiez ce que vous avez entré par rapport aux commandes précédentes.
Vous pouvez répertorier les images Docker disponibles localement en exécutant la commande suivante:
sudo docker images
La sortie affiche la liste des images disponibles sur votre ordinateur local, ainsi que leur ID et leur date de création.
Votre registre Docker est configuré. Vous avez inséré une image et vérifié que vous pouvez la réduire. Ajoutons maintenant une authentification pour que seules certaines personnes puissent accéder au code.
[[step-3 -—- ajoutant-account-authentication-and-configuring-kubernetes-access]] == Étape 3 - Ajout de l'authentification de compte et configuration de l'accès Kubernetes
Dans cette étape, vous allez configurer l'authentification par nom d'utilisateur et mot de passe pour le registre à l'aide de l'utilitairehtpasswd
.
L'utilitairehtpasswd
provient du serveur Web Apache, que vous pouvez utiliser pour créer des fichiers qui stockent les noms d'utilisateur et les mots de passe pour l'authentification de base des utilisateurs HTTP. Le format des fichiershtpasswd
estusername:hashed_password
(un par ligne), ce qui est suffisamment portable pour permettre à d'autres programmes de l'utiliser également.
Pour rendrehtpasswd
disponible sur le système, vous devrez l'installer en exécutant:
sudo apt install apache2-utils -y
[.Remarque]##
Note:
Si vous exécutez ce didacticiel à partir d'un Mac, vous devrez utiliser la commande suivante pour rendrehtpasswd
disponible sur votre ordinateur:
docker run --rm -v ${PWD}:/app -it httpd htpasswd -b -c /app/htpasswd_file sammy password
Créez-le en exécutant la commande suivante:
touch htpasswd_file
Ajoutez une combinaison de nom d'utilisateur et de mot de passe àhtpasswd_file
:
htpasswd -B htpasswd_file username
Docker nécessite que le mot de passe soit haché à l'aide de l'algorithmebcrypt, c'est pourquoi nous transmettons le paramètre-B
. L'algorithme bcrypt est une fonction de hachage de mot de passe basée sur le chiffrement par bloc Blowfish, avec un paramètrework factor, qui spécifie le coût de la fonction de hachage.
N'oubliez pas de remplacerusername
par le nom d'utilisateur souhaité. Lorsqu'il est exécuté,htpasswd
vous demandera le mot de passe associé et ajoutera la combinaison àhtpasswd_file
. Vous pouvez répéter cette commande pour autant d'utilisateurs que vous souhaitez en ajouter.
Maintenant, affichez le contenu dehtpasswd_file
en exécutant la commande suivante:
cat htpasswd_file
Sélectionnez et copiez le contenu affiché.
Pour ajouter une authentification à votre registre Docker, vous devrez modifierchart_values.yaml
et ajouter le contenu dehtpasswd_file
dans la variablehtpasswd
.
Ouvrezchart_values.yaml
pour l'édition:
nano chart_values.yaml
Trouvez la ligne qui ressemble à ceci:
chart_values.yaml
htpasswd: ""
Modifiez-le pour qu'il corresponde à ce qui suit, en remplaçanthtpasswd\_file\_contents
par le contenu que vous avez copié à partir deshtpasswd_file
:
chart_values.yaml
htpasswd: |-
htpasswd_file_contents
Faites attention à l’indentation, chaque ligne du contenu du fichier doit avoir quatre espaces devant elle.
Une fois que vous avez ajouté votre contenu, enregistrez et fermez le fichier.
Pour propager les modifications sur votre cluster, exécutez la commande suivante:
helm upgrade docker-registry stable/docker-registry -f chart_values.yaml
Le résultat sera similaire à celui affiché lors du premier déploiement de votre registre Docker:
OutputRelease "docker-registry" has been upgraded. Happy Helming!
LAST DEPLOYED: ...
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
docker-registry-config 1 3m8s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
docker-registry-6c5bb7ffbf-ltnjv 1/1 Running 0 3m7s
==> v1/Secret
NAME TYPE DATA AGE
docker-registry-secret Opaque 4 3m8s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
docker-registry ClusterIP 10.245.128.245 5000/TCP 3m8s
==> v1beta1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
docker-registry 1/1 1 1 3m8s
==> v1beta1/Ingress
NAME HOSTS ADDRESS PORTS AGE
docker-registry registry.example.com 159.89.215.50 80, 443 3m8s
NOTES:
1. Get the application URL by running these commands:
https://registry.example.com/
Cette commande appelle Helm et lui demande de mettre à niveau une version existante, dans votre casdocker-registry
, avec son graphique défini dansstable/docker-registry
dans le référentiel de graphiques, après avoir appliqué le fichierchart_values.yaml
.
Maintenant, vous allez essayer à nouveau d’extraire une image du registre:
sudo docker pull registry.example.com/mysql
La sortie ressemblera à ceci:
OutputUsing default tag: latest
Error response from daemon: Get https://registry.example.com/v2/mysql/manifests/latest: no basic auth credentials
Il a correctement échoué car vous n'avez fourni aucune information d'identification. Cela signifie que votre registre Docker autorise correctement les requêtes.
Pour vous connecter au registre, exécutez la commande suivante:
sudo docker login registry.example.com
N'oubliez pas de remplacerregistry.example.com
par votre adresse de domaine. Il vous demandera un nom d'utilisateur et un mot de passe. S'il affiche une erreur, vérifiez ce que contient votrehtpasswd_file
. Vous devez définir la combinaison nom d'utilisateur et mot de passe dans leshtpasswd_file
, que vous avez créés plus tôt dans cette étape.
Pour tester la connexion, vous pouvez essayer de tirer à nouveau en exécutant la commande suivante:
sudo docker pull registry.example.com/mysql
La sortie ressemblera à ce qui suit:
OutputUsing default tag: latest
latest: Pulling from mysql
Digest: sha256:f2dc118ca6fa4c88cde5889808c486dfe94bccecd01ca626b002a010bb66bcbe
Status: Image is up to date for registry.example.com/mysql:latest
Vous avez maintenant configuré Docker et pouvez vous connecter en toute sécurité. Pour configurer Kubernetes afin qu'il se connecte à votre registre, exécutez la commande suivante:
sudo kubectl create secret generic regcred --from-file=.dockerconfigjson=/home/sammy/.docker/config.json --type=kubernetes.io/dockerconfigjson
Vous verrez la sortie suivante:
Outputsecret/regcred created
Cette commande crée un secret dans votre cluster avec le nomregcred
, prend le contenu du fichier JSON où Docker stocke les informations d'identification et l'analyse en tant quedockerconfigjson
, ce qui définit une information d'identification de registre dans Kubernetes.
Vous avez utiliséhtpasswd
pour créer un fichier de configuration de connexion, configuré le registre pour authentifier les demandes et créé un secret Kubernetes contenant les informations de connexion. Vous allez ensuite tester l'intégration entre votre cluster Kubernetes et votre registre.
[[step-4 -—- testing-kubernetes-integration-by-running-a-sample-deployment]] == Étape 4 - Test de l'intégration Kubernetes en exécutant un exemple de déploiement
Dans cette étape, vous allez exécuter un exemple de déploiement avec une image stockée dans le registre de cluster pour tester la connexion entre votre cluster Kubernetes et le registre.
Dans la dernière étape, vous avez créé un secret, appeléregcred
, contenant les informations de connexion pour votre registre privé. Il peut contenir des informations de connexion pour plusieurs registres, auquel cas vous devrez mettre à jour le secret en conséquence.
Vous pouvez spécifier le secret que Kubernetes doit utiliser lors de l'extraction de conteneurs dans la définition de pod en spécifiantimagePullSecrets
. Cette étape est nécessaire lorsque le registre Docker requiert une authentification.
Vous allez maintenant déployer un échantillonHello World image de votre registre Docker privé vers votre cluster. Tout d’abord, pour le pousser, vous le tirerez sur votre machine en exécutant la commande suivante:
sudo docker pull paulbouwer/hello-kubernetes:1.5
Ensuite, marquez-le en exécutant:
sudo docker tag paulbouwer/hello-kubernetes:1.5 registry.example.com/paulbouwer/hello-kubernetes:1.5
Enfin, poussez-le dans votre registre:
sudo docker push registry.example.com/paulbouwer/hello-kubernetes:1.5
Supprimez-le de votre ordinateur car vous n'en avez plus besoin localement:
sudo docker rmi registry.example.com/paulbouwer/hello-kubernetes:1.5
Vous allez maintenant déployer l'exemple d'application Hello World. Tout d'abord, créez un nouveau fichier,hello-world.yaml
, à l'aide de votre éditeur de texte:
nano hello-world.yaml
Ensuite, vous allez définir un service et une entrée pour rendre l’application accessible en dehors du cluster. Ajoutez les lignes suivantes en remplaçant les lignes en surbrillance par vos domaines:
hello-world.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: k8s-test.example.com
http:
paths:
- path: /
backend:
serviceName: hello-kubernetes
servicePort: 80
---
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes
template:
metadata:
labels:
app: hello-kubernetes
spec:
containers:
- name: hello-kubernetes
image: registry.example.com/paulbouwer/hello-kubernetes:1.5
ports:
- containerPort: 8080
imagePullSecrets:
- name: regcred
Tout d’abord, vous définissez l’entrée Ingress pour le déploiement Hello World, que vous acheminerez via l’équilibreur de charge appartenant au contrôleur Nginx Ingress Controller. Ensuite, vous définissez un service pouvant accéder aux pods créés dans le déploiement. Dans la spécification de déploiement réelle, vous spécifiez leimage
comme celui situé dans votre registre et définissezimagePullSecrets
surregcred
, que vous avez créé à l'étape précédente.
Enregistrez et fermez le fichier. Pour le déployer sur votre cluster, exécutez la commande suivante:
kubectl apply -f hello-world.yaml
Vous verrez le résultat suivant:
Outputingress.extensions/hello-kubernetes-ingress created
service/hello-kubernetes created
deployment.apps/hello-kubernetes created
Vous pouvez maintenant accéder à votre domaine de test - le deuxième enregistrement A,k8s-test.example.com
dans ce didacticiel. Vous verrez la page de KubernetesHello world!.
La page Hello World répertorie des informations sur l’environnement, telles que la version du noyau Linux et l’ID interne du pod à partir duquel la demande a été traitée. Vous pouvez également accéder à votre espace via l’interface Web pour voir les images avec lesquelles vous avez travaillé dans ce tutoriel.
Si vous souhaitez supprimer ce déploiement de Hello World après les tests, exécutez la commande suivante:
kubectl delete -f hello-world.yaml
Vous avez créé un exemple de déploiement de Hello World pour vérifier si Kubernetes extrait correctement les images de votre registre privé.
Conclusion
Vous avez maintenant déployé avec succès votre propre registre Docker privé sur votre cluster DigitalOcean Kubernetes, en utilisant DigitalOcean Spaces comme couche de stockage située en dessous. Il n'y a pas de limite au nombre d'images que vous pouvez stocker. Les espaces peuvent s'étendre à l'infini, tout en offrant la même sécurité et la même robustesse. En production, cependant, vous devez toujours vous efforcer d'optimiser autant que possible vos images Docker, jetez un œil au tutoriel deHow To Optimize Docker Images for Production.