Czy powinienem używać plików Dockerfiles lub zatwierdzeń obrazu?

81

Jestem trochę zdezorientowany tymi dwiema opcjami. Wydają się być spokrewnieni. Jednak nie są one tak naprawdę kompatybilne.

Na przykład wydaje się, że używanie Dockerfiles oznacza, że ​​nie powinieneś tak naprawdę angażować się w obrazy, ponieważ tak naprawdę powinieneś po prostu śledzić plik Dockerfile w git i wprowadzać w nim zmiany. Wtedy nie ma dwuznaczności co do tego, co jest autorytatywne.

Jednak zmiany obrazu wydają się naprawdę ładne. To tak wspaniałe, że możesz po prostu bezpośrednio zmodyfikować kontener i oznaczyć zmiany, aby utworzyć inny obraz. Rozumiem, że możesz nawet uzyskać coś w rodzaju różnicy systemu plików z historii zatwierdzania obrazu. Niesamowite. Ale wtedy nie powinieneś używać Dockerfiles. W przeciwnym razie, jeśli dokonałeś zatwierdzenia obrazu, będziesz musiał wrócić do swojego pliku Dockerfile i wprowadzić jakąś zmianę, która reprezentuje to, co zrobiłeś.

Więc jestem rozdarty. Podoba mi się idea zatwierdzeń obrazu: nie musisz przedstawiać stanu obrazu w pliku Dockerfile - możesz go po prostu śledzić bezpośrednio. Ale niepokoję się rezygnacją z pomysłu na jakiś rodzaj pliku manifestu, który daje szybki przegląd tego, co jest na obrazie. Niepokojące jest również zobaczenie dwóch funkcji w tym samym pakiecie oprogramowania, które wydają się niekompatybilne.

Czy ktoś ma jakieś przemyślenia na ten temat? Czy używanie zatwierdzeń obrazu jest uważane za złą praktykę? A może powinienem po prostu puścić mój załącznik, aby zamanifestować pliki z dni Puppet? Co powinienem zrobić?

Aktualizacja :

Do wszystkich, którzy uważają, że jest to pytanie oparte na opiniach, nie jestem tego taki pewien. Jest w tym kilka subiektywnych cech, ale myślę, że jest to głównie pytanie obiektywne. Ponadto uważam, że dobra dyskusja na ten temat będzie miała charakter informacyjny.

Na koniec mam nadzieję, że każdy, kto czyta ten post, lepiej zrozumie, w jaki sposób pliki Dockerfiles i zobowiązania dotyczące obrazu odnoszą się do siebie.

Aktualizacja - 2017/7/18 :

Niedawno odkryłem legalne użycie zatwierdzeń obrazu. Właśnie utworzyliśmy potok CI w naszej firmie i podczas jednego etapu potoku nasze testy aplikacji są uruchamiane wewnątrz kontenera. Musimy pobrać wyniki pokrycia z opuszczonego kontenera po wygenerowaniu ich przez proces uruchamiający testy (w systemie plików kontenera) i zatrzymaniu działania kontenera. Używamy do tego zatwierdzeń obrazu, zatwierdzając zatrzymany kontener w celu utworzenia nowego obrazu, a następnie uruchamiając polecenia, które wyświetlają i zrzucają plik pokrycia na standardowe wyjście. Więc warto to mieć. Oprócz tego bardzo konkretnego przypadku używamy Dockerfiles do definiowania naszych środowisk.

