Comment configurer un registre de dockers privé au-dessus d’espaces DigitalOcean et l’utiliser avec DigitalOcean Kubernetes

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 commekubectl 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 étantregistry.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.

Empty file uploaded to empty Space

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!.

Hello World page

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.

Related