Kako sam pokrenuo Docker unutar Dockera i šta je iz njega proizašlo

Zdravo svima! U njegovom prethodni članak, obećao sam da ću govoriti o pokretanju Dockera u Dockeru i praktičnim aspektima korištenja ove lekcije. Vrijeme je da održi obećanje. Iskusni devopser će vjerovatno prigovoriti da oni kojima je potreban Docker unutar Dockera jednostavno proslijede Docker daemon socket sa hosta u kontejner i to će biti dovoljno u 99% slučajeva. Ali nemojte žuriti da me bacate kolačićima, jer ćemo razgovarati o stvarnom pokretanju Dockera unutar Dockera. Ovo rješenje ima mnogo mogućih primjena i ovaj članak je o jednoj od njih, stoga se zavalite i ispravite ruke ispred sebe.

Kako sam pokrenuo Docker unutar Dockera i šta je iz njega proizašlo

Начало

Sve je počelo jedne kišne septembarske večeri kada sam čistio mašinu koju sam iznajmio za 5 dolara na Digital Oceanu, koja je bila zamrznuta zbog činjenice da je Docker svojim slikama i kontejnerima popunio svih 24 gigabajta dostupnog prostora na disku. Ironija je bila u tome što su sve ove slike i kontejneri bili prolazni i bili su potrebni samo za testiranje performansi moje aplikacije svaki put kada se izda nova verzija biblioteke ili okvira. Pokušao sam pisati shell skripte i postaviti cron raspored za čišćenje smeća, ali nije pomoglo: svaki put se to neizbježno završilo tako što je prostor na disku mog servera bio pojeden i server visi (u najboljem slučaju). U nekom trenutku, naišao sam na članak o tome kako pokrenuti Jenkins u kontejneru i kako može kreirati i obrisati build pipelines kroz docker daemon socket proslijeđen u njega. Svidjela mi se ideja, ali sam odlučio ići dalje i pokušati eksperimentirati s direktnim pokretanjem Dockera unutar Dockera. U to vrijeme mi se činilo potpuno logičnim rješenjem da preuzmem Docker slike i napravim kontejnere za sve aplikacije koje su mi bile potrebne za testiranje unutar drugog kontejnera (nazovimo ga scenskim kontejnerom). Ideja je bila da se pokrene scenski kontejner sa -rm zastavicom, koja automatski briše ceo kontejner i sav njegov sadržaj kada se zaustavi. Razmislio sam o Docker imidžu iz samog Dockera (https://hub.docker.com/_/docker), ali ispostavilo se da je preglomazno i ​​nikad nisam uspio da ga natjeram da radi onako kako mi je trebao, a htio sam i sam ići do kraja.

Vježbajte. Konusi

Zamislio sam da kontejner radi onako kako sam trebao i nastavio svoje eksperimente, koji su rezultirali bezbroj pupoljaka. Rezultat mog samomučenja bio je sljedeći algoritam:

  1. Pokrećemo Docker kontejner u interaktivnom načinu rada.

    docker run --privileged -it docker:18.09.6

    Obratite pažnju na verziju kontejnera, idite desno ili lijevo i vaš DinD se pretvara u bundevu. U stvari, stvari se često pokvare kada se objavi nova verzija.
    Moramo odmah ući u školjku.

  2. Pokušavamo saznati koji se kontejneri pokreću (odgovor: nema), ali ipak pokrenimo naredbu:

    docker ps

    Bićete malo iznenađeni, ali ispostavilo se da Docker demon čak i ne radi:

    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. Pokrenimo ga sami:

    dockerd &

    Još jedno neprijatno iznenađenje:

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

  4. Instalirajte iptables i bash pakete (sve je ugodnije raditi u bash-u nego u sh-u):

    apk add --no-cache iptables bash

  5. Pokrenimo bash. Konačno smo se vratili u uobičajenu ljusku

  6. Pokušajmo ponovo pokrenuti Docker:

    dockerd &

    Trebali bismo vidjeti dugačak list dnevnika koji završava sa:

    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. Pritisnite Enter. Vratili smo se u bash.

Od sada možemo pokušati pokrenuti druge kontejnere unutar našeg Docker kontejnera, ali šta ako želimo da pokrenemo još jedan Docker kontejner unutar našeg Docker kontejnera ili nešto pođe po zlu i kontejner se sruši? Počni iznova.

Vlastiti DinD kontejner i novi eksperimenti

Kako sam pokrenuo Docker unutar Dockera i šta je iz njega proizašlo
Kako bih izbjegao ponavljanje gornjih koraka iznova i iznova, napravio sam svoj DinD kontejner:

https://github.com/alekslitvinenk/dind

Radno DinD rješenje dalo mi je mogućnost da rekurzivno pokrećem Docker unutar Dockera i radim avanturističkije eksperimente.
Sada ću opisati jedan takav (uspešan) eksperiment sa pokretanjem MySQL-a i Nodejs-a.
I najnestrpljiviji mogu vidjeti kako je ovdje bilo

Dakle, krenimo:

  1. Pokrećemo DinD u interaktivnom modu. U ovoj verziji DinD-a, moramo ručno mapirati sve portove koje naši podređeni kontejneri mogu koristiti (već radim na tome)

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

    Ulazimo u bash, odakle možemo odmah početi s lansiranjem dječjih kontejnera.

  2. Pokrenite MySQL:

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

  3. Povezujemo se sa bazom podataka na isti način kao što bismo se povezali na nju lokalno. Hajde da se uverimo da sve funkcioniše.

  4. Pokrenite drugi kontejner:

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

    Imajte na umu da će mapiranje portova biti tačno 8080:8080, budući da smo već mapirali port 80 sa hosta na roditeljski kontejner na port 8080.

  5. Idemo na localhost u pretraživaču, uvjerimo se da server odgovara „Hello World!“

U mom slučaju, eksperiment sa ugniježđenim Docker kontejnerima pokazao se prilično pozitivnim i nastavit ću razvijati projekt i koristiti ga za staging. Čini mi se da je ovo mnogo lakše rješenje od Kubernetesa i Jenkinsa X. Ali ovo je moje subjektivno mišljenje.

Mislim da je to sve za današnji članak. U sljedećem članku ću detaljnije opisati eksperimente s rekurzivnim pokretanjem Dockera u Dockeru i montiranjem direktorija duboko u ugniježđene kontejnere.

PS Ako smatrate da je ovaj projekat koristan, dajte mu zvjezdicu na GitHub-u, razdvojite ga i recite svojim prijateljima.

Edit1 Ispravljene greške, fokusiran na 2 videa

izvor: www.habr.com

Dodajte komentar