David Sanders
źródło
2
Jest tu dużo filozofii, a filozofie ludzi różnią się, co może być złym pytaniem dla SO. Jednak moja filozofia - zawsze chcesz dokładnie wiedzieć, jak odtworzyć dany obraz i mieć pewność, że możesz to zrobić. Korzystając ze złotych obrazów, bardzo łatwo jest nie wiedzieć, jak ktoś przeszedł ze stanu A do stanu B, podczas gdy dzięki automatyzacji, która steruje procesem kompilacji, nie można o tym zapomnieć. Osobiście tak, nazywam Dockerfiles Właściwą Rzeczą, a zatwierdzanie obrazów (jak każdy rodzaj złotego obrazu, który opiera się na ręcznej interwencji w celu zbudowania), jest złem. Ale to ja i YMMV.
Charles Duffy,
@CharlesDuffy Gdzie powinno iść to pytanie, jeśli nie należy do SO?
David Sanders
1
@CharlesDuffy Nawiasem mówiąc, nie zgadzam się, że jest to pytanie oparte na opiniach. Powinna być tutaj prawidłowa odpowiedź, jeśli nie dobra odpowiedź, która zależy od trochę więcej kontekstu. FYI, zagłosowałem za przeniesieniem mojego pytania do Serverfault.
David Sanders,
2
...*wzruszać ramionami*. Mogę przytoczyć konkretne powody moich preferencji, ale czy to czyni je bardziej słusznymi niż konkretne powody, dla których ktoś inny przytacza swoje? Pracowałem z ludźmi, którzy są fanami złotego wizerunku i nie zawsze można kogoś przekonać cytowaniem faktów, ponieważ strony mogą cenić różne cechy rozwiązania w różnym stopniu, więc całkowicie możliwe jest uzgodnienie faktów ale nie zgadzam się z wnioskami. Co jest cechą charakterystyczną pytania opartego na opinii i czego spodziewam się zobaczyć, jeśli rzeczywiście pojawią się tu jacyś fani złotego obrazu.
Charles Duffy,
1
Zastanawiałem się nad tym samym i mam wrażenie (które może być całkowicie błędne), że tak naprawdę jest to ten sam przypadek, co w przypadku vms -> nie chcesz nie wiedzieć, jak odtworzyć obraz vm. W moim przypadku mam do zainstalowania zwykłe skrypty .sh i zastanawiam się, dlaczego nie mogę po prostu nimi zarządzać, uruchamiać dockera i skutecznie je wywoływać i tworzyć w ten sposób obraz złotej wersji. Moje skrypty działają, aby zainstalować go na lokalnym komputerze, a powodem, dla którego chcę używać dockera, jest radzenie sobie z konfliktami wielu wystąpień programów / mam czysty system plików / itp.
Bradford Medeiros

Odpowiedzi:

47

Dockerfiles to narzędzie służące do tworzenia obrazów.

Wynikiem działania docker build .jest obraz z zatwierdzeniem, więc nie można użyć pliku Dockerfile bez utworzenia zatwierdzenia . Pytanie brzmi, czy należy aktualizować obraz ręcznie za każdym razem, gdy coś się zmieni, a tym samym skazać się na przekleństwo złotego obrazu ?

Klątwa złotego obrazu jest straszną klątwą rzuconą na ludzi, którzy muszą nadal żyć z błędnym obrazem bazowym, na którym znajduje się dziura w zabezpieczeniach, aby uruchomić swoje oprogramowanie, ponieważ osoba, która go stworzyła, została dawno pożarta przez starożytnych (lub przeniosła się do nowa praca) i nikt nie wie, skąd wzięli wersję imagemagii, która znalazła się w tym obrazie. i jest jedyną rzeczą, która będzie łączyła się z modułem c ++ dostarczonym przez tego konsultanta, którego syn szefa zatrudnił trzy lata temu, i tak czy owak to nie ma znaczenia, ponieważ nawet jeśli zorientowałeś się, skąd imagemagic pochodzi wersja libstdc ++ używana przez JNI wzywa narzędzie wsparcia, które stażysta z utworzonymi długimi włosami i tak istnieje tylko w nieobsługiwanej wersji Ubuntu.

