Comment j'ai lancé Docker à l'intérieur de Docker et ce qui en est résulté

Bonjour Ă  tous ! Dans mon l'article prĂ©cĂ©dent, j'avais promis de parler du lancement de Docker dans Docker et des aspects pratiques de cette activitĂ©. Il est temps de tenir ma promesse. Un DevOps expĂ©rimentĂ© pourrait objecter que ceux qui ont besoin de Docker dans Docker se contentent gĂ©nĂ©ralement de transfĂ©rer le socket du dĂ©mon Docker de l'hĂŽte dans le conteneur, et cela suffit dans 99 % des cas. Mais ne vous dĂ©pĂȘchez pas de me lancer des cookies, car nous allons vraiment aborder le lancement de Docker Ă  l'intĂ©rieur de Docker. Cette solution possĂšde de nombreuses applications possibles, et cette article en traite une. Alors, asseyez-vous confortablement et redressez vos mains.

Comment j'ai lancé Docker à l'intérieur de Docker et ce qui en est résulté

Début

Tout a commencĂ© un soir de septembre pluvieux, lorsque je nettoyais une machine louĂ©e pour 5 $ sur Digital Ocean, qui s'est figĂ©e Ă  cause du fait que Docker avait envahi les 24 Go d'espace disque disponible avec ses images et conteneurs. L'ironie Ă©tait que toutes ces images et conteneurs Ă©taient transitoires et n'Ă©taient nĂ©cessaires que pour tester le bon fonctionnement de mon application chaque fois qu'une nouvelle version d'une bibliothĂšque ou d'un framework sortait. J'ai essayĂ© d'Ă©crire des scripts shell et de configurer des tĂąches cron pour nettoyer le dĂ©sordre, mais cela n'a pas servi : chaque fois, cela se terminait inĂ©vitablement par un espace disque de mon serveur complĂštement consommĂ© et un serveur figĂ© (au mieux). À un moment donnĂ©, je suis tombĂ© sur un article sur comment lancer Jenkins dans un conteneur et comment il pouvait crĂ©er et supprimer des pipelines de compilation via le socket du dĂ©mon Docker transfĂ©rĂ© vers lui. L'idĂ©e m'a plu, mais j'ai dĂ©cidĂ© d'aller plus loin et d'expĂ©rimenter le lancement direct de Docker dans Docker. Je pensais alors qu'il Ă©tait tout Ă  fait logique de tĂ©lĂ©charger des images Docker et de crĂ©er des conteneurs pour toutes les applications dont j'avais besoin pour tester Ă  l'intĂ©rieur d'un autre conteneur (appelons-le conteneur de staging). L'idĂ©e Ă©tait de lancer le conteneur de staging avec l'option -rm, qui supprime automatiquement tout le conteneur avec tout son contenu Ă  son arrĂȘt. J'ai fouillĂ© l'image Docker de Docker lui-mĂȘme (https://hub.docker.com/_/docker), mais elle s'est rĂ©vĂ©lĂ©e trop encombrante et je n'ai pas rĂ©ussi Ă  la faire fonctionner comme je le voulais, alors j'avais envie de tout faire par moi-mĂȘme.

Pratique. Échecs.

