Docker w Continuous Integration

Opublikowano 20 maja 2019
3 minuty

Docker jest jednym z najważniejszych narzędzi do deploymentu nowoczesnych aplikacji. Lekkie, w stosunku do maszyn wirtualnych, kontenery przyniosły nam nowy sposób na odpalanie naszych appek, ale jak to z każdą nowością — pojawiają się też nowe problemy.

Continuous Integration

Buildy Dockera są łatwe do uruchomienia, ale problematyczne w większej skali. Trochę przypominają klasycznego pipeline’a z takich narzędzi jak CircleCI, Jenkins czy TravisCI, ale znowu nie są na tyle elastyczne, by móc takie narzędzie zastąpić.

Ciekawostką i źródłem problemów, które napotkałem, jest fakt, że Docker buduje obrazy za pomocą kontenerów. Obrazy Dockera są de facto klonem kontenera, którego używaliśmy w Dockerfile’u. Zatem, jeśli CircleCI czy Google Cloud Build używa kontenerów do pipeline’ów, to czy możemy uruchomić Dockera w Dockerze?

Logo w logo

Incepcja

Sierpnia 2013 roku kontrybucja Jérôme Petazzoni’ego sprawiła, że jest możliwe uruchomienie Dockera w Dockerze. 2 lata później opublikował on post, żeby tego rozwiązania unikać…

https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/

Rozwiązanie

Jérôme Petazzoni sugeruje w swoim artykule, aby współdzielić za pomocą wolumenów ten sam kontekst Dockera z uruchomionym kontenerem. Dzięki temu nasz uruchomiony kontener będzie mógł odpalać równoległe kontenery (czyli też buildy) bez dodatkowych problemów z cachowaniem, bezpieczeństwem i złożonością całego procesu.

A teraz to wszystko w chmurze

Nie pisałbym tego posta, gdyby sprawa była taka prosta

W chmurze chcesz mieć kontenery pod swoją kontrolą. Zwykle sprowadza się to do używania jakiegoś programu sterującego np. scheduler z Kubernetesa. Teraz wyobraź sobie, że twój kontener jest w stanie zburzyć tę hierarchię i samemu sobie tworzyć kontenery. Brzmi jak niezły koszmar admina, a co gorsza nie ma prostego rozwiązania tego problemu.

Docker bez Dockera

A co jeśli Ci powiem, że możesz nie potrzebować Dockera?

Jest taki projekt, który nazywa się kaniko. Googlowski projekt do budowania obrazów Dockera, bez Dockera. Sam projekt obiecuje lepsze cachowanie, kompatybilność i oczywiście brak problemów z Dockera w Dockerze.

Magia, co nie? Nic tylko ściągać i odpalać! Tylko że pewnie byście dostali błąd…

Kaniko logo

kaniko — fajny pomysł, ale jeszcze trzeba poczekać.

Kiedy wielkość ma znaczenie

FROM node:lts-alpine as Builder

Ta linijka działa w Dockerze, ale nie w kaniko.

FROM node:lts-alpine as builder

Ta już działa dobrze. Myślę, że jesteście w stanie wyobrazić sobie moje zażenowanie, kiedy odkryłem takie cudo. Issue na GitHubie już był stworzony.

open /etc/passwd: no such file or directory

Ten problem już mnie przerósł. W skrócie, kaniko nie potrafi wykryć mojego użytkownika. Pomijając fakt, że Docker tak naprawdę nie wymaga tego, żeby taki użytkownik istniał. Pokombinowałem trochę i wyglądało to tak jakby kaniko nie potrafił z własnego cache’u wyciągnąć tej informacji. Szkoda.

https://github.com/GoogleContainerTools/kaniko/issues/477

Jeszcze nie teraz

Gdy to piszę, na GitHubie jest 104 otwartych i 214 zamkniętych issue’ów. To trochę pokazuje, że to jeszcze nie jest pora, by Google rekomendował to narzędzie w swojej dokumentacji. Jest zbyt wiele problemów do naprawienia.

Co do samej idei — są alternatywy. Jedna z najlepszych to img. Jako tako dał radę zbudować mój obraz, ale najpierw musiałem pobrać repo, zbudować img i odpalić budowanie w Dockerze. To nie jest najlepszy UX.

Na koniec, czy to ma jakiekolwiek znaczenie? Większość firm i tak używa gotowych rozwiązań i kilka dodatkowych minut na budowanie obrazu nie robi jakiś wielkich różnic, natomiast jeśli potrzebujesz swojego rozwiązania może warto rozważyć użycie starych, dobrych wirtualek. Ja tymczasem wracam do Cloud Builda, mimo, że nie jest perfekcyjny.

Bartosz Wiśniewski

Everything* Developer, entuzjasta technologii Google, przyjaciel Wrocław JUG, majsterkowicz i piwowar. Zwolennik prostych i pragmatycznych rozwiązań.