Arthur Ulfeldt
źródło
3
Wydaje mi się, że to sedno problemu. Jeśli używasz wyłącznie zatwierdzeń graficznych, utkniesz z obrazem podstawowym. Możesz dokonać aktualizacji dystrybucji obrazu, ale to brzmi jak koszmar. Wydaje się, że bardziej korzystne jest, aby tego rodzaju informacje były przedstawiane w przejrzysty sposób w pliku Dockerfile. Myślę, że Docker nie powinien ujawniać zatwierdzeń obrazu w ramach swojego publicznego interfejsu API. Po prostu wydaje się, że nie ma dla nich żadnego uzasadnionego wykorzystania poza celami zilustrowania we wstępnej dokumentacji.
David Sanders
7
Nie wymyśliłem tylko tego przykładu ... :-(
Arthur Ulfeldt
22

Znajomość zarówno zalet, jak i niewygodności rozwiązań to dobry początek. Ponieważ połączenie tych dwóch jest prawdopodobnie właściwą drogą.

Wada: unikaj ślepej uliczki złotego obrazu :

Używanie samych zatwierdzeń jest złe, jeśli nie wiesz, jak odbudować swój obraz. Nie chcesz być w stanie, w którym nie możesz odbudować obrazu . Ten stan końcowy jest tutaj nazywany złotym obrazem, ponieważ obraz będzie jedynym punktem odniesienia, punktem początkowym i końcowym na każdym etapie. Jeśli go zgubisz, będziesz miał dużo kłopotów, ponieważ nie możesz go odbudować. Fatalnym ślepym zaułkiem jest to, że pewnego dnia będziesz musiał odbudować nową (ponieważ na przykład wszystkie biblioteki systemowe są przestarzałe) i nie będziesz miał pojęcia, co zainstalować ... kończąc się dużą stratą czasu.

Na marginesie , jest prawdopodobne, że używanie zatwierdzeń zamiast zatwierdzeń byłoby przyjemniejsze, gdyby dziennik historii był łatwy w użyciu (zapoznaj się z różnicami i powtórz je na innych obrazach), tak jak to jest w git: zauważysz, że git nie ma ten dylemat.

Pro: zgrabne aktualizacje do dystrybucji

Z drugiej strony, zatwierdzanie warstw ma znaczną przewagę pod względem rozproszonych uaktualnień, a tym samym pod względem przepustowości i czasu wdrażania. Jeśli zaczniesz obsługiwać obrazy dockera tak, jak piekarz obsługuje naleśniki (na co pozwala docker), lub chcesz natychmiast wdrożyć wersję testową, z przyjemnością wyślesz niewielką aktualizację w postaci małego zatwierdzenia, a nie zupełnie nowy obraz. Zwłaszcza w przypadku ciągłej integracji dla klientów, w przypadku których poprawki błędów powinny być wdrażane szybko i często.

Spróbuj uzyskać to, co najlepsze z dwóch światów:

W tego typu scenariuszach prawdopodobnie będziesz chciał oznaczyć główną wersję swoich obrazów i powinny one pochodzić Dockerfiles. Możesz zapewnić ciągłe wersje integracyjne dzięki zatwierdzeniom opartym na oznaczonej wersji. Zmniejsza to zalety i niedogodności związane ze scenariuszem zatwierdzania plików Dockerfiles i warstwami. Tutaj kluczową kwestią jest to, że nigdy nie przestajesz śledzić swoich obrazów, ograniczając liczbę zatwierdzeń, które pozwolisz na ich wykonanie.

Więc myślę, że zależy to od twojego scenariusza i prawdopodobnie nie powinieneś próbować znaleźć jednej reguły. Jednak mogą istnieć prawdziwe ślepe zaułki, których naprawdę powinieneś unikać (jako kończące się scenariuszem „złotego obrazu”), niezależnie od rozwiązania.

vaab
źródło
Czy Docker nie odbudowuje inteligentnie obrazów w taki sposób, że nie ma potrzeby ściągania całego nowego obrazu w celu wdrożenia po odbudowaniu ze zmodyfikowanego pliku Dockerfile?
David Sanders
1
@DavidSanders Nie zakończysz pobierania całych nowych obrazów, masz rację. Ale jakakolwiek wczesna instrukcja, która spowoduje zmiany, unieważni wszystkie kolejne warstwy. Notorycznie, „DODAJ” lub jakakolwiek instrukcja zależności to często instrukcje, które można wykonać na końcu za pomocą pojedynczego nowego zatwierdzenia, ale jeśli przebudujesz plik Dockerfile, wygeneruje on zupełnie nowe warstwy. Podjęto pewne wysiłki w zakresie „ADD”, aby być bardziej sprytnym github.com/docker/docker/issues/880 , zobacz także, kierując się podobnymi obawami jpetazzo.github.io/2013/12/01/docker-python-pip-requirements
vaab