Produkcja – Szkoła Dockera https://szkoladockera.pl Najlepsze miejsce dla entuzjastów konteneryzacji i Dockera Thu, 22 Oct 2020 06:29:54 +0000 pl-PL hourly 1 https://wordpress.org/?v=5.7.15 https://szkoladockera.pl/wp-content/uploads/2019/07/cropped-Shelftons-5-32x32.png Produkcja – Szkoła Dockera https://szkoladockera.pl 32 32 Open Container Initiative (OCI) – standard dla obrazów i kontenerów https://szkoladockera.pl/open-container-initiative-oci-standard-docker-image-i-kontenerow/ https://szkoladockera.pl/open-container-initiative-oci-standard-docker-image-i-kontenerow/#comments Thu, 22 Oct 2020 06:28:38 +0000 https://szkoladockera.pl/?p=2188 Docker (jako firma) w 2015 roku dołączył do OCI (Open Container Initative), tym samym znacznie otwierając się na współpracę z innymi firmami w rozwoju konteneryzacji. Był to jeden z przełomowych momentów (również dla nas – użytkowników) i spora zmiana polityki firmy. Powiem tylko tyle, albo aż tyle: Ten wpis powinien Dowiedz się więcej

Artykuł Open Container Initiative (OCI) – standard dla obrazów i kontenerów pochodzi z serwisu Szkoła Dockera.

]]>
Docker (jako firma) w 2015 roku dołączył do OCI (Open Container Initative), tym samym znacznie otwierając się na współpracę z innymi firmami w rozwoju konteneryzacji. Był to jeden z przełomowych momentów (również dla nas – użytkowników) i spora zmiana polityki firmy.

Powiem tylko tyle, albo aż tyle:

Ten wpis powinien przeczytać każdy, kto myśli na poważnie o stosowaniu konteneryzacji.

Gwarantuję – nie pożałujesz. Przejdźmy więc do sedna – czego się dowiesz?


Czego się dowiesz

  • Czym jest organizacja Open Container Initiative i dlaczego powstało
  • Jakie standardy wprowadza OCI
  • Co z pozostałymi narzędziami takimi jak Kubernetes, Podman?
  • Jak obrazy dockerowe mogą działać w Kubernetes?
  • Czy obraz zbudowany w wersji Dockera 17.03 będzie działać na wersji 19.03?


Open Container Initiative (OCI) – co to jest?

Jeśli pracowałeś w większej firmie, to pewnie możesz kojarzyć coś takiego jak ISO. Jest to organizacja zajmująca się „standardyzacją” – przykład: bezpieczeństwo (bhp), zarządzanie jakością (ISO 9001).

Open Container Initiative również możemy określić jako organizację zajmującą się standaryzacją. Zadaniem OCI jest – jak łatwo się domyślić – utrzymanie standardów konteneryzacji.

Organizacja została założona w 2015 roku przez firmy Docker oraz CoreOS (twórcy świetnych narzędzi takich jak Prometheus, Clair czy Quay.io). Z czasem do projektu dołączały inni giganci z doliny krzemowej, min. Google, Amazon, Redhat, czy Microsoft (i wiele wiele innych).

Jakie standardy wyznacza OCI

OCI skupia się na dwóch ważnych sprawach:

Zarówno OCI Image Format jak i OCI Runtime odbiły się sporym echem i miały znaczny wpływ na dalszy rozwój konteneryzacji. W kolejnym akapicie dowiesz się, co dzięki temu my – użytkownicy na tym zyskujemy.


OCI Image Format – czyli specyfikacja obrazów

Skoro tu jesteś, to wiesz czym jest Docker (a jeśli nie wiesz – jest genialnym narzędziem).

Teraz może Cię trochę zaskoczę, ale jak to zwykle w świecie bywa – Docker nie ma już monopolu i doczekał się konkurencji. Nie mam jednak zamiaru dzisiaj o tym mówić, na przykład – jaka jest przyszłość Dockera, albo czy konkurencja go wyprzedzi. To nie jest temat na dziś, ale możesz być spokojny – warto inwestować czas w Dockera. Mówię to naprawdę z czystym sumieniem („a co miałbyś powiedzieć” – pewnie pomyślałeś – „skoro promujesz się jako ekspert dockerowy”).

Jeśli moje słowa Cię nie przekonują, zerknij na Stack Overlow Survey 2020.

TLDR; Docker zajął drugie miejsce w kategorii Most Loved Platforms. Wyprzedził min. Kubernetes oraz chmurę AWS.

OK — pora wrócić do tematu.

Skupmy się na specyfikacji obrazów (OCI Image Format).

Źródło: https://coreos.com/blog/oci-image-specification.html

Łatwo zauważyć, że przed erą OCI mieliśmy dysproporcję pomiędzy standardem obrazów dla Docker i RKT (pierwsza konkurencja dla Dockera?).

Oznaczało to, że obraz zbudowany za pomocą Dockera oraz obraz zbudowany przez RKT – to były dwie podobne, ale jednak inne rzeczy. Ba, nawet sam docker image V1 nie był kompatybilny z docker image v2.2 – tym samym nie było to zgodne z różnymi wersjami Docker Registry.

OCI Image Format wprowadził pełną kompatybilność pomiędzy Dockerem a RKT (na początku) jeśli chodzi o strukturę obrazów, a z czasem dołączyły do tego nowo-powstałe narzędzia – na przykład Podman czy Buildah.

Poniższe polecenie to potwierdzają.

Pobieranie obrazu
$ docker pull dnaprawa/hello-world
$ podman pull dnaprawa/hello-world
$ buildah pull dnaprawa/hello-world
Wypchnięcie obrazu do repozytorium
$ docker push dnaprawa/hello-world
$ podman push dnaprawa/hello-world

A teraz mała uwaga.

OCI Image Format to nie tylko to, co widzisz powyżej – czyli podobieństwo poleceń docker pull image i podman pull image.

To przede wszystkim wspólny standard struktury obrazu (od strony technicznej). Mam nadzieję, że jest już to zrozumiałe. Lećmy dalej. Czas na OCI Runtime.


OCI Runtime – czyli standard uruchamiania kontenerów

OCI Image Format był przełomowy, ale bez standaryzacji runtime’u byłby znacznie mniej użyteczny.

Nadszedł rok 2017 i celebracja powstania pierwszej wersji Open Container Initivative Specification 1.0.

Dzięki temu firmy takie, jak Docker, CoreOs, czy RedHat mogły rozwijać autorskie narzędzia, ale już nie po swojemu, ale według odgórnie ustalonego STANDARDU. My jako użytkownicy zyskaliśmy na tym wiele. Zyskaliśmy pełną dowolność jeśli chodzi o wybór narzędzi do pracy z kontenerami jak również kompatybilność przy wdrażaniu na produkcję.

  • Po pierwsze: do budowania obrazów (Docker)
  • Po drugie: wybierania środowiska uruchomieniowego.

Jak już wcześniej wspominałem, Docker nie jest już jedyną opcją jeśli chodzi o runtime kontenerów. Sama roadmapa na rok 2020 to potwierdza. Docker obecnie skupia się na rozwiązaniach dla programistów – czyli zapewnienie jak najlepszego ekosystemu do codziennej pracy z kontenerami lokalnie, jak również tworzenia i dystrybucji obrazów.

Kilka alternatyw dla Dockera:

  • CRI-O (stworzony z myślą o Kubernetes)
  • ContainerD (stworzony przez Dockera i udostępniony jako open-source, wykrzystywany również przez k8s)
  • Podman (chyba największa „konkurencja” dla Dockera)

To oznacza, że obrazy zgodne z OCI będą działać dla każdego runtime’u kontenerów, który będzie zgodny OCI runtime.


Obraz zgodny z formatem OCI

Obraz zbudowany przy pomocy Dockera jest artefaktem – zgodnym z formatem OCI. Dzięki temu nie jesteśmy całkowicie uzależnieni od ekosystemu Dockera. Naszym wyborem wcale nie musi być Docker Hub jeśli chodzi o repozytorium obrazów.

Nie muszę też przypominać, że obecnie na rynku można dowolnie przebierać w prywatnych Docker Registry. Kilka najpopularniejszych to:

  • Azure Container Registry (ACR)
  • Elastic Container Registry (ECR)
  • Google Container Registry (GCR)
  • Gitlab Container Registry
  • Canister.io

Można by wymieniać prawie bez końca. Nowe rejestry obrazów powstają jak grzyby po deszczu. Co to oznacza?

Zwyczajnie jest na to zapotrzebowanie na rynku. Coraz więcej firm decyduje się na migrację do kontenerów i potrzebuje gdzieś te komercyjne obrazy przechowywać.


Czy obraz zbudowany na wersji Dockera 17.03 będzie działać na nowszej wersji?

Załóżmy, że zaadaptowaliśmy Dockera i kontenery jakiś czas temu, gdy najnowszą wersją Dockera była 17.03. Aplikacja działała przez te wszystkie lata stabilnie, ale chcemy się zmigrować do najnowszej wersji Dockera, albo przejść na Kubernetes. Może pojawić się pytanie:

Czy to będzie działać?

Zacznijmy od tego co się zmieniło w Dockerze na przestrzeni lat. W starszych wersjach, obraz po pobraniu (docker image pull) był inaczej reprezentowany na dysku. Za tę kwestię odpowiedzialny jest storage driver.

Jeżeli jesteś zainteresowany szczegółami działania najnowszego i zarazem rekomendowanego storage drivera – overlay2 – to zajrzyj TUTAJ. W tym filmie dość szczegółowo omawiam jego działanie. Jeżeli z kolei jesteś już na pokładzie mojego programu Docker Maestro, to również znajdziesz tam lekcję o tej tematyce (Moduł: Docker Advanced, lekcja „Przechowywanie warstw obrazu na dysku”)

Może pojawić się pytanie?

Generalnie będzie działać (bo obraz zbudowany na wersji Docker 17.03 jest już zgodny z OCI Image Format), ale mogą być drobne różnicę w działaniu „pod spodem” (głównie w/w storage driver). Więcej na ten temat znajdziesz w „breaking changes”: https://docs.docker.com/engine/breaking_changes/

Docker – kluczowe zmiany

Jak widać dotyczą one Dockera w wersji 1.10. Warto zwrócić uwagę na to zdanie: 

Every Engine release strives to be backward compatible with its predecessors, and interface stability is always a priority at Docker

Tutaj też lista wszystkich starszych realease’ów oraz lista wprowadzonych zmian względem poprzedniej wersji: https://docs.docker.com/engine/release-notes/17.03/


Co dalej?

Mam nadzieję, że ten post pomógł Ci zrozumieć czym jest OCI oraz rozwiał Twoje wątpliwości w kwestii kompatybilności obrazów, a różnymi wersjami Dockera oraz pozostałymi narzędziami takimi jak Kubernetes czy Podman.

Jeżeli masz jakieś dodatkowe pytania – śmiało pisz w komentarzu.

Będę również niezmiernie wdzięczny ??, jeśli podzielisz się tym postem z kolegą albo w Social Media. Możesz również zapisać się do newslettera poniżej i być na bieżąco z kolejnymi wpisami.

Dzięki i do usłyszenia wkrótce!
– Damian

Artykuł Open Container Initiative (OCI) – standard dla obrazów i kontenerów pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/open-container-initiative-oci-standard-docker-image-i-kontenerow/feed/ 2
Komunikacja kontenerów – sieć typu bridge https://szkoladockera.pl/komunikacja-kontenerow-siec-typu-bridge/ https://szkoladockera.pl/komunikacja-kontenerow-siec-typu-bridge/#respond Wed, 24 Jun 2020 08:12:18 +0000 https://szkoladockera.pl/?p=1921 Komunikacja kontenerów Podstawowa rzecz, z jaką prędzej czy później musimy się zmierzyć, to komunikacja między kontenerami. Najprostszy przykład, jaki nasuwa mi się na myśl, to komunikacji kontenera zawierającego frontend z kontenerem zawierającym backend aplikacji. Kolejny przykład – komunikacja backendu z usługami typu Redis czy Elasticsearch. Takich przykładów może być zdecydowanie Dowiedz się więcej

Artykuł Komunikacja kontenerów – sieć typu bridge pochodzi z serwisu Szkoła Dockera.

]]>
Komunikacja kontenerów

Podstawowa rzecz, z jaką prędzej czy później musimy się zmierzyć, to komunikacja między kontenerami. Najprostszy przykład, jaki nasuwa mi się na myśl, to komunikacji kontenera zawierającego frontend z kontenerem zawierającym backend aplikacji.

Kolejny przykład – komunikacja backendu z usługami typu Redis czy Elasticsearch. Takich przykładów może być zdecydowanie więcej. Wszystko zależy od naszych potrzeb i rodzaju wykorzystywanych w projekcie technologii.

Żeby dokładnie zrozumieć, w jaki sposób Docker na to zezwala, trzeba zacząć od podstaw, czyli od tego jak działa sieć typu bridge.

Można śmiało powiedzieć, że jest to najczęściej stosowany sterownik sieciowy — bridge.

Wynika to z tego, że można go wykorzystywać zarówno do celów developerskich, jak również uruchamiając projekt na środowiskach testowych czy produkcyjnych.

Czego się dowiem?


Po pierwsze, poznasz różnicę pomiędzy DOMYŚLNĄ siecią typu bridge (tworzoną przez Dockera po zainstalowaniu) oraz manualnie tworzonymi sieciami.

Po drugie, zobaczysz w praktyce jak tworzyć własne sieci i podpinać do nich kontenery

Po trzecie, zrozumiesz działanie sieci typu bridge

Jest to jedna z lekcji mojego kursu online Docker Maestro.

Łącznie cały kurs to blisko 13 godzin materiału.

Sprawdź agendę i listę wszystkich lekcji na http://dockermaestro.pl



Artykuł Komunikacja kontenerów – sieć typu bridge pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/komunikacja-kontenerow-siec-typu-bridge/feed/ 0
Kontener na produkcji puchnie – czyli problem z miejscem na dysku https://szkoladockera.pl/kontener-mi-puchnie-czyli-problem-z-miejscem-na-dysku/ https://szkoladockera.pl/kontener-mi-puchnie-czyli-problem-z-miejscem-na-dysku/#respond Fri, 19 Jun 2020 07:22:23 +0000 https://szkoladockera.pl/?p=1883 Prędzej czy później możemy natknąć się na sytuację, gdzie kontener na produkcji po jakimś czasie puchnie. Inaczej mówiąc, z czasem jego rozmiar na dysku jest coraz to większy i większy. Przyjrzymy się dzisiaj temu problemowi oraz pokażę potencjalne miejsca, które mogą być tego powodem. Problem puchnięcia kontenera (jak i sposób Dowiedz się więcej

Artykuł Kontener na produkcji puchnie – czyli problem z miejscem na dysku pochodzi z serwisu Szkoła Dockera.

]]>
Prędzej czy później możemy natknąć się na sytuację, gdzie kontener na produkcji po jakimś czasie puchnie. Inaczej mówiąc, z czasem jego rozmiar na dysku jest coraz to większy i większy. Przyjrzymy się dzisiaj temu problemowi oraz pokażę potencjalne miejsca, które mogą być tego powodem.

Problem puchnięcia kontenera (jak i sposób jak tego uniknąć) jest na tyle uniwersalny, że przedstawione w tym artykule praktyki śmiało możesz od razu wdrożyć u siebie.

Gdzie kontener domyślnie zapisuje dane?

Żeby móc zrozumieć gdzie tkwi problem, zaczniemy od podstaw – czyli od tego gdzie domyślnie kontener zapisuje swoje dane.

Po uruchomieniu dowolnego kontenera tworzy nam się minimum jeden proces.

Każdy taki proces ma prawo do modyfikacji systemu plików kontenera. Gdzie zatem zapisywane są te zmiany?

Domyślnym katalogiem, gdzie Docker przechowuje warstwy obrazów jest /var/lib/docker/overlay2. Więcej na ten temat możesz znaleźć TUTAJ.

**Mowa tutaj o kontenerach odpalonych za pomocą Dockera

Oprócz warstw obrazu, na podstawie którego tworzony jest kontener, dodatkowo tworzy się warstwa – writeable layer. Służy ona do przechowywania zmian zachodzących w kontenerze.

Warstwa writeable

Warto jeszcze wspomnieć, że warstwa writeable istnieje do momentu usunięcia kontenera. Chcąc zapisać naniesione w kontenerze zmiany, możemy to zrobić za pomocą polecenia docker container commit <nazwa_lub_id_kontenera> <nowy_obraz:tag>.

To polecenie jest odpowiedzialne za utworzenie nowego obrazu na podstawie kontenera, uwzględniając wszystkie zmiany, jakie zaszły w warstwie writeable.


Co może powodować, że kontener puchnie?

Wiemy już, gdzie kontener zapisuje dane. Teraz czas na przedstawienie dwóch najczęstszych błędów w podejściu do konteneryzacji.

Jak to kiedyś ktoś fajnie powiedział:

„Żyj krótko, umieraj młodo”

Po pierwsze – kontenery zostały stworzone dla aplikacji BEZSTANOWYCH.

Oznacza to, że stan kontenera powinien być wyniesiony na zewnątrz. Jednym z powodów przyrostu miejsca na dysku może być przechowywanie stanu aplikacji w systemie plików kontenera.

Sprawdź, czy i jakie pliki są tworzone podczas działania kontenera

Po drugie – zapisywanie logów aplikacji do pliku

To podejście doskonale znamy z ery przed Dockerem i konteneryzacją. Powiedziałbym, że nadal coś takiego ma miejsce dla aplikacji hostowanych na VM-kach (szczególnie windowsowych).

Sprawdź, gdzie przechowane są logi aplikacji lub usługi uruchomionej w kontenerze

Mam tutaj na myśli logowania do pliku tekstowego (.log). Zaraz po przechowywaniu stanu, jest to najczęstszy powód puchnięcia kontenera.


Jak sprawdzić jakie zmiany zaszły w kontenerze?

Wiemy już, co może być przyczyną puchnięcia kontenera. Jak zatem upewnić się i dokładnie zidentyfikować problem?

Rozważmy to na poniższym przykładzie:

docker container run -it --name mydebian debian:stretch bash
echo 'Tekst, tekst, tekst' > tekst.txt
exit

Co się stało powyżej? Odpalony został kontener o nazwie mydebian, wewnątrz którego stworzony został plik text.txt. Polecenie exit spowodowało zatrzymanie kontenera.


Sprawdzenie co zostało zmienione za pomocą poniższej instrukcji:

docker container diff mydebian
A /tekst.txt
C /root
A /root/.bash_history

Instrukcja docker container diff zwraca to, co zostało zmienione w systemie plików kontenera względem obrazu. Inaczej mówiąc, zwraca to, co zostało zapisane w warstwie writeable.

Docker Maestro – najbardziej obszerny kurs online Dockera po polsku

Poruszana tematyka:

  • Tworzenie własnych obrazów
  • narzędzia wspomagające pracę z Dockerem
  • bezpieczeństwo,
  • orkiestracja
  • zagadnienia DevOps
  • …i wiele, wiele więcej

Sprawdź na http://dockermaestro.pl


Jak sprawdzić ile miejsca na dysku zajmują zmiany?

Pomocne tutaj będzie kolejne polecenie (które częściowo już napewno znasz). Tym poleceniem jest docker container ls (lub docker ps) rozbudowane o dodatkowy parametr -s.

Sprawdźmy całość na poniższym przykładzie:

docker container ls -as

CONTAINER ID    IMAGE            STATUS                        NAMES       SIZE
5ce9595d1e76    debian:stretch   Exited (0) 10 minutes ago     mydebian    70B (virtual 101MB)

Zwróć uwagę na ostatnią kolumne SIZE.

Wartość przed nawiasem, to ilość miejsca na dysku po zmianach zachodzących w kontenerze.

Jeżeli chcemy wyświetlić, ile miejsca zajmują również zatrzymane kontenery, do docker container ls dorzucamy parametr -as.


Rozwiązanie problemu

Mierząc się z problemem puchnięcia danych, zacząłbym od dwóch czynności:

  1. Stan aplikacji nie powinien zostać zapisywany w systemie plików kontenera
  2. Logi kontenera powinny zostać wyniesione do zewnętrznej usługi lub do STDOUT/STDERR

Z reguły są to dwie najczęstsze przyczyn.

Artykuł Kontener na produkcji puchnie – czyli problem z miejscem na dysku pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/kontener-mi-puchnie-czyli-problem-z-miejscem-na-dysku/feed/ 0
LazyDocker – czyli Docker NIE tylko dla leniwych https://szkoladockera.pl/lazydocker-czyli-docker-nie-tylko-dla-leniwych/ https://szkoladockera.pl/lazydocker-czyli-docker-nie-tylko-dla-leniwych/#respond Thu, 23 Apr 2020 06:40:21 +0000 https://szkoladockera.pl/?p=1770 Docker kojarzony jest głównie z terminalem, a co za tym idzie — wpisywaniem poleceń służących do uruchamiania kontenerów i zarządzania nimi. Czy można tego uniknąć i nie wpisywać tych wszystkich poleceń manualnie? Odpowiedź brzmi: TAK. Istnieje wiele narzędzi pozwalających zarządzanie Dockerem z poziomu GUI. Dzisiaj chciałbym pokazać narzędzie, które może Dowiedz się więcej

Artykuł LazyDocker – czyli Docker NIE tylko dla leniwych pochodzi z serwisu Szkoła Dockera.

]]>
Docker kojarzony jest głównie z terminalem, a co za tym idzie — wpisywaniem poleceń służących do uruchamiania kontenerów i zarządzania nimi. Czy można tego uniknąć i nie wpisywać tych wszystkich poleceń manualnie? Odpowiedź brzmi: TAK. Istnieje wiele narzędzi pozwalających zarządzanie Dockerem z poziomu GUI. Dzisiaj chciałbym pokazać narzędzie, które może być ciekawą alternatywą lub po prostu dodatkiem dla terminala. Mowa tutaj o narzędziu — LazyDocker.

Czym jest Lazy Docker?

Jak sama nazwa wskazuje, Lazy Docker to narzędzie stworzone dla osób, których męczy ciągłe wpisywanie różnych poleceń w terminalu. Zamiast ręcznie wpisywać polecenia, możemy uruchomić Lazy Docker, jednocześnie nie wychodząc z terminala. Po jego uruchomieniu otrzymujemy “klikalną” aplikację pozwalająca na podgląd i zarządzanie: lokalnych kontenerów, obrazów oraz volumenów. Dodatkowo posiada również wsparcie dla docker-compose.

Nie można by nie wspomnieć, że LazyDocker jest projektem open-source, dostępnym na GitHubie.

Instalacja Lazy Docker

Narzędzie posiada wsparcie dla różnych systemów operacyjnych. Oznacza, że jesteśmy w stanie uruchomić go zarówno na Linuxie, jak i na Windowsie czy Macu. Osobiście przetestowałem działanie LazyDocker na dwóch systemach: Windows 10 Pro oraz Ubuntu 18.04. W obu przypadkach instalacja przebiegła błyskawicznie, a narzędzia działa bez żadnych problemów.

Instalacja na Windows 

Najprostszym sposobem na zainstalowanie LazyDocker na systemach Windows, jest pobranie gotowego execa. Możemy go pobrać z oficjalnego repozytorium LazyDocker na GitHubie. W moim przypadku był to plik lazydocker_0.8_Windows_x86_64.zip

Wystarczy rozpakować pobrane archiwum .zip i umieścić lazydocker.exe w wybranym przez siebie katalogu.

UWAGA: Aby móc uruchomić LazyDocker w terminalu z dowolnel lokalizacji, polecam dodać katalog, w którym znajduje się lazydocker.exe do zmiennej środowiskowej $PATH. 

Gdy już to zrobimy, wystarczy w CMD lub w Powershellu wpisać lazydocker.  

Instalacja na Linuxie

W przypadku Linuxa, instalacja jest jeszcze prostsza. Wystarczy użyć następującego polecenia: 

curl https://raw.githubusercontent.com/jesseduffield/lazydocker/master/scripts/install_update_linux.sh | bash

Spowoduje to pobranie oraz dodanie binarki LazyDocker do katalogu /usr/local/bin, dzięki czemu otrzymamy również możliwość uruchomienia narzędzia z dowolnej lokalizacji.

Jeżeli instalacja zakończy się pomyślnie, wystarczy w terminalu wpisać polecenie lazydocker


Jak używać Lazy Docker?

Pozostaje nam tylko wpisanie polecenia lazydocker w dowolnym momencie, w którym chcemy z niego z skorzystać.

Po uruchomieniu narzędzia możemy posługiwać się zarówno myszką jak klawiaturą (jak komu będzie wygodniej). Na samym dole okienka znajduje się opis klawiszy, służących do nawigacji po programie.

Podgląd stanu kontenerów

