Zdravo svima! U njegovom
Начало
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 (
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:
-
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. -
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
-
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
-
Instalirajte iptables i bash pakete (sve je ugodnije raditi u bash-u nego u sh-u):
apk add --no-cache iptables bash
-
Pokrenimo bash. Konačno smo se vratili u uobičajenu ljusku
-
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
-
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 bih izbjegao ponavljanje gornjih koraka iznova i iznova, napravio sam svoj DinD kontejner:
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:
-
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.
-
Pokrenite MySQL:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql
-
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.
-
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.
-
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