Docker jest narzędziem izolującym, przez co przy małych nakładach czasowych poświęconych na konfigurację zapewnia bardzo dobre zabezpieczenie aplikacji, którą uruchamiamy za jego pomocą. Posiada bardzo wiele funkcji dzięki którym po odpowiednim skonfigurowaniu sprawiają, że staje się systemem sprawiającym ogromne wyzwanie dla osób łamiących zabezpieczenia.
Jednym z powodów monitorowania logów jest sprawdzenie wykorzystania dostępnych zasobów sprzętowych. Jeżeli nasza aplikacja ma działać sprawnie, to musi posiadać także odpowiednie zasoby. Jeżeli ich jest za mało, to jej funkcjonalność może być mocno ograniczona. Do takiej sytuacji dojść może gdy stanie się ona na przykład popularna i zwiększa się ruch, co idzie w parze z wykorzystaniem zasobów. Przeczytaj nasz artykuł docker – monitorowanie logów kontenera.
Ostatni webinar w tym roku!
Zapraszamy na bezpłatny webinar poświęcony roli sztucznej inteligencji w zarządzaniu infrastrukturą IT, zarówno w dużych serwerowniach, jak i w środowiskach homelab.
W trakcie wydarzenia dowiesz się, jak AI może wspierać codzienną pracę administratora, pomagając w automatyzacji procesów, monitorowaniu zasobów, analizie danych oraz zwiększaniu efektywności operacyjnej.
Zapisy na: https://asdevops.pl/warsztaty/
Bezpieczeństwo dockera
Poniżej przedstawiam listę narzędzi, które możemy wykorzystać w celu zapewnienia bezpieczeństwa naszym kontenerom oraz obrazom:
- Przestrzeń nazw Linuksa – standardowy system zabezpieczeń występujący w kontenerach. Polega na tym, że wszystko w kontenerze wydaje się działać tak, jakby był to główny system operacyjny;
- Cgroups – ogranicza wykorzystanie zasobów sprzętowych, ale również daje możliwość zablokowania dostępu do kontenera przez inne kontenery na hoście;
- Capabilities – systemy z rodziny Linux umożliwiają nadanie lub odebranie uprawnień na każdy z procesów. Przy tworzeniu kontenerów możesz skorzystać z tej możliwości blokując niektóre z nich, bez utraty funkcjonalności uruchomionej aplikacji;
- Seccomp – bezpiecznie uruchamia procesu umożliwiając im wykonanie poleceń tylko z zakresu bezpiecznych;
- AppArmor – przeznaczony dla systemu Debian Linux który jest ulepszeniem jądra systemu dzięki któremu ogranicza programom dostęp do zasobów systemowych;
- SELinux – jedno z bardziej znanych zabezpieczeń wśród systemów Linux. Przeznaczony jest dla dystrybucji RedHat. Izoluje kontenery od siebie, ale również od głównego hosta. Posiada ogromną liczbę funkcji jak kontrolę dostępu dla użytkowników, a także wszystkiego co znajduje się w systemie. System ten nazywany jest drugą linią obrony.
Pomimo takiej ilości mechanizmów nie możemy zapomnieć o logach, są one podstawowym narzędziem które należy monitorować. Można zadać sobie pytanie po co tyle fatygi, szczególnie przy takiej ilości możliwych zabezpieczeń. Otóż bowiem nie istnieje zabezpieczenie idealne. W przypadku gdy nasze mechanizmy zostaną złamane głównym narzędziem obronnym są właśnie logi. To w nich możemy odnaleźć informacje, że nastąpiło włamanie i jesteśmy w stanie albo w porę zareagować lub po włamaniu wiedzieć co intruz zrobił i również usunąć błąd lub lukę umożliwiającą ponowne włamanie.
Jednak musisz wiedzieć, że nie zawsze takie informacje zostaną zapisane we wspomnianych logach. Kwestia w jaki sposób osoba niepowołana dostała się do naszej aplikacji, jakie miała uprawnienia, a także czy udało jej się zmodyfikować logi. Najczęściej osoba która chce ukryć swoją obecność usuwa zawartość takich plików, ale to też jesteśmy w stanie wykryć ponieważ jeżeli coś zostanie usunięte powstanie luka czasowa w pliku. Istnieje jeszcze szansa, że haker zechce także przekazać informację w jaki sposób udało mu się uzyskać dostęp do naszych zasobów.
Po tym dość obszernym wstępie zajmijmy się głównym tematem materiału naszego artykułu, czyli docker – monitorowanie logów kontenera.
Aplikacja do testów
Aby móc sprawdzić logi musimy na początku stworzyć odpowiednie kontenery i je uruchomić. Na łamach tego artykułu chciałbym skorzystać z WordPressa, dlatego tworzymy plik compose.yaml i umieszczamy w nim poniższy kod:
version: '3.8'
services:
database:
image: mysql:latest
container_name: database_mysql
volumes:
- database_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: uczymysiedokera
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
networks:
- wordpress
wordpress:
depends_on:
- database
image: wordpress:latest
container_name: wordpress_cms
volumes:
- wordpress_files:/var/www/html
restart: always
environment:
WORDPRESS_DB_HOST: database:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
ports:
- "8080:80"
networks:
- wordpress
volumes:
database_data:
wordpress_files:
networks:
wordpress:
driver: bridge
Prezentowany plik został skonstruowany w formie tak prostej w celu testów. Co najważniejsze działa i jesteś w stanie uruchomić CMSa wprowadzając polecenie docker compose up -d które pobierze niezbędne obrazy, a także uruchomi kontenery.
Po zakończeniu pracy wystarczy, że wejdziemy pod adres localhost:8080 a następnie stworzymy konto dla wordpressa. Gdy mamy już na czym pracować teraz możemy zająć się samymi logami.
Logi dockera
Docker w standardowej swojej konfiguracji zapisuje dane wyjściowe kontenera, a także strumienie błędów. Po usunięciu kontenera razem z nim jest usuwany plik z logami, dlatego pamiętaj, że jeżeli chcesz przeanalizować jakiś błąd lub awarię przed usunięciem kontenera musisz go skopiować.
Wspomniane pliki z logami znajdują się w folderze /var/lib/docker/containers/ gdzie każdy kontener posiada swój folder nazwany po jego id.
Jeżeli użyłeś mojego pliku do uruchomienia wordpressa powinieneś posiadać dwa kontenery w związku z tym i dwa foldery z logami:
ls -l /var/lib/docker/containers/
drwx--x--- 4 root root 4096 09-16 09:15 1efd12d487ceb41cbe59bf6758b579e413aa34c83b87ab0190cb88910d01085e
drwx--x--- 4 root root 4096 09-16 09:15 3b8518d555de68407697e47475942c1c15d3a552a2edf12c209d62ae72dc3a08
Pliki znajdują się we wskazanych miejscach z przykładu. Noszą nazwę <id>.json.
Wiesz już gdzie odnaleźć tytułowe pliki, natomiast wiedz, że dostęp do nich ma tylko administrator na danym hoście.
Przeglądanie plików ręcznie może być trochę kłopotliwe dlatego docker posiada wbudowane dwa narzędzia które mogą się przydać do tego celu.
Pierwszym jest docker logs. Pozwala na wyświetlanie zawartości plików z logami w trochę czytelniejszy sposób niż czytanie ich w edytorze tekstu. Zerknijmy na poniższy przykład:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1efd12d487ce wordpress:latest "docker-entrypoint.s…" 40 minutes ago Up 40 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp wordpress_cms
3b8518d555de mysql:latest "docker-entrypoint.s…" 40 minutes ago Up 40 minutes 3306/tcp, 33060/tcp database_mysql
docker logs 1efd12d487ce
…
172.18.0.1 - - [16/Sep/2022:07:16:24 +0000] "GET /wp-admin/css/l10n.min.css?ver=6.0.2 HTTP/1.1" 200 1021 "http://localhost:8080/wp-admin/install.php" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
172.18.0.1 - - [16/Sep/2022:07:16:24 +0000] "GET /wp-admin/css/forms.min.css?ver=6.0.2 HTTP/1.1" 200 6564 "http://localhost:8080/wp-admin/install.php" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
172.18.0.1 - - [16/Sep/2022:07:16:24 +0000] "GET /wp-includes/css/dashicons.min.css?ver=6.0.2 HTTP/1.1" 200 36068 "http://localhost:8080/wp-admin/install.php" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
172.18.0.1 - - [16/Sep/2022:07:16:24 +0000] "GET /wp-admin/css/install.min.css?ver=6.0.2 HTTP/1.1" 200 2124 "http://localhost:8080/wp-admin/install.php" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
172.18.0.1 - - [16/Sep/2022:07:16:24 +0000] "GET /wp-includes/js/jquery/jquery-migrate.min.js?ver=3.3.2 HTTP/1.1" 200 4520 "http://localhost:8080/wp-admin/install.php" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
…
Przykład celowo został skrócony.
Zwróć uwagę, że tutaj zostało wypisane wszystko to, co wykonaliśmy w trakcie instalacji wordpressa. Polecenie posiada kilka wbudowanych opcji. Dokładną listę otrzymamy, gdy wprowadzimy polecenie w następujący sposób:
docker logs --help
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
Options:
--details Show extra details provided to logs
-f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
-n, --tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
Z wymienionych bardzo przyda się opcja umożliwiająca wyświetlenie danej ilości linii z pliku, a także opcja do nieprzerwanego nadzorowania logów. Zwróćmy uwagę my zainstalowaliśmy i uruchomiliśmy naszą aplikację dlatego nasze logi systemowe nie są tak obszerne, ale z czasem rozrosną się i wtedy te polecenia okażą się bardzo przydatne. Poniżej przedstawiam przykłady użycia:
docker logs -n 5 1efd12d487ce
172.18.0.1 - - [16/Sep/2022:07:32:04 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1" 200 512 "http://localhost:8080/wp-admin/" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
172.18.0.1 - - [16/Sep/2022:07:34:04 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1" 200 512 "http://localhost:8080/wp-admin/" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
172.18.0.1 - - [16/Sep/2022:07:36:04 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1" 200 512 "http://localhost:8080/wp-admin/" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
172.18.0.1 - - [16/Sep/2022:07:38:04 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1" 200 512 "http://localhost:8080/wp-admin/" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
172.18.0.1 - - [16/Sep/2022:07:40:04 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1" 200 512 "http://localhost:8080/wp-admin/" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
docker logs -f 1efd12d487ce
W przypadku drugiego, logi są aktualizowane i wyświetlane automatycznie gdy wystąpi jakaś akcja.
Statystyki wykorzystania zasobów
Drugim narzędziem monitorującym wbudowanym w dockera jest także docker stats. W przeciwieństwie do swojego poprzednika nie wyświetla logów dotyczących czynności jakie zostały wykonane w naszej aplikacji tylko wyświetla wykorzystanie zasobów przez nasze kontenery w czasie ciągłym. Spójrzmy na poniższy przykład:
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
1efd12d487ce wordpress_cms 0.01% 165.4MiB / 15.55GiB 1.04% 2.06MB / 1.79MB 4.1kB / 75.1MB 11
3b8518d555de database_mysql 0.64% 426.3MiB / 15.55GiB 2.68% 817kB / 932kB 270kB / 310MB 41
Docker z opcją stats monitoruje wykorzystanie dostępnych zasobów. Jest to bardzo czytelnie przedstawione i myślę, że nie ma sensu tłumaczyć co znajduje się w tym przykładzie. W celu śledzenia konkretnego kontenera wystarczy, że po opcji wpiszesz id kontenera który chcesz sprawdzić.
Bardziej czytelne wyświetlanie wykorzystania zasobów
Jednym z najprostszych narzędzi do monitorowania zasobów sprzętowych przez dockera jest ctop. Wyświetla w konsoli to samo co docker stats, ale bardziej czytelnie oraz posiada kilka dodatkowych funkcji. Dokładne informacje dotyczące tego projektu możesz przeczytać pod adresem https://github.com/bcicen/ctop.
Instalację przeprowadzam na systemie Linux Debian 11 Bullseye.
Nim przejdziemy do instalacji programu musimy doinstalować niezbędne pakiety, bez których program nie uruchomi się:
sudo apt-get install ca-certificates curl gnupg lsb-release
Następnie dodajemy repozytorium do naszego systemu:
curl -fsSL https://azlux.fr/repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/azlux-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/azlux-archive-keyring.gpg] http://packages.azlux.fr/debian \
$(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/azlux.list >/dev/null
I na samym końcu instalujemy oprogramowanie ctop:
sudo apt-get update
sudo apt-get install docker-ctop
Program uruchamiamy wpisując w konsoli ctop, po czym pojawi się okno z dostępnymi kontenerami oraz wykorzystaniem zasobów tak jak na poniższym przykładzie:
Jeżeli postępowałeś zgodnie z artykułem, to powinieneś otrzymać podobny wynik. Różni się ID oraz ilością zasobów. Niestety oba kontenery nie są bardzo aktywne ponieważ zainstalowaliśmy wszystko na naszym lokalnym komputerze i tak naprawdę my tylko z tego korzystamy więc nie generujemy takiej aktywności by statystyki podskakiwały.
Po liście kontenerów poruszamy się przy pomocy strzałek klawiatury a także klawisza ENTER, po którym wciśnięciu pojawi się lista z opcjami.
Jednak sposób prezentowany tutaj nie jest jedyny ponieważ polecenie posiada kilka dostępnych opcji z których jesteśmy w stanie skorzystać przy uruchomieniu:
ctop --help
Usage of ctop:
-a show active containers only
-connector string
container connector to use (default "docker")
-f string
filter containers
-h display this help dialog
-i invert default colors
-r reverse container sort order
-s string
select container sort field
-v output version information and exit
Inną możliwością programu są jego skróty klawiszowe z którymi możesz zapoznać się na stronie https://github.com/bcicen/ctop.
Innym bardzo dobrym narzędziem do wszelkich rodzajów logów dockera jest także darmowe narzędzie Zabbix, które bardzo dobrze tłumaczy Arkadiusz Siczek w swoim szkoleniu znajdującym się na stronie https://asdevops.pl/szkolenie-zabbix/.
Podsumowanie docker – monitorowanie logów kontenera
Dzienniki dockera są bardzo ważnym elementem pod względem bezpieczeństwa, jak i również funkcjonowania samej aplikacji. Pomimo tylu narzędzi wspomagających w tym aspekcie nadal należy nadzorować dzienniki. W przypadku zasobów sprzętowych tu też warto poświęcić czas i sprawdzać w jakiej ilości nasze kontenery je wykorzystują. W tej sytuacji przychodzą z pomocą prezentowane narzędzia pomimo, że należą do grona podstawowych. Do tych bardziej zaawansowanych należy wspomniany Zabbix, ale analiza czy wystarczą prezentowane narzędzia czy też wypada jednak poznać coś bardziej zaawansowanego należy już do Ciebie.