Lazy Docker pozwala na podgląd zarówna działających, jak i zatrzymanych kontenerów. Oznacza to, że jesteśmy w stanie przeglądać logi, sprawdzać konfigurację, czy wyświetlić wszystkie procesy działające w kontenerze.

W zakładce „Config” możemy podejrzeć całą konfigurację kontenera, w tym też zmienne środowiskowe.

Po naciśnięciu na klawiaturze klawisza “b”, pojawia się menu, w którym mamy możliwość zatrzymania czy usunięcia wszystkich kontenerów. 

Powyższy przykład jest tylko początkiem tego, co możemy zrobić za pomocą tego narzędzia. Wybierając klawisz “x” na klawiaturze pojawia nam się kolejne menu, które oferuje znacznie więcej możliwości. 

Dzięki temu możemy już niemal w pełni kontrolować poszczególne kontenery, podobnie jak robimy to za pomocą poleceń w terminalu. Mianowicie: zatrzymać lub usunąć kontener, przejrzeć logi. W łatwy sposób możemy również “wejść do kontenera”. Wystarczy wybrać opcję “run predefined custom command”.

Spowoduje to wygenerowanie polecenia ‘docker exec’.

Po naciśnięciu Entera, wchodzimy do konsoli kontenera:


Przeglądanie warstw obrazów

Chyba najlepsza opcja, jaką oferuje to narzędzie, czyli przeglądanie warstw obrazów. Oznacza to, że możemy podejrzeć z ilu i z jakich warstw składa się poszczególny obraz.

Po prawej stronie ekranu widzimy wszystkie warstwy obrazu, który zaznaczyliśmy. W większości przypadków finalny obraz korzysta z jakiegoś obrazu bazowego (instrukcja FROM). Możemy tutaj podejrzeć, jakie warstwy znajdują się w obrazie bazowym.

Jedną z kluczowych informacji, jakie tutaj możemy uzyskać, jest rozmiar poszczególnych warstw. Zwróć uwagę na instrukcję takie jak EXPOSE czy CMD. Pomimo że dla tych instrukcji tworzone są osobne warstwy, to nie wpływają one na finalny rozmiar obrazu, gdyż zajmują 0 bajtów.

Podgląd volumenów

Ostatnia z oferowanych przez narzędzie Lazy Docker opcja to podgląd informacji o wszystkich volumenach. 

Jeżeli interesuje nas, gdzie fizycznie na dysku przechowywane są dane dla poszczególnych volumenów, to tutaj jesteśmy w stanie się tego dowiedzieć.

Wsparcie dla docker-compose

Oprócz wszystkich wymienionych funkcji, LazyDocker posiada również wsparcie dla docker-compose. Aby móc z niego skorzystać, należy uruchomić lazydocker z katalogu, w którym znajduje się plik docker-compose.yml

Poniżej przedstawiony został przykład WordPressa:

docker-compose

Potrzebujesz zrestartować którąś z usług? Wystarczy użyć „Shift + R”, a pojawi się menu z kilkoma opcjami do wyboru. Uwaga: sam klawisz „r” (bez Shift) spowoduje natychmiastowy restart kontenera.


Podsumowanie

Lazy Docker jest tylko jednym z wybranych narzędzi, które w sposób graficzny pozwalają na wyświetlanie informacji o Dockerze i zarządzanie poszczególnymi jego komponentami. Jednak jego główną zaletą jest fakt, że możemy uruchomić go bezpośrednio w terminalu. Może się to przydać szczególnie w przypadku, gdy łączymy się do zdalnego serwera po SSH i chcemy zbiorczo sprawdzić stan kontenerów czy też podglądnąć logi. Oczywiście, na zdalnym hoście również potrzebujemy go zainstalować, ale zdecydowanie nie jest wielkim problemem. Polecam! 🙂


Artykuł LazyDocker – czyli Docker NIE tylko dla leniwych pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/lazydocker-czyli-docker-nie-tylko-dla-leniwych/feed/ 0
Jak tworzyć testy jednostkowe dla obrazów dockerowych? https://szkoladockera.pl/jak-tworzyc-testy-jednostkowe-dla-obrazow-dockerowych/ https://szkoladockera.pl/jak-tworzyc-testy-jednostkowe-dla-obrazow-dockerowych/#respond Thu, 09 Apr 2020 05:51:35 +0000 https://szkoladockera.pl/?p=1674 Dzisiaj dla odmiany, zamiast formy tekstowej mam dla Ciebie wideo. Temat dosyć niszowy, ale warty uwagi, czyli Docker i testy jednostkowe. Oglądając to wideo, dowiesz się, dlaczego warto tworzyć testy jednostkowe dla obrazów oraz przede wszystkim nauczysz się jak to robić! Film skupia się głównie na praktyce, czyli na pisaniu Dowiedz się więcej

Artykuł Jak tworzyć testy jednostkowe dla obrazów dockerowych? pochodzi z serwisu Szkoła Dockera.

]]>
Dzisiaj dla odmiany, zamiast formy tekstowej mam dla Ciebie wideo. Temat dosyć niszowy, ale warty uwagi, czyli Docker i testy jednostkowe. Oglądając to wideo, dowiesz się, dlaczego warto tworzyć testy jednostkowe dla obrazów oraz przede wszystkim nauczysz się jak to robić! Film skupia się głównie na praktyce, czyli na pisaniu testów i ich uruchamianiu.


Testy jednostkowe – po co to komu?

Tak samo jak tworzymy testy jednostkowe podczas programowania aplikacji, podobnie też, możemy tworzyć testy jednostkowe dla obrazów Dockera.

W przypadku pisania testów jednostkowych dla aplikacji, ich ideą jest sprawdzenie, czy pojedyncza funkcja większego systemu działa tak, jak sobie założyliśmy. Może to być zachowanie pojedynczej metody, czy też klasy. W momencie gdy dana funkcjonalność jest rozbudowana, testy pilnują tego czy całość działa poprawnie.

To tyle tytułem wstępu. Przechodzimy do konkretów.


Testy jednostkowe obrazów

W przypadku obrazów dockerowych, skupiamy się na testowaniu pojedynczych plików lub funkcjonalności znajdujących się w obrazie.

Dla przykładu możemy testować:

  • istnienie i zawartość plików
  • wartości zmiennych środowiskowych
  • poprawność działania narzędzi
  • dystrybucję systemu operacyjnego


Najpierw testy – później kontener

W przypadku „standardowych” testów jednostkowych (dla aplikacji), zasadą TDD (Test Driven Development) w bardzo ogólnym skrócie brzmi: „Najpierw testy – później kod”.

W naszym przypadku (Docker), możemy przełożyć to na następujące stwierdzenie: „Najpierw testy – później kontener”. Rozwijając ten skrót – najpierw tworzymy testy dla obrazu by upewnić się, że działa tak jak to sobie założyliśmy, a dopiero poźniej tworzymy kontener na podstawie tego obrazu.

Wydaje się proste? Zachęcam do oglądania oraz zasubskrybowania kanału!


Kiedy warto tworzyć testy jednostkowe dla obrazów?

Szczególnie poleciłbym tworzenie testów jednostkowych podczas pracy w zespole. Ze swojego doświadczenia wiem, że w większym zespole takie testy często weryfikują przypadkowe błędy. Przede wszystkim mam tutaj na myśli wszelkiego rodzaju literówki oraz błędy spowodowane nieznajomością wiedzy na temat tworzenia plików Dockerfile… 🙂

Innym powodem dla którego warto to robić, jest auto-dokumentacja naszych założeń. Przeglądając takie testy, możemy szybko przypomnieć sobie jakie były początkowe zamiary co do obrazu naszej aplikacji.

Przykładowo:

  • plik A powinien znajdować się w obrazie w katalogu X
  • plik A powinien mieć prawa dostępu 775
  • plik A powinien zawierać frazę o nazwie „ConnectionString”
  • framework niezbędny do działania naszej aplikacji powinien być w wersji X
  • w obrazie powinno znajdować się narzędzie curl
PS. Narzędzie, które wykorzystuję do tworzenia testów to Container Structure Test. Jest to kolejne narzędzie ze stajni Google’a.


Artykuł Jak tworzyć testy jednostkowe dla obrazów dockerowych? pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/jak-tworzyc-testy-jednostkowe-dla-obrazow-dockerowych/feed/ 0
Zmienne środowiskowe w Dockerze https://szkoladockera.pl/zmienne-srodowiskowe-w-dockerze/ https://szkoladockera.pl/zmienne-srodowiskowe-w-dockerze/#respond Thu, 19 Mar 2020 07:08:15 +0000 https://szkoladockera.pl/?p=1508 Przeglądając grupy tematyczne związane z Dockerem, zauważyłem, że wiele osób ma problem z zrozumieniem, w jaki sposób można przekazywać zmienne środowiskowe do obrazu i do kontenera. Zmotywowało mnie to do stworzenia tego artykułu. Z artykułu dowiesz się WSZYSTKO na temat zmiennych środowiskowych w Dockerze. Oczywiście wszystko na przykładach, tak by Dowiedz się więcej

Artykuł Zmienne środowiskowe w Dockerze pochodzi z serwisu Szkoła Dockera.

]]>
Przeglądając grupy tematyczne związane z Dockerem, zauważyłem, że wiele osób ma problem z zrozumieniem, w jaki sposób można przekazywać zmienne środowiskowe do obrazu i do kontenera. Zmotywowało mnie to do stworzenia tego artykułu.

Z artykułu dowiesz się WSZYSTKO na temat zmiennych środowiskowych w Dockerze. Oczywiście wszystko na przykładach, tak by łatwiej było zrozumieć, a następnie móc zastosować u siebie.

Post ten jest kontynuacją serii, w której opisują poszczególne instrukcje Dockerfile. Jeżeli jeszcze nie widziałeś, koniecznie sprawdź COPY vs ADD oraz CMD vs ENTRYPOINT.


Zastosowania instrukcji ENV

Wewnątrz pliku Dockerfile, instrukcja ENV służy do tworzenia zmiennych środowiskowych. Podczas uruchamiania kontenera na podstawie obrazu, możemy nadpisać ich wartość. Taka praktyka jest bardzo często stosowana.

Do czego mogą służyć zmienne środowiskowe? Niemal każda aplikacja ma jakąś konfigurację.

Przykłady:

  • adres IP do bazy danych
  • adres IP do innych usług (Elasticsearch, Vault etc.)
  • zmienne związane z technologią (NODE_ENV, JAVA_VERSION etc)
  • zmienne związane z logiką biznesową


Sposoby na przekazywanie zmiennych środowiskowych

1. Uruchamianie kontenera z terminala

Jeżeli tworzysz kontener korzystając z terminala, do nadpisania lub ustawienia zmiennej środowiskowej służy argument -e KLUCZ=WARTOŚĆ. Poniżej tworzymy kontener WordPressa, przekazując w zmiennych środowiskowych połączenie do bazy danych.

docker run -e WORDPRESS_DB_HOST=10.1.2.3:3306 \
    -e WORDPRESS_DB_USER=user \
    -e WORDPRESS_DB_PASSWORD=somepassword \
    -d wordpress

2. Uruchamianie z pomocą docker-compose

Ten sam efekt możesz uzyskać wewnątrz pliku docker-compose.yml

version: '3.1'

services:

  wordpress:
    image: wordpress
    environment:
       - WORDPRESS_DB_HOST: 10.1.2.3:3306
       - WORDPRESS_DB_USER: user 
       - WORDPRESS_DB_PASSWORD: somepassword
       - WORDPRESS_DB_NAME: exampledb

3. Bezpośrednio w Dockerfile

Istnieją pewne przypadki, dla których na stałe chcemy ustawić zmienną środowiskową. Jak już wyżej wspominałem, może dotyczyć to technologii, w której tworzymy aplikację. Przykładowo, chcemy na stałe ustawić zmienną środowiskową NODE_VERSION. Przykład poniżej.

FROM scratch

# set up node
ENV NODE_VERSION 8.9.4
ENV NODE_DOWNLOAD_SHA 21fb4690e349f82d708ae766def01d7fec1b085ce1f5ab30d9bda8ee126ca8fc
RUN curl -SL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" --output nodejs.tar.gz \
    && echo "$NODE_DOWNLOAD_SHA nodejs.tar.gz" | sha256sum -c - \
    && tar -xzf "nodejs.tar.gz" -C /usr/local --strip-components=1 \
    && rm nodejs.tar.gz \
    && ln -s /usr/local/bin/node /usr/local//nodejs


Stosowanie plików .env

Istnieje możliwość stworzenia pliku o nazwie .env. Zawartość tego pliku może posłużyć do nadpisania wartości znajdujących się w pliku docker-compose.yml. Warto zaznaczyć, że oba pliki muszą znajdować się w tym samym katalogu.

Zawartość pliku .env defniujemy za pomocą schematu klucz=wartość

DB_PORT=5434
DB_USER=myuser

Przykład pliku docker-compose, gdzie to zadziała. Zwróć uwagę w jaki sposób określamy, że zmienna ma zostać podstawiona. Jest to składnia ${DB_PORT} oraz ${DB_USER}

version: '3.2'

services:
  postgres:
    image: postgres:9.6
    ports:
      - ${DB_PORT}:5432
    environment:
        POSTGRES_PASSWORD: secretpassword
        POSTGRES_USER: ${DB_USER}

Aby upewnić się, że wartości są podstawiane prawidłowo wystarczy użyć komendy docker-compose config

$ docker-compose config                  
services:                                
  postgres:                              
    environment:                         
      POSTGRES_PASSWORD: secretpassword  
      POSTGRES_USER: myuser              
    image: postgres:9.6                  
    ports:                               
    - published: 5434                    
      target: 5432                       
version: '3.2'

W miejsce ${DB_USER} została podstawiona wartość myuser, a w miejsce ${DB_PORT} wartość 5434. Wartości te pochodzą z pliku .env. Warto podkreślić, że oba pliki muszą znajdować się w tym samym katalogu.

Gdzie takie podejście może mieć zastosowanie?

Plik docker-compose.yml jest dodawany do kontroli wersji, natomiast plik .env już nie. Dzięki temu, każdy z członków zespołu może mieć inną zawartość pliku .env według własnych potrzeb, co nie będzie powodować żadnych zmian w repozytorium.


Zmienne środowiskowe na hoście nadpisują wpisy w pliku .env

Jeżeli na hoście istnieje zmienna o takiej samej nazwie jak wewnątrz pliku .env, wartość zostanie pobrana z zmiennej środowiskowej hosta! Sprawdźmy to na przykładzie. Na hoście ustawiłem wartość zmiennej środowiskowej JAVA_HOME na C:\Program Files\Java\jdk1.8.0_221

Mamy następujące plik docker-compose.yml, w którym odwołujemy się do ${JAVA_HOME}

version: '3.2'

services:
  myapp:
    image: openjdk:7
    environment:
        JAVA_DIRECTORY: ${JAVA_HOME}

W tym samym katalogu znajduje się również plik .env zawierający zmienną JAVA_HOME=D:/java

JAVA_HOME=D:/java

Teraz pozostaje sprawdzić całość za pomocą polecenia docker-compose config

$ docker-compose config
services:
  myapp:
    environment:
      JAVA_DIRECTORY: C:\Program Files\Java\jdk1.8.0_221
    image: openjdk:7
version: '3.2'

Rezulat? Zamiast wartości zdefiniowanej w pliku .env, została podstawiona wartość zmiennej środowiskowej z hosta! (C:\Program Files\Java\jdk1.8.0_221)


Zmienne w terminalu nadpisują wszystko

Nie można było o tym nie wspomnieć. Definiując zmienną środowiskową wewnątrz terminala, ma ona najwyższy priorytet.

Ustawiamy zmienną środowiskową (system Windows):

$ set JAVA_HOME=D:\shell_variable_path

Obecny stan zmiennych o nazwie JAVA_HOME:

  • na hoście: C:\Program Files\Java\jdk1.8.0_221
  • w pliku .env:  D:\java
  • w terminalu: D:\shell_variable_path

Tradycyjnie sprawdzamy rezultat poleceniem docker-compose config

$ docker-compose config
services:
  myapp:
    environment:
      JAVA_DIRECTORY: D:\shell_variable_path
    image: openjdk:7
version: '3.2'

Tym sposobem mamy potwierdzenie, iż zmienne środowiskowe zdefiniowane w terminalu mają najwyższy priorytet!

UWAGA: Plik .env nie ma nic wspólnego z instrukcjami ENV wewnątrz Dockerfile oraz argumentem `-e` w terminalu!  Oznacza to, że wartości zdefiniowane w pliku .env, NIE trafią bezpośrednio do kontenera, a służą tylko do podstawiania wartości w pliku docker-compose.yml


Inne sposoby na przekazywanie zmiennych środowiskowych do kontenera

Po zbudowaniu obrazu, możemy uruchamiać kontenery i przekazywać do nich zmienne środowiskowe na kilka sposobów. W każdym przypadku, spowoduje to nadpisanie domyślnych wartości zdefiniowanych w Dockerfile.

1. Zmienne środowiskowe z hosta

Jak to działa? Standardowo korzystamy z argumentu -e, ale z małą różnicą. Podajemy tylko nazwę zmiennej, bez wartości. W ten sposób docker pobiera zmienną środowiskową zdefiniowaną w terminalu (jeżeli istnieje) lub w systemie hosta.

Obecnie w terminalu wartość zmiennej JAVA_HOME=D:\shell_variable_path

Uruchamiamy kontener w trybie interaktywnym z konsolą, wskazując -e JAVA_HOME. Następnie wewnątrz kontenera, wyświetlamy zawartość zmiennej.

$ docker run -it -e JAVA_HOME alpine sh
/ # $JAVA_HOME 
sh: D:\shell_variable_path

Widzimy, że wewnątrz kontenera została podstawiona wartość z hosta (a dokładnie z terminala hosta).

2. Wartości z pliku (env_file)

Tworzymy plik o dowolnej nazwie, a jego zawartość powinna opierać się o wpisach typu klucz=wartość. Dla przykładu, plik ten będzie miał nazwę my_env_file (bez żadnego rozszerzenia), a jego zawartość będzie następująca:

VARIABLE_NAME=variable_value

Uruchamiamy kontener z parametrem env (spowoduje wyświetlenie wszystkich zmiennych środowiskowych) wskazując na plik my_env_file:

$ docker run --env-file=my_env_file alpine env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=77929624bad0
VARIABLE_NAME=variable_value
HOME=/root

Możemy również wykorzystać to samo podejście w pliku docker-compose.yml, dodając wpis env_file: <ścieżka_do_pliku>

version: '3.2'

services:
  alpine:
    image: alpine
    env_file: my_env_file


Podsumowanie

Stosowanie zmiennych środowiskowych w Dockerze jest czymś naturalnym i często wykorzystywanym. Na przykładzie WordPressa widzimy, że nawet oficjalne obrazy, które możemy znaleźć na Docker Hubie stosują ten mechanizm. Warto go zatem znać i rozumieć jak działa.

Mam nadzieję, że nieco pomogłem zrozumieć Ci jak działają zmienne środowiskowe w Dockerze, lub bynajmniej post ten spowodował odświeżenie Twojej dotychczasowej wiedzy. Ważne, że w razie wątpliwości można tutaj wrócić i rozwiać swoje wątpliwości, do czego gorąco zachęcam!



Artykuł Zmienne środowiskowe w Dockerze pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/zmienne-srodowiskowe-w-dockerze/feed/ 0
Distroless Docker Images vs Alpine Linux https://szkoladockera.pl/distroless-docker-images-vs-alpine-linux/ https://szkoladockera.pl/distroless-docker-images-vs-alpine-linux/#respond Thu, 12 Mar 2020 07:34:50 +0000 https://szkoladockera.pl/?p=1403 Distroless Images Na początku, gdy zaczęto używać kontenerów, większość z nas traktowała je jako bardziej wydajne VM-ki. Jeżeli spojrzymy na obrazy na Docker Hubie, publikowane przez dostawców systemów operacyjnych, możemy dostrzec, że w większości przypadków kopiują oni do obrazów to, co do tej pory dostarczali jako cały system operacyjny. Zwykle, Dowiedz się więcej

Artykuł Distroless Docker Images vs Alpine Linux pochodzi z serwisu Szkoła Dockera.

]]>
Distroless Images

Na początku, gdy zaczęto używać kontenerów, większość z nas traktowała je jako bardziej wydajne VM-ki. Jeżeli spojrzymy na obrazy na Docker Hubie, publikowane przez dostawców systemów operacyjnych, możemy dostrzec, że w większości przypadków kopiują oni do obrazów to, co do tej pory dostarczali jako cały system operacyjny. Zwykle, obrazy są okrajane tylko o niektóre, niepotrzebne ich zdaniem paczki / binarki.

Pomimo tego, obrazy nadal są za ciężkie, zajmując na dysku setki megabajtów. To spowodowało wzrost popularności dystrybucji takich jak Alpine. Czy kiedykolwiek wcześniej wykorzystywałeś Alpine, zanim zaczęto go używać w obrazach dockerowych? Ja nie.

Dlaczego zaczęto stosować Alpine Linux do obrazów bazowych?

Głównym powodem, dla którego zaczęto na potęgę wykorzystywać Alpine, jest oczywiście jego rozmiar. 5 MB — tyle waży obraz Alpine. W porównaniu do np. Debiana (125 MB) lub Ubuntu (188MB) jest to spora różnica. W pewnym momencie, z uwagi na rozmiar obrazów, Docker Hub zaczął mieć problemy wydajnościowe. Te problemy z czasem zostały zażegnane, lecz popularność Alpine nadal rosła.

Pojawia się zatem pytanie. Co jest złego w stosowaniu Alpine Linux?

Docker alpine

Wady Alpine Linux

Pomimo że Alpine Linux jest ultralekki, nadal jego zachowanie może być porównane do wirtualnej maszyny. Dlaczego?

Stosując obraz Alpine, nadal możemy korzystać z shell’a a nawet z managera pakietów. No właśnie, manager pakietów…

1. Brakujące pakiety

Zdarzały się przypadki, w których brakowało podstawowych pakietów. Coś, co innych dystrybucjach takich jak Debian mamy pewne. Przykład – brakująca paczka MySQL.

2. Różnice w repozytoriach dla różnych wersji Alpine

Każda wersja Alpine Linux posiada własny manager pakietów i niestety nie przechowuje archiwalnych wersji. Przykładowo w wersji Alpine 3.5, dostępna paczka Node.js może być w wersji 2.0, w Alpine 3.4 będzie już w wersji 1.9. Chcąc używać Node.js w wersji 1.9, musimy opierać się o starszą wersje Alpine.

3.  Brak glibc

Jeśli cokolwiek w życiu kompilowałeś (np. na studiach) to zakładam że w 90% przypadków korzystałeś z glibc. Alpine zastąpił glibc własnym stworem o nazwie musl. Osobiście, natknąłem się na ten problem w momencie w którym aplikacja webowa uruchomiona w kontenerze na bazie Debiana działała poprawnie, a wewnątrz kontenera na bazie Alpine, już nie

Jeżeli chcesz by Twoja aplikacja działała poprawnie, musisz skompilować ją w środowisku wykorzystującym musl.

4. Stabilność

Obecnie obraz dockerowy Alpine Linux jest rozwijany jako projekt open-source.

Poszperałem nieco tu i ówdzie i co znalazłem?

Okazuje się, że aktywnie rozwija go zaledwie kilka osób. A do zatwierdzenia zmiany w repozytorium wystarczą dwie (!), powtarzam, dwie osoby (na dzień pisania tego artykułu). Przykład pull requesta — TUTAJ

Czy w swoich obrazach, chcesz bazować na czymś, czego jakość sprawdza dwie osoby?

Zauważyłem też, że repozytorium z powyższego linka, w którym widnieją osoby rozwijające, zostało przeniesione do https://github.com/alpinelinux/docker-alpine, gdzie kontrybutorem jest tylko jedna osoba. Na Docker Hubie widnieje już adres nowego repozytorium Githuba. Dlaczego?

5. Wydajność

Szukając informacji o wydajności Alpine, natrafiłem na post na Reddicie, w którym mowa o aplikacji Node.js. Jeden z użytkowników twierdzi, że jego aplikacja działała 15% wolniej używając Alpine jako obraz bazowy w porównaniu do Debiana.

Inny przykład to aplikacja w Pythonie. Bardzo ciekawy artykuł opisujący wady Alpine Linux w porównaniu do Ubuntu.

6. Bezpieczeństwo

Nie wiele narzędzi do skanowania obrazów „radzi” sobie z obrazami bazującymi na Alpine. Jeżeli skanowałeś obrazy narzędziami takimi jak Anchore czy Clair, które nie wykryły żadnych podatności – polecałbym porównać wyniki skanowania z wynikami uzyskanymi narzędziem trivy.


Distroless Docker Images

W związku z problemami z rozmiarem obrazów oraz wyżej wymienionymi wadami Alpine Linux nie kto inny jak firma Google, zaprezentowała światu Distroless Images.

Nie muszę chyba przypominać, że to jak zachowuje się nasz kontener, zależy od obrazu, na podstawie którego został utworzony. Co zatem takiego kryje się pod słowem distroless?

Ideą distroless jest zbudowanie minimalnego obrazu zawierającego tylko aplikację i jej zależności.

$ docker pull gcr.io/distroless/base

Rozmiar powyższego obrazu to tylko ~16 MB.

Obraz jest pozbawiony managera pakietów, shell’a (!) oraz innych programów, które możesz znaleźć w tradycyjnej dystrybucji.

UWAGA: brak shella oznacza, że nie mamy możliwości wejścia do kontenera poprzez wykonanie polecenia docker exec -it <container> sh

$ docker run -it gcr.io/distroless/base /bin/sh
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: 
starting container process caused 
"exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown

Brak shell’a został wprowadzony celowo, z uwagi na bezpieczeństwo. Często przekazujemy sekrety do kontenera jako zmienne środowiskowe. Może być to na przykład connection string do bazy danych. W tradycyjnych obrazach atakujący może go wyłuskać, wchodząc do kontenera i podglądnąć zmienne środowiskowe.

Pojawia się zatem problem – Jak można debuggować kontener, jeżeli nie ma shella?

W razie takiej potrzeby, jednym z podejść jest stworzenie kontenera bazującego na obrazie z tagiem :debug. Obrazy z tym tagiem, mają wbudowany shell.


Przykłady obrazów distroless

Obrazy distroless bazują na na Debianie (wersja 9 i 10). Wszystkie gotowe obrazy możemy znaleźć w oficjalnym repozytorium Google – gcr.io.

Oprócz „czystych” obrazów, możemy znaleźć obrazy dedykowane do języków/technologii. Jednak według Google’a, należy je stosować z rozwagą (na czas pisania tego artykułu, nie są rekomendowane na produkcję)

Tworzenie własnych obrazów w oparciu o distroless

Chcąc samemu tworzyć obrazy distroless, możemy użyć dwóch podejść.

Pierwszym podejściem jest wykorzystanie Docker multi-stage builds. Wystarczy zastosować się do dwóch kroków:

  1. Wybierz obraz bazowy odpowiadający Twojej aplikacji
  2. Stwórz Dockerfile w trybie multi-stage build

Poniżej znajdziesz Dockerfile budujący obraz distroless dla aplikacji Node.js.

FROM node:10.17.0 AS build-env
ADD . /app
WORKDIR /app

FROM gcr.io/distroless/nodejs
COPY --from=build-env /app /app
WORKDIR /app
CMD ["hello.js"]

Budujemy obraz tradycyjnie:

$ docker build . -t myapp:distroless


Druga metoda na tworzenie obrazów distroless to użycie narzędzia Bazel.

Podstawową kwestią jest stworzenie pliku BUILD.  Poniżej znajduję się zawartość pliku BUILD. Cały przykład, wraz z plikami *.js znajdziesz TUTAJ

package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_docker//container:container.bzl", "container_image")

# These examples are adapted from:
# https://howtonode.org/hello-node
container_image(
    name = "hello",
    base = "//experimental/nodejs:nodejs",
    cmd = ["hello.js"],
    files = [":hello.js"],
)

container_image(
    name = "hello_http",
    base = "//experimental/nodejs:nodejs",
    cmd = ["hello_http.js"],
    files = [":hello_http.js"],
    ports = ["8000"],
)

load("@io_bazel_rules_docker//contrib:test.bzl", "container_test")

container_test(
    name = "hello_test",
    configs = ["testdata/hello.yaml"],
    image = ":hello",


Podsumowanie

Pomimo lekkości obrazu Alpine, okazuje się że nie jest on taki idealny. Licznie opublikowane problemy z wydajnością oraz braki niektórych pakietów mogą dawać do myślenia.

Alternatywą są obrazy distroless, które oprócz lekkości, zapewniają bezpieczeństwo. Ich atutem jest fakt, że są rozwijane przez Google oraz stosowane w rozwiązaniach produkcyjnych wraz z Kubernetes.

Na sam koniec, jeśli zastanawiasz się co wybrać – Distroless vs Alpine, wystarczy odpowiedzieć sobie na pytanie: Czy wolisz stosować coś co jest rozwijane przez firmę Google czy też coś nad czym czuwają dwie osoby?

Dla mnie odpowiedź jest prosta.

Artykuł Distroless Docker Images vs Alpine Linux pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/distroless-docker-images-vs-alpine-linux/feed/ 0
Skanowanie obrazów Dockerowych pod kątem bezpieczeństwa z Anchore https://szkoladockera.pl/skanowanie-obrazow-dockerowych-pod-katem-bezpieczenstwa-z-anchore/ https://szkoladockera.pl/skanowanie-obrazow-dockerowych-pod-katem-bezpieczenstwa-z-anchore/#respond Thu, 06 Feb 2020 06:30:12 +0000 https://szkoladockera.pl/?p=1157 W dzisiejszym artykule skupimy się na temacie skanowania obrazów pod kątem bezpieczeństwa za pomocą narzędzia Anchore. Pokażę Ci, w jaki sposób możesz przeskanować obraz Twojej aplikacji lub oficjalnie obrazy dostępne na Docker Hub. Spis treści W artykule poruszymy następujące kwestie: Dlaczego do skanowania obrazów używam Anchore? Architektura Anchore Anchore – Dowiedz się więcej

Artykuł Skanowanie obrazów Dockerowych pod kątem bezpieczeństwa z Anchore pochodzi z serwisu Szkoła Dockera.

]]>
W dzisiejszym artykule skupimy się na temacie skanowania obrazów pod kątem bezpieczeństwa za pomocą narzędzia Anchore. Pokażę Ci, w jaki sposób możesz przeskanować obraz Twojej aplikacji lub oficjalnie obrazy dostępne na Docker Hub.

Spis treści

W artykule poruszymy następujące kwestie:

  • Dlaczego do skanowania obrazów używam Anchore?
  • Architektura Anchore
  • Anchore – wymagania wstępne i instalacja
  • Skanowanie obrazów: centos, nginx, aspnetcore

Skanowanie obrazów

Aby sprawdzić działanie Anchore, posłużymy się trzema oficjalnymi obrazami z Docker Hub. Będzie to kolejno: centos, nginx oraz aspnetcore.

Dlaczego wybrałem te obrazy?

Docker opublikował raport prezentujący najpopularniejsze obrazy w roku 2019.
Zarówno nginx jak i centos, znalazły się w TOP 10 najczęściej wyszukiwanych obrazów.

Obraz aspnetcore jest mi szczególnie bliski, ponieważ jak pewnie wiesz, na co dzień oprócz tematów związanych z Dockerem, zajmuję się projektowaniem i tworzeniem aplikacji, korzystając z frameworka ASP NET Core.

Źródło: https://www.docker.com/blog/introducing-the-docker-index/?fbclid=IwAR3QCy9cAnMrEO4L-PwRvlDrqbRCZWAlHF-jg9JZbhO8D141DVMflyHZI_Y


Dlaczego Anchore?

Anchore jest moim zdaniem jednym z najlepszych narzędzi open-source służącym do wykrywania podatności w obrazach Dockerowych.


Po pierwsze, Anchore posiada bardzo dobrą dokumentację. Czy wyobrażasz sobie korzystanie z jakiegoś narzędzia bez dokumentacji? Ja nie.

Po drugie posiada community, które ciągle wspomaga jego rozwój. Z reguły, gdy rozpoznaje narzędzia open-source, skupiam się właśnie na tych dwóch czynnikach – dokumentacja i community.

Na GitHubie można znaleźć wiele interesujących projektów, jednak często brak dokumentacji sprawia, że giną one śmiercią naturalną. Jeżeli Anchore nie spełnia Twoich oczekiwań, sprawdź koniecznie mój wpis na temat innych narzędzi, które polecam. Wpis dostępny jest TUTAJ.

Po trzecie, Anchore integruje się z systemami CI / CD. Przykładowo, istnieje plugin integrujący Anchore z Jenkinsem. Uważam jednak, że Anchore może zostac zintegrowany niemal z każdym narzędziem CI / CD. Wynika to z jego architektury, którą za chwilę poznasz.

Polecam przeczytać chociaż pierwsze fragmenty poprzedniego wpisu, aby zrozumieć skąd podatności znajdują się w obrazach oraz dlaczego należy je skanować.


Anchore – architektura

Spójrz proszę na poniższy obrazek, prezentujący architekturę Anchore. Komponenty w czerwonej ramce, są cześcią Anchore Enterprise – czyli płatnej wersji Anchore. My skupimy się głównie na komponentach wchodzących w skład Anchore open-source (w niebieskich ramkach).

Jak łatwo zauważyć na powyższym diagramie, Anchore został podzielony na 4 warstwy:

  • Warstwa kliencka
  • Warstwa API
  • Warstwa stanu
  • Warstwa „robocza”

Anchore CLI – to nic innego jak klient, który komunikuje się za pomocą REST z Anchore API.

Anchore API – kluczowa część architektury. Odbiera komunikaty od Anchore CLI a następnie komunikuje się z komponentami z warstwy State Tier

Catalog – odpowiada za zarządzanie stanem. Przechowuje dane niestrukturalne – np. pliki w formacie JSON (rezultat skanowania)

Policy Engine – wczytuje rezultaty skanowania pochodzące z Catalog a następnie normalizuje niestrukturalne dane, tak by można było je filtrować oraz weryfikować pod kątem zdefiniowanych polityk.

SimpleQueque – kolejka PostgreSQL używana przez pozostałe komponenty do asynchronicznych operacji (rozkazy, notyfikacje)

Analyzer – pobiera obrazy z Docker Registry (Docker Hub lub inne) i przeprowadza skanowanie. Odbiera rozkazy od SimpleQueque, a następnie po zakończeniu skanowania przekazuje rezultaty do Catalog oraz PolicyEngine.


Anchore – wymagania wstępne

Rekomendacją ze strony producenta jest minimum 4GB RAM i 10GB miejsca na dysku. Upewnij się, że maszyna na której będzie działać Anchore, spełnia te wymagania. Osobiście przeprowadziłem testy na maszynie z 2GB RAM i okazało się nie wystarczająco. Na szczęście była to maszyna wirtualne na Azure, więc przesunięcie suwaka w prawo załatwiło sprawę 🙂

Ważne. Całość poniżej prezentowanych poleceń została wykonana na Linuxie, a dokładniej na Ubuntu 18.04.


Anchore – instalacja

Istnieją dwie opcje na zainstalowanie Anchore – sposób tradycyjny oraz poprzez użycie Dockera. Jak można się łatwo domyślić – wybrałem opcję nr 2 🙂

Okey, czas na konfigurację i instalację. Postępuj zgodnie z instrukcją poniżej.

Stwórz katalog do przechowywania plików konfiguracyjnych

$ mkdir ~/aevolume && cd ~/aevolume

Skopiuj pliki konfiguracyjne

Wewnątrz obrazu anchore-engine, znajduje się plik docker-compose.yml, który posłuży do uruchomienia Anchore. Pobierz zatem obraz anchore-engine.

$ docker pull docker.io/anchore/anchore-engine:latest

Skopiuj plik docker-compose.yml do Twojego katalogu roboczego.

$ docker create --name ae docker.io/anchore/anchore-engine:latest
$ docker cp ae:/docker-compose.yaml ~/aevolume/docker-compose.yaml
$ docker rm ae

Upewnij się, że plik docker-compose.yml został poprawnie skopiowany do Twojego katalogu roboczego.

$ ls ~/aevolume
docker-compose.yaml

Pobierz i uruchom kontenery Anchore

Przejdź do katalogu roboczego i pobierz wszystkie niezbędne obrazy

$ cd ~/aevolume
$ docker-compose pull

Teraz nadszedł czas na uruchomienie. Jest tutaj jednak mała uwaga. Podczas pierwszego uruchomienia, Anchore musi pobrać bazę wszystkich podatności na dysk. Może to potrwać do 10 minut. Dlatego przed uruchomieniem całości, należy ustawić zmienną środowiskową COMPOSE_HTTP_TIMEOUT. Dla bezpieczeństwa ustawimy ją na 1000 sekund. Jeżeli Twoje połączenie internetowe jest kiepskie, ta wartość może być niewystarczająca.

$ COMPOSE_HTTP_TIMEOUT=1000 docker-compose up -d

Starting aevolume_anchore-db_1 ... done
Starting aevolume_engine-catalog_1 ... done
Starting aevolume_engine-api_1           ... done
Starting aevolume_engine-analyzer_1      ... done
Starting aevolume_engine-policy-engine_1 ... done
Starting aevolume_engine-simpleq_1       ... done

Upewnij się, że wszystkie usługi zostały uruchomione poprawnie

$ docker-compose ps

             Name                            Command                       State                   Ports
-----------------------------------------------------------------------------------------------------------------
aevolume_anchore-db_1             docker-entrypoint.sh postgres    Up                      5432/tcp
aevolume_engine-analyzer_1        /docker-entrypoint.sh anch ...   Up (health: starting)   8228/tcp
aevolume_engine-api_1             /docker-entrypoint.sh anch ...   Up (health: starting)   0.0.0.0:8228->8228/tcp
aevolume_engine-catalog_1         /docker-entrypoint.sh anch ...   Up (health: starting)   8228/tcp
aevolume_engine-policy-engine_1   /docker-entrypoint.sh anch ...   Up (health: starting)   8228/tcp
aevolume_engine-simpleq_1         /docker-entrypoint.sh anch ...   Up (health: starting)   8228/tcp

Sprawdź status Anchore Engine za pomocą następującego polecenia:

$ docker-compose exec engine-api anchore-cli system status

Service analyzer (anchore-quickstart, http://engine-analyzer:8228): up
Service simplequeue (anchore-quickstart, http://engine-simpleq:8228): up
Service policy_engine (anchore-quickstart, http://engine-policy-engine:8228): up
Service catalog (anchore-quickstart, http://engine-catalog:8228): up
Service apiext (anchore-quickstart, http://engine-api:8228): up

Engine DB Version: 0.0.12
Engine Code Version: 0.6.1

I teraz ważna kwestia. Po mimo, że Anchore wystartował poprawnie, podczas pierwszego uruchomienia aktualizuje on bazę danych CVE. Zanim zaczniesz skanowanie obrazów, upewnij się ze cała baza danych została zsynchronizowana.

$ docker-compose exec engine-api anchore-cli system feeds list


Feed               Group           LastSync                      RecordCount
nvdv2              nvdv2:cves      pending                       0
vulnerabilities    alpine:3.10     2020-02-03T05:52:16.614182    1725
vulnerabilities    alpine:3.3      2020-02-03T05:52:44.576739    457
vulnerabilities    alpine:3.4      2020-02-03T05:52:52.426065    681
vulnerabilities    alpine:3.5      2020-02-03T05:53:04.347937    875
vulnerabilities    alpine:3.6      2020-02-03T05:53:19.113143    1051
vulnerabilities    alpine:3.7      2020-02-03T05:54:37.856837    1395
vulnerabilities    alpine:3.8      2020-02-03T05:55:02.512212    1486
vulnerabilities    alpine:3.9      2020-02-03T05:55:30.023154    1558
vulnerabilities    amzn:2          2020-02-03T05:56:00.192895    299
vulnerabilities    centos:5        pending                       1000
vulnerabilities    centos:6        pending                       0
vulnerabilities    centos:7        pending                       0
vulnerabilities    centos:8        pending                       0
vulnerabilities    debian:10       pending                       0
vulnerabilities    debian:11       pending                       0
vulnerabilities    debian:7        pending                       0
vulnerabilities    debian:8        pending                       0

Twoja instancja Anchore będzie w pełni gotowa, gdy wszystkie wartości w kolumnie RecordCount będą większe od 0.


Skanowanie obrazu Centos:7

Aby przeskanować dowolny obraz przy użyciu Anchore, wykorzystamy anchore-cli. Pierwszym krokiem jest pobranie obrazu przez Anchore-Engine. W naszym przypadku będzie to Centos:7.

$ docker-compose exec engine-api anchore-cli \
    image add docker.io/library/centos:7

Co ważne, pobieranie z Docker Hub zostanie zainicjalizowane w tle. Aby sprawdzić, czy obraz jest już gotowy do skanowania, skorzystaj z polecenia:

$ docker-compose exec engine-api anchore-cli \
    image wait docker.io/library/centos:7

Anchore umożliwia weryfikacje zainstalowanych pakietów oraz modułów. Służy do tego następujące polecenie:

$  docker-compose exec engine-api anchore-cli \
     image content docker.io/library/centos:7

os: available
files: available
npm: available
gem: available
python: available
java: available

Wreszcie nadchodzi wyczekiwane skanowanie.

$  docker-compose exec engine-api anchore-cli \
     image vuln docker.io/library/centos:7 all

I co? Jaki jest jego rezultat? Zżera cię ciekwość? Więc proszę – oto wyniki skanowania obrazu centos:7

Vulnerability ID   Package                          Severity   Fix                   Vulnerability URL
RHSA-2019:4190     nss-3.44.0-4.el7                 High       0:3.44.0-7.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-softokn-3.44.0-5.el7         High       0:3.44.0-8.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-softokn-freebl-3.44.0-5.el7  High       0:3.44.0-8.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-sysinit-3.44.0-4.el7         High       0:3.44.0-7.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-tools-3.44.0-4.el7           High       0:3.44.0-7.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-util-3.44.0-3.el7            High       0:3.44.0-4.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2020:0227     sqlite-3.7.17-8.el7              High       0:3.7.17-8.el7_7.1    https://access.redhat.com/errata/RHSA-2020:0227

W obrazie centos:7, Anchore wykrył aż 7 podatności oznaczonych wysokim ryzykiem! A przecież jest to obraz pochodzący z sprawdzonego i oficjalnego źródła – Docker Hub’a.


Skanowanie obrazu Nginx

Na tapetę weźmiemy obraz nginx w wersji 1.17.8 (najbardziej aktualny w czasie pisania tego artykułu).

Postępujemy analogicznie jak w przypadku obrazu centos. Najpierw przy wykorzystaniu polecenia add, pobieramy obraz z Docker Huba i czekamy aż obraz zostanie pobrany przez Anchore.

$ docker-compose exec engine-api anchore-cli \
    image add docker.io/library/nginx:1.17.8
$ docker-compose exec engine-api anchore-cli \
    image wait docker.io/library/nginx:1.17.8

Gdy obraz jest gotowy – skanujemy całość poleceniem:

$  docker-compose exec engine-api anchore-cli \
     image vuln docker.io/library/nginx:1.17.8 all

I co otrzymujemy? 🙂

Vulnerability ID        Package                                   Severity          Fix                    CVE Refs        Vulnerability URL
CVE-2005-2541           tar-1.30+dfsg-6                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2005-2541
CVE-2007-5686           login-1:4.5-1.1                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-5686
CVE-2007-5686           passwd-1:4.5-1.1                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-5686
CVE-2007-6755           libssl1.1-1.1.1d-0+deb10u2                Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-6755
CVE-2009-4487           nginx-1.17.8-1~buster                     Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2009-4487
CVE-2010-0928           libssl1.1-1.1.1d-0+deb10u2                Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-0928
CVE-2010-4051           libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4051
CVE-2010-4051           libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4051
CVE-2010-4052           libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4052
CVE-2010-4052           libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4052
CVE-2010-4756           libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4756
CVE-2010-4756           libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4756
CVE-2011-3374           apt-1.8.2                                 Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3374
CVE-2011-3374           libapt-pkg5.0-1.8.2                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3374
CVE-2011-3389           libgnutls30-3.6.7-4                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3389
CVE-2011-4116           perl-base-5.28.1-6                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-4116
CVE-2013-0340           libexpat1-2.2.6-2+deb10u1                 Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-0340
CVE-2013-4235           login-1:4.5-1.1                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4235
CVE-2013-4235           passwd-1:4.5-1.1                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4235
CVE-2013-4392           libsystemd0-241-7~deb10u2                 Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4392
CVE-2013-4392           libudev1-241-7~deb10u2                    Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4392
CVE-2014-8130           libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2014-8130
CVE-2015-9019           libxslt1.1-1.1.32-2.2~deb10u1             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2015-9019
CVE-2016-9085           libwebp6-0.6.1-2                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2016-9085
CVE-2017-11164          libpcre3-2:8.39-12                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-11164
CVE-2017-15232          libjpeg62-turbo-1:1.5.2-2+b1              Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-15232
CVE-2017-16231          libpcre3-2:8.39-12                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-16231
CVE-2017-16232          libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-16232
CVE-2017-17973          libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-17973
CVE-2017-18018          coreutils-8.30-3                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-18018
CVE-2017-5563           libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-5563
CVE-2017-7245           libpcre3-2:8.39-12                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-7245
CVE-2017-7246           libpcre3-2:8.39-12                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-7246
CVE-2017-9117           libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-9117
CVE-2017-9937           libjbig0-2.1-3.1+b2                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-9937
CVE-2018-1000654        libtasn1-6-4.13-3                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-1000654
CVE-2018-10126          libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-10126
CVE-2018-14048          libpng16-16-1.6.36-6                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-14048
CVE-2018-14550          libpng16-16-1.6.36-6                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-14550
CVE-2018-20796          libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-20796
CVE-2018-20796          libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-20796
CVE-2018-6829           libgcrypt20-1.8.4-5                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-6829
CVE-2019-1010022        libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010022
CVE-2019-1010022        libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010022
CVE-2019-1010023        libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010023
CVE-2019-1010023        libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010023
CVE-2019-1010024        libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010024
CVE-2019-1010024        libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010024
CVE-2019-1010025        libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010025
CVE-2019-1010025        libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010025
CVE-2019-19882          login-1:4.5-1.1                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-19882
CVE-2019-19882          passwd-1:4.5-1.1                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-19882
CVE-2019-6129           libpng16-16-1.6.36-6                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-6129
CVE-2019-9192           libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9192
CVE-2019-9192           libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9192
CVE-2019-9893           libseccomp2-2.3.3-4                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9893
CVE-2019-9923           tar-1.30+dfsg-6                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9923
CVE-2019-18224          libidn2-0-2.0.5-1                         Unknown           2.0.5-1+deb10u1                        https://security-tracker.debian.org/tracker/CVE-2019-18224
CVE-2019-20388          libxml2-2.9.4+dfsg1-7+b3                  Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-20388
CVE-2020-7595           libxml2-2.9.4+dfsg1-7+b3                  Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2020-7595

Dużo tego – przyznaję, że nie liczyłem ile wpisów wykrył nam Anchore. Na szczęście wszystkie wykryte wpisy są w statusie „Nieistotne” lub „Nieznane”.

Skanowanie na mojej maszynie zajęło mniej niż 3 sekundy, co również dobrze świadczy o Anchore.

Skanowanie obrazu ASP NET Core

Posłużymy się najnowszym wydaniem (na czas pisania tego artykułu) obrazu ASP NET Core w wersji 3.1. Będziemy postępować analogicznie jak w przypadku centos i nginx. W skrócie – pobieramy obraz, upewniamy się że obraz został pobrany, skanujemy.

$ docker-compose exec engine-api anchore-cli \
    image add mcr.microsoft.com/dotnet/core/aspnet:3.1
$ docker-compose exec engine-api anchore-cli \
    image wait mcr.microsoft.com/dotnet/core/aspnet:3.1

Gdy obraz będzie gotowy – skanujemy 🙂

$  docker-compose exec engine-api anchore-cli \
     image vuln mcr.microsoft.com/dotnet/core/aspnet:3.1 all

Jako że jest to bliska mi technologia, sam byłem bardzo ciekawy rezultatów.

Sięgając pamięcią wstecz, przypominam sobie, że w oficjalnym obrazie ASP NET Core 2.2 było wiele podatności o wysokim ryzyku, które musiałem ręcznie „fixować”.
Na szczęście w wersji 3.1 – bynajmniej Anchore, nie wykrywa żadnych podatności o wysokim ryzyku.

Tak jak w przypadku nginx, wykryte zostały tylko „Nieistotne” oraz „Nieznane”.

Vulnerability ID        Package                                     Severity          Fix                    CVE Refs        Vulnerability URL
CVE-2004-0971           libgssapi-krb5-2-1.17-3                     Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2004-0971
CVE-2004-0971           libk5crypto3-1.17-3                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2004-0971
CVE-2004-0971           libkrb5-3-1.17-3                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2004-0971
CVE-2004-0971           libkrb5support0-1.17-3                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2004-0971
CVE-2005-2541           tar-1.30+dfsg-6                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2005-2541
CVE-2007-5686           login-1:4.5-1.1                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-5686
CVE-2007-5686           passwd-1:4.5-1.1                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-5686
CVE-2007-6755           libssl1.1-1.1.1d-0+deb10u2                  Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-6755
CVE-2007-6755           openssl-1.1.1d-0+deb10u2                    Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-6755
CVE-2010-0928           libssl1.1-1.1.1d-0+deb10u2                  Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-0928
CVE-2010-0928           openssl-1.1.1d-0+deb10u2                    Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-0928
CVE-2010-4051           libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4051
CVE-2010-4051           libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4051
CVE-2010-4052           libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4052
CVE-2010-4052           libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4052
CVE-2010-4756           libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4756
CVE-2010-4756           libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4756
CVE-2011-3374           apt-1.8.2                                   Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3374
CVE-2011-3374           libapt-pkg5.0-1.8.2                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3374
CVE-2011-3389           libgnutls30-3.6.7-4                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3389
CVE-2011-4116           perl-base-5.28.1-6                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-4116
CVE-2013-4235           login-1:4.5-1.1                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4235
CVE-2013-4235           passwd-1:4.5-1.1                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4235
CVE-2013-4392           libsystemd0-241-7~deb10u2                   Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4392
CVE-2013-4392           libudev1-241-7~deb10u2                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4392
CVE-2015-3276           libldap-2.4-2-2.4.47+dfsg-3+deb10u1         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2015-3276
CVE-2015-3276           libldap-common-2.4.47+dfsg-3+deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2015-3276
CVE-2017-11164          libpcre3-2:8.39-12                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-11164
CVE-2017-14159          libldap-2.4-2-2.4.47+dfsg-3+deb10u1         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-14159
CVE-2017-14159          libldap-common-2.4.47+dfsg-3+deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-14159
CVE-2017-16231          libpcre3-2:8.39-12                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-16231
CVE-2017-17740          libldap-2.4-2-2.4.47+dfsg-3+deb10u1         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-17740
CVE-2017-17740          libldap-common-2.4.47+dfsg-3+deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-17740
CVE-2017-18018          coreutils-8.30-3                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-18018
CVE-2017-7245           libpcre3-2:8.39-12                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-7245
CVE-2017-7246           libpcre3-2:8.39-12                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-7246
CVE-2018-1000654        libtasn1-6-4.13-3                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-1000654
CVE-2018-20796          libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-20796
CVE-2018-20796          libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-20796
CVE-2018-5709           libgssapi-krb5-2-1.17-3                     Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-5709
CVE-2018-5709           libk5crypto3-1.17-3                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-5709
CVE-2018-5709           libkrb5-3-1.17-3                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-5709
CVE-2018-5709           libkrb5support0-1.17-3                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-5709
CVE-2018-6829           libgcrypt20-1.8.4-5                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-6829
CVE-2019-1010022        libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010022
CVE-2019-1010022        libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010022
CVE-2019-1010023        libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010023
CVE-2019-1010023        libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010023
CVE-2019-1010024        libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010024
CVE-2019-1010024        libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010024
CVE-2019-1010025        libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010025
CVE-2019-1010025        libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010025
CVE-2019-19882          login-1:4.5-1.1                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-19882
CVE-2019-19882          passwd-1:4.5-1.1                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-19882
CVE-2019-9192           libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9192
CVE-2019-9192           libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9192
CVE-2019-9893           libseccomp2-2.3.3-4                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9893
CVE-2019-9923           tar-1.30+dfsg-6                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9923
CVE-2019-18224          libidn2-0-2.0.5-1                           Unknown           2.0.5-1+deb10u1                        https://security-tracker.debian.org/tracker/CVE-2019-18224
CVE-2019-5481           curl-7.64.0-4                               Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-5481
CVE-2019-5481           libcurl4-7.64.0-4                           Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-5481
CVE-2019-5482           curl-7.64.0-4                               Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-5482
CVE-2019-5482           libcurl4-7.64.0-4                           Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-5482

Podsumowanie

Zachęcam Cię mocno do weryfikacji Twoich obrazów pod kątem bezpieczeństwa. Pamiętaj, że tworząc Dockerfile, w 90% przypadków korzystamy z polecenia FROM i wywołujemy obraz bazowy, który może mieć podatności. Te podatności przejdą bezpośrednio na Twój finalny obraz. Jeżeli będzie to obraz wykorzystywany do celów developerskich – nie będzie to aż tak groźne. Ryzyko pojawi się, gdy wdrożysz obraz z podatnościami na produkcję.

Polecam wprowadzenie nawyku skanowania obrazów. Niekoniecznie musi to być narzędzie Anchore.

PS. Jeżeli znasz jakieś inne ciekawe narzędzie, koniecznie podziel się nim w komentarzu!

Artykuł Skanowanie obrazów Dockerowych pod kątem bezpieczeństwa z Anchore pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/skanowanie-obrazow-dockerowych-pod-katem-bezpieczenstwa-z-anchore/feed/ 0
Docker i mikroserwisy – połączenie idealne? https://szkoladockera.pl/docker-i-mikroserwisy-polaczenie-idealne/ https://szkoladockera.pl/docker-i-mikroserwisy-polaczenie-idealne/#respond Thu, 30 Jan 2020 06:00:59 +0000 https://szkoladockera.pl/?p=1118 Dlaczego architektura mikroserwisów zyskała na popularności w ostatnich latach? Są różne opinie. Jedni są zdania, że trzeba było o czymś opowiadać na konferencjach :). Drudzy z kolei twierdzą, że to konteneryzacja oraz w dużej mierze Docker pozwoliły na ekspansję mikroserwisów. Intro Zaczynasz projekt i masz do skonfigurowania standardowo 3 środowiska. Dowiedz się więcej

Artykuł Docker i mikroserwisy – połączenie idealne? pochodzi z serwisu Szkoła Dockera.

]]>
Dlaczego architektura mikroserwisów zyskała na popularności w ostatnich latach?

Są różne opinie. Jedni są zdania, że trzeba było o czymś opowiadać na konferencjach :).

Drudzy z kolei twierdzą, że to konteneryzacja oraz w dużej mierze Docker pozwoliły na ekspansję mikroserwisów.

Intro

Zaczynasz projekt i masz do skonfigurowania standardowo 3 środowiska. Dev, Staging, Prod. Czy wyobrażasz sobie deployment aplikacji złożonej z 10 mikroserwisów bez kontenerów? Owszem – teraz mamy chmurę i jej usługi pozwalające wdrożyć aplikację, bez martwienia się o infrastrukturę.

Niestety, ale z doświadczenia wiem, że chmura nie nadaje się do wszystkiego. W niektórych firmach, istnieją pewne regulacje o przechowywaniu danych. Dane mają być przechowywane na serwerach firmy. Koniec kropka. A jeśli jest to korporacja – nie ponegocjujesz.

Ktoś powie – trzymaj dane on-premise, a hostuj mikroserwisy w chmurze. Owszem, czasami takie rozwiązania się sprawdzają. Osobiście jestem fanem dobierania narzędzi do problemu, a nie odwrotnie. W związku z tym nie neguję żadnego podejścia.


Czym są mikroserwisy?

Tworzenie aplikacji mikroserwisowych jest sztuką. Tak – sztuką. To sztuka budowania „dużych” systemów oraz łamania zasad towarzyszących nam przez ostatnie dekady – zasad monolitu.

Architektura mikroserwisowa wprowadza inne podejście do tworzenia modułów systemu. Polega to na wydzielaniu logicznych grup, które mają odzwierciedlenie w procesach biznesowych. Idealnym określeniem, które ciężko mi przetłumaczyć na język polski, jest business capability.

Przekładając to na język techniczny, mikroserwisy powinny byc projektowane tak, że jeżeli zmieni się logika biznesowa dla danego business capability to zmiana w pojedynczym mikroserwisie nie wymusza zmiany w drugim. Jest to mocno związane z pojęciem bounded context, pochodzącym z książki Erica Evansa – Domain Driven Design.

Wdrożenia nowych wersji stają się mniej bolesne, ponieważ wdrażamy tylko tę mikrousługę, w której nastąpiła zmiana w kodzie.

Źródło: https://medium.com/@hoangbkit/the-hype-microservices-6088c0871ef4


Przykład Netflixa

Na pewno wiesz co to Netflix. A czy zastanawiałeś się kiedykolwiek, jak to działa, że Netflixa oglądają miliony ludzi na całym świecie, a mimo to nie ma problemów z oglądnięciem ulubionego serialu wieczorem w godzinach szczytu?

Netflix chętnie dzieli się wiedza w temacie swojej architektury. W sieci można znaleźć wiele ciekawych artykułów na ten temat. Na przełomie roku 2008/2009, Netflix jako jeden z pierwszych na świecie zaczął korzystać z mikroserwisów. Było to spowodowane rosnącą liczbą klientów oraz problemami z wydajnością dotychczasowej aplikacji monolitycznej.

W 2009 roku mało kto słyszał o mikroserwisach a rozwiązania chmurowe nie były jeszcze tak popularne jak teraz. Netflix był pierwszym, który złamał bariery zamieniając architekturę monolitu na architekturę mikroserwisową, równocześnie porzucąjąc własne serwery i przenosząc się do chmury AWS.

Oczywiście w tym czasie, nie było jeszcze Dockera i takiego bumu na kontenery. Dopiero z czasem Netflix zaczął korzystać z benefitów wynikających z konteneryzacji.

Obecnie całość aplikacji składa się z 500+ (brzmi zabawnie? :D) skonteneryzowanych mikroserwisów. Warto jednak podkreślić, że przez lata Netflix pracował nad swoim „idealnym” środowiskiem. Stworzył nawet narzędzie Chaos Monkey, które losowo ubija mikroserwisy na produkcji (!), po to by mieć pewność, że są przygotowani na awarię i posiadają dobry recovery plan.


Wyzwania w budowaniu aplikacji mikroserwisowych

Monitoring

Monitorowanie mikroserwisów rozproszonych na wielu hostach może być trudne. Zamiast śledzenia jednej aplikacji, musimy monitorować ich kilka (naście, dziesiąt), jednocześnie skupiając się na poprawnym działaniu całego systemu.

Wydajność infrastruktury

Każdy mikroserwis zużywa znacznie mniej zasobów niż aplikacje monolityczne, ale pamiętaj, że liczba mikroserwisów może rosnąć wraz z rozwojem systemu. Bez odpowiedniego zarządzania, wiele pojedynczych hostów może zużywać tyle mocy obliczeniowej i pamięci, albo i więcej, niż architektura monolityczna.

Nieefektywne zużywanie zasobów

Weźmy jako przykład Amazon Web Services, w którym istnieje dolny limit zasobów, które możesz przypisać do danego zadania. Mikroserwisy mogą być tak małe, że wystarczy im zdecydowanie mniej mocy obliczeniowej niż minimalna opcja EC2 (Amazon Elastic Compute Cloud). Może to powodować marnowanie zasobów i generowanie niepotrzebnych kosztów.

Bardziej skomplikowany deployment

Podstawową zaletą mikroserwisów jest niezależność co do technologii, w których są tworzone. Każdy język programowania jest jednak zależny od własnych bibliotek i frameworków. Powstaje zatem problem utrzymywania wersji bibliotek dla różnych technologii. Zwiększa to zdecydowanie nakłady pracy (i koszty) oraz sprawia, że ​​wdrożenia są skomplikowane.

I właśnie tutaj, z pomocą przychodzą kontenery oraz Docker.


Docker na pomoc

W przeciwieństwie do maszyn wirtualnych, dzięki Dockerowi nie musimy stale konfigurować systemu w nadziei na uniknięcie konfliktów wersji bibliotek czy frameworków. Docker rozwiązuje ten problem, jednocześnie gwarantując nam, że wszystkie mikroserwisy będą działać niezależnie od siebie a zarazem będą niezależne od systemu operacyjnego.

Izolacja

Tworząc pojedynczy kontener dla każdego z mikroserwisów, możesz uruchomić wiele z nich jednocześnie na pojedynczym hoście.

Sprawniejszy i wspólny model wdrażania

Chcąc uruchomić projekt oparty o architekturę mikroserwisową lokalnie na twoim laptopie, nie musisz konfigurować całego środowiska, instalować bibliotek czy zależności. Możesz skorzystać z Docker image, dokładnie tego samego, który działa na produkcji.

Wspieranie różnych technologii programowania

SoftwareHouse’y często posiadają zespoły pracujące w różnych technologiach. Dzięki konteneryzacji, są w stanie pracować nad pojedynczym komponentem aplikacji niezależnie od technologii czy języków programowania

Optymalizacja zużycia mocy obliczeniowej

Zamiast sztywnego przypisywania zasobów sprzętowych per mikroserwis, wiele pojedynczych mikroserwisów zapakowanych w kontenery, może być uruchomiona na pojedynczym hoście współdzieląc moc obliczeniową (CPU, pamięć).

Skalowalność

Może nie tworzymy systemów na miarę Netflixa (chciałbym :D), ale obecne wymagania biznesowe sprawiają, że możemy potrzebować skalowania. Z pomocą przychodzą narzędzia do orchestracji, zaczynając od najprostszego orchestratora – Docker Compose poprzez Docker Swarm i Kubernetes.


Skąd czerpać wiedzę o mikroserwisach?

Dla osób chcących zgłębić swoją wiedzę w temacie mikroserwisów w oparciu o technologię .NET jest znakomita okazja!

UWAGA: Z kodem rabatowym SZKOLADOCKERA, otrzymasz 10% zniżki na zakup!
Więcej informacji o kursie znajdziesz TUTAJ

Mikroserwisy.NET to kompleksowy kurs online wprowadzający w świat nowoczesnej architektury mikroserwisów z wykorzystaniem metodyki Event Storming oraz najpopularniejszych technologii takich jak: .NET Core, Docker, Kubernetes, Istio Service Mesh i wiele innych!


Podsumowanie

Chyba nikt nie odważy się zaprzeczyć, że Docker mocno przyczynił się do rozwoju i popularności mikroserwisów. Pomimo, że wcześniej istniały narzędzia do konteneryzacji – mało kto o nich wiedział, a jeszcze mniej osób z tego korzystała.

Należy jednak podkreślić fakt, że pojęcie mikroserwisy nie równa się kontenerom. Oczywiście mikroserwisy i kontenery bardzo dobrze ze sobą się łączą. Warto pamiętać, że mikroserwisy są zdecydowanie czymś więcej. Decydując się na taka architekurę, musisz mieć świadomość trudności jakie cię czekają i przygotować się na najgorsze. Mam tutaj na myśli dobry recovery plan, dla każdego klocka twojej architektury.


Artykuł Docker i mikroserwisy – połączenie idealne? pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/docker-i-mikroserwisy-polaczenie-idealne/feed/ 0
Docker Monitoring – 7 Rzeczy O Których Warto Wiedzieć https://szkoladockera.pl/docker-monitoring-7-rzeczy-o-ktorych-warto-wiedziec/ https://szkoladockera.pl/docker-monitoring-7-rzeczy-o-ktorych-warto-wiedziec/#comments Thu, 23 Jan 2020 06:28:15 +0000 https://szkoladockera.pl/?p=998 Decydując się na użycie Dockera produkcyjnie, oprócz benefitów związanych z skalowalnością czy łatwością przenoszenia na różne środowiska, czekają nas również wyzwania. Bez wątpienia, jednym z największych wyzwań jest monitoring. Aby móc kontrolować nasze środowiska, potrzebujemy również zrozumieć co naprawdę dzieje się wewnątrz skonteneryzowanych aplikacji. Monitoring jest pierwszym krokiem ku temu. Jesteśmy Dowiedz się więcej

Artykuł Docker Monitoring – 7 Rzeczy O Których Warto Wiedzieć pochodzi z serwisu Szkoła Dockera.

]]>

Decydując się na użycie Dockera produkcyjnie, oprócz benefitów związanych z skalowalnością czy łatwością przenoszenia na różne środowiska, czekają nas również wyzwania. Bez wątpienia, jednym z największych wyzwań jest monitoring. Aby móc kontrolować nasze środowiska, potrzebujemy również zrozumieć co naprawdę dzieje się wewnątrz skonteneryzowanych aplikacji. Monitoring jest pierwszym krokiem ku temu. Jesteśmy w stanie śledzić na bieżąco stan naszego środowiska i wykrywać potencjalne problemy wydajnościowe.

1. Czym jest monitoring kontenerów

Monitoring kontenerów to proces śledzenia aplikacji zawartych w kontenerze poprzez kolekcjonowanie i analizowanie metryk dotyczących ich wydajności. Proces ten jest bardziej złożony i różni się nieco od monitorowania tradycyjnych aplikacji działających na maszynach wirtualnych. Wynika to z ogólnej natury kontenerów, które są emferyczne. Pomimo złożoności problemu nie możemy „nie monitorować”. Chcąc zapewnić wysoką wydajność oraz dostępność naszych aplikacji, nadal kwestia ta jest krytyczna.
Oprócz monitorowania aplikacji działających w kontenerach, musimy również skupić się na monitorowaniu…kontenerów. Mam tutaj na myśli zasoby sprzętowe przypisane do kontenera takie jak pamięć operacyjna czy zużycie procesora.

Źródło: https://unsplash.com/

2. Benefity monitoringu

Nie mając monitoringu, nie mamy pewności, że obecna wydajność aplikacji spełnia nasze początkowe założenia. Nie wiemy czy wraz ze wzrostem użytkowników aplikacja działa ciągle tak samo.
Innymi słowy, nie jesteśmy w stanie zmierzyć wydajności naszego systemu.

Obecnie wymagania co do dostępności aplikacji (biznesowych) są wygórowane. Nie możemy sobie pozwolić na przestoje w działaniu aplikacji. Dzięki monitoringu jesteśmy w stanie wychwycić wszelkie niedociągnięcia, zanim dowiemy się o nich od użytkowników systemu.


Każdy monitoring jest lepszy niż brak monitoringu.


3. Różnice w monitoringu

Monitorowanie kontenerów nie różni się całkowicie od tradycyjnego monitoringu. Nadal potrzebujemy zbierać logi, metryki oraz używać health-checków. Podstawową różnicą jest dodatkowa warstwa do monitorowania, wynikająca z architektury i budowy kontenerów oraz Dockera. Mówi się, że dobry monitoring powinien pokrywać wszystkie warstwy całego ekosystemu.


4. Idealny system monitoringu

  1. Po pierwsze powinien zawierać podstawowe parametry takie jak bieżące wykorzystanie pamięci czy procesora hosta. Dodatkowo należy pamiętać, że każdy kontener ma przydzielone limity procesora i pamięci. Dzięki takim metrykom, jesteśmy w stanie ustalić i zdecydować w którą stronę należy skalować naszą solucję. Jeżeli mamy do dyspozycji wolne zasoby, być może wystarczy tylko zwiększenie samego limitu dla poszczególnych kontenerów.
  2. Po drugie, monitorowanie kontenerów powinno pokrywać również infrastrukturę. W przypadku środowisk opartych o Docker Swarm czy Kubernetes – musimy zwrócić uwagę na wskaźniki procesora nie tylko dla pojedynczej maszyny, ale dla całego klastra. Dzięki temu możemy również zadecydować o kierunku skalowania.
  3. Po trzecie, oprócz infrastruktury, nie możemy zapomnieć o monitorowaniu samej aplikacji działającej wewnątrz kontenera. Przykładowo, jeżeli mamy do czynienia z aplikacją webową, należy monitorować czasy odpowiedzi czy liczbę żadąń do serwera. Nie jesteśmy w stanie uzyskać tych informacji np. z runtime’u mówiącemu nam o cyklu życia kontenerów.

Podsumowując, każda warstwa wewnątrz naszego ekosystemu może wpłynąć na finalne działanie skonteneryzowanej aplikacji. Tworząc monitoring, warto pomyśleć o takim, który obejmie wszystkie warstwy – począwszy od infrastruktury, aż po warstwę aplikacji.


5. Najprostszy monitoring – Docker API

Nie możemy do końca nazwać to monitorowaniem, aczkolwiek uważam że każdy powinien wiedzieć o takiej możliwości. Chodzi tutaj o wbudowane komendy CLI: min. docker logs czy docker stats wykorzystujące Docker API do wyświetlania odpowiednio logów oraz aktualnego zużycia zasobów sprzętowych.

Podstawowa wbudowana komenda służąca do wyświetlania logów z kontenera to docker logs. Zwykle by z niej skorzystać, musimy najpierw użyć komendy docker ps, by uzyskać ID kontenera, z którego logi chcemy wyświetlić.

docker logs CONTAINER_ID

Przykładowo, aby wyświetlić tylko 10 ostatnich logów z kontenera, należy użyć polecenia:

docker logs CONTAINER_ID --tail 10

$ docker logs postgres --tail 10
LOG:  MultiXact member wraparound protections are now enabled
LOG:  database system is ready to accept connections
LOG:  autovacuum launcher started

PostgreSQL Database directory appears to contain a database; Skipping initialization

LOG:  database system was shut down at 2020-01-20 07:59:45 UTC
LOG:  MultiXact member wraparound protections are now enabled
LOG:  database system is ready to accept connections
LOG:  autovacuum launcher started

Drugim istotnym poleceniem jest docker stats. Wyświetla „na żywo” stan zużycia zasobów przez poszczególne kontenery (uruchomione) oraz przypisane limity.

CONTAINER ID        NAME                                 CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
dda1311d5d21        visitbooker_visitbooker-postgres_1   0.01%               8.07MiB / 1.934GiB    0.41%               3.75kB / 0B         26.8MB / 2.85MB     6   
2296b6704d71        mvc_db_1                             1.35%               634.7MiB / 1.934GiB   32.05%              1.11MB / 325kB      1.23GB / 44.3MB     134 

Jak widać w powyższym listingu, dla dwóch kontenerów pamięć operacyjna została przydzielona równo po 1.934 GiB.

Warto to kontrolować i uniknąć sytuacji, w której limity zasobów sprzętowych mogą okazać się niewystarczające. Warto również wiedzieć, że jeżeli sami nie wyspecyfikujemy limitu zasobów dla danego kontenera, Docker ustawi je automatycznie.


6. Analiza logów

Zamiast samodzielnie i manualnie używać Docker API (docker logs) do analizowania logów pochodzących z kontenerów, możemy ułatwić i zautomatyzować ten proces, wykorzystując dostępne narzędzia open-source.

Obecnie popularnym narzędziem do gromadzenia logów jest Elasticsearch, który najczęściej łączy się z innymi narzędziami tworząc tzw. ELK Stack

Po pierwsze, może to być Logstash – służący do zasilania Elastica danymi oraz Kibana do ich wizualizacji.

Źródło: https://www.elastic.co/guide/en/kibana/7.x/xpack-logs.html

7. Zbieranie metryk

Do zbierania metryk jednym z najbardziej popularnych i zarazem rekomendowanych przez Dockera narzędzi jest Prometheus. Należy podkreślić, że nie służy on wyłącznie do monitoringu kontenerów. Używając tego narzędzia możemy monitorować: serwery, bazy danych, wirtualne maszyny. Krótko mówiąc, prawie wszystko 🙂

Prometheus jest narzędziem open-source, jednak jego popularność jest na tyle duża, że jest używany przez duże organizacje. Dodatkowo jest prężnie rozwijany przez społeczność.

Jako ciekawostkę można przytoczyć fakt, iż w 2016 roku Prometheus dołączył do Cloud Native Computing Foundation, jako drugi projekt project po Kubernetes.

W połączeniu z narzędziem takim jak Grafana, służącym do wizualizacji danych, możemy uzyskać podobny efekt jak poniżej.

Źródło: https://prometheus.io/docs/visualization/grafana/

Podsumowanie

Nie ważne z ilu kontenerów składa się Twój system. Monitoring zawsze będzie kluczową kwestią, aby zapewnić ciągłość działania aplikacji. Jako DevOps czy osoba odpowiadająca za projekt potrzebujesz zintegrowanego monitoringu, dzięki któremu możesz śledzić wydajność i odpowiednio reagować.

Czas poświęcony na konfiguracje środowiska oraz potencjalne koszty dedykowanej infrastruktury z pewnością szybko się spłacą. Z biznesowego punktu widzenia, jest to również kluczowa kwestia. Często większe firmy zawierają kontrakty, w których definiują kary umowne w razie niedostępności systemów.

W kolejnym artykule, przedstawię obszerny monitoring oparty o Prometheusa. Cała solucja będzie składać się z dodatkowych narzędzi.

  • Node Exporter gromadzącym głownie metryki sprzętowe i systemu operacyjnego
  • cAdvisor dostarczający metryki zużycia zasobów przez poszczególne kontenery
  • Grafana do wizualizacji i tworzenia dashboardów.

Warto dołączyć do newslettera, by nie przegapić tego wpisu!

Artykuł Docker Monitoring – 7 Rzeczy O Których Warto Wiedzieć pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/docker-monitoring-7-rzeczy-o-ktorych-warto-wiedziec/feed/ 2