J'ai pour objectif de faire fonctionner le conteneur comme je le souhaite, et j'ai poursuivi mes expĂ©riences, ce qui a entraĂźnĂ© une multitude d'erreurs. Le rĂ©sultat de ma quĂȘte d'autopunition est l'algorithme suivant :

  1. Lançons le conteneur Docker en mode interactif.

    docker run --privileged -it docker:18.09.6

    Notez la version du conteneur, un pas à droite ou à gauche et votre DinD se transforme en citrouille. En réalité, tout se casse assez souvent avec la sortie d'une nouvelle version.
    Nous devons immédiatement accéder au shell.

  2. Essayons de voir quels conteneurs sont en cours d'exĂ©cution (RĂ©ponse : aucun), mais exĂ©cutons la commande quand mĂȘme :

    docker ps

    Vous serez un peu surpris, mais en fait, le dĂ©mon Docker n'est mĂȘme pas lancĂ© :

    error during connect: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 
    192.168.65.1:53: no such host

  3. Lançons-le nous-mĂȘmes :

    dockerd &

    Une autre mauvaise surprise :

    failed to start daemon: Error initializing network controller: error obtaining controller instance: failed 
    to create NAT chain DOCKER: Iptables not found

  4. Installons les paquets iptables et bash (travailler dans bash est bien plus agréable que dans sh) :

    apk add --no-cache iptables bash

  5. Lançons bash. Enfin, nous sommes de retour dans un shell familier.

  6. essayons de relancer Docker :

    dockerd &

    Nous devrions voir un long défilement de journaux se terminant par :

    INFO[2019-11-25T19:51:19.448080400Z] Daemon has completed initialization          
    INFO[2019-11-25T19:51:19.474439300Z] API listen on /var/run/docker.sock

  7. Appuyez sur Entrée. Nous sommes de nouveau dans bash.

À partir de ce moment, nous pouvons essayer de lancer d'autres conteneurs Ă  l'intĂ©rieur de notre conteneur Docker, mais que faire si nous voulons dĂ©marrer un autre conteneur Docker Ă  l'intĂ©rieur de notre conteneur Docker ou si quelque chose ne va pas et que le conteneur "s'Ă©crase" ? Recommencer depuis le dĂ©but.

Conteneur DinD personnel et nouvelles expériences

Comment j'ai lancé Docker à l'intérieur de Docker et ce qui en est résulté
Pour ne pas répéter les étapes décrites ci-dessus encore et encore, j'ai créé mon propre conteneur DinD :

https://github.com/alekslitvinenk/dind

Une solution DinD fonctionnelle m'a permis de lancer Docker à l'intérieur de Docker de maniÚre récursive et d'effectuer des expériences plus audacieuses.
Je vais maintenant décrire une telle expérience (réussie) avec le lancement de MySQL et Nodejs.
Les plus impatients peuvent voir comment cela s'est passé ici.

Lire la vidéo

Alors, commençons :

  1. Lançons DinD en mode interactif. Dans cette version de DinD, nous devons mapper manuellement tous les ports que nos conteneurs fils peuvent utiliser (je travaille déjà là-dessus).

    docker run --privileged -it 
    -p 80:8080 
    -p 3306:3306 
    alekslitvinenk/dind

    Nous accĂ©dons au bash, oĂč nous pouvons immĂ©diatement commencer Ă  lancer des conteneurs enfants.

  2. Lançons MySQL :

    docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql

  3. Nous nous connectons à la base de données comme nous le ferions localement. Nous vérifions que tout fonctionne.

  4. Lançons le deuxiÚme conteneur :

    docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server

    Notez que le mapping de port ici sera exactement 8080:8080, car nous avons déjà mappé le port 80 de l'hÎte au conteneur parent sur le port 8080.

  5. Allons sur localhost dans le navigateur et vérifions que le serveur répond « Hello World ! ».

Dans mon cas, l'expérience avec les conteneurs Docker imbriqués s'est avérée assez positive et je vais continuer à développer le projet et l'utiliser pour le staging. Je pense que c'est une solution beaucoup plus légÚre que Kubernetes et Jenkins X. Mais c'est mon opinion subjective.

Je pense que c'est tout pour l'article d'aujourd'hui. Dans le prochain article, je décrirai plus en détail les expériences avec l'exécution récursive de Docker dans Docker et le montage de répertoires dans des conteneurs imbriqués.

P.S. Si vous trouvez ce projet utile, n'hésitez pas à lui donner une étoile sur GitHub, à le forker et à en parler à vos amis.

Éditer1 J'ai corrigĂ© des erreurs et mis l'accent sur 2 vidĂ©os

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster