Podman, KVM i kontenery: praktyczny przewodnik po bezpiecznej wirtualizacji

Ostatnia aktualizacja: 9 marca 2026
  • Kontenery współdzielą jądro z hostem, więc ich izolacja zależy od przestrzeni nazw, grup c i wzmocnienia systemu.
  • W porównaniu do klasycznego Dockera Podman zapewnia dodatkowe bezpieczeństwo, unikając centralnego demona root i ułatwiając wykonywanie poleceń bez uprawnień roota.
  • Sieci typu bridge, host i rootless (slirp4netns, paste) w Podmanie umożliwiają dostosowanie równowagi między łącznością a izolacją.
  • Połączenie KVM, kontenerów i najlepszych praktyk (rootless, MAC, seccomp, skanowanie obrazów) zapewnia solidną platformę do produkcji.

Podman KVM bezpieczna wirtualizacja

Rozpoczynając konfigurację poważnego środowiska kontenerowego w systemie Linux, natychmiast pojawia się to samo pytanie: w jakim stopniu bezpieczne jest poleganie wyłącznie na kontenerach i kiedy wskazane jest przejście na KVM lub mikro-VM? W środowiskach korporacyjnych, gdzie Docker, Podman, LXC, maszyny wirtualne KVM i różne hiperwizory są ze sobą połączone, dogłębne zrozumienie modelu izolacji jest kluczowe dla uniknięcia błędów.

Co więcej, dość złożone scenariusze nie są rzadkością, takie jak próba użycia Docker Desktop lub Podman w maszynie wirtualnej w VirtualBox lub KVM , gdzie w grę wchodzi kilka poziomów wirtualizacji (zagnieżdżonych lub nie), i łatwo o błędy takie jak „KVM nie jest włączony na hoście”. Uporządkujmy wszystkie te elementy — kontenery, maszyny wirtualne, Podman, KVM, sieć i zabezpieczenia — i zobaczmy, jak je połączyć, aby uzyskać naprawdę bezpieczną i praktyczną wirtualizację.

Klasyczna wirtualizacja z KVM i maszynami wirtualnymi

Podstawą całej tej konfiguracji pozostaje pełna wirtualizacja systemów operacyjnych za pomocą hiperwizorów, takich jak KVM, Xen czy ESXi . W tym przypadku na sprzęcie fizycznym działa hiperwizor, który odpowiada za „podzielenie” maszyny na kilka niezależnych maszyn wirtualnych.

W tym modelu każda maszyna wirtualna uruchamia własne jądro i system operacyjny gościa , całkowicie niezależne od hosta. Hiperwizor (na przykład KVM, zintegrowany z jądrem Linuksa) pełni rolę strażnika między sprzętem a maszynami wirtualnymi i odpowiada za ich silną izolację.

Zazwyczaj mówimy o dwóch typach hiperwizorów: hiperwizorach typu 1, czyli typu bare metal, które działają bezpośrednio na sprzęcie, oraz hiperwizorach typu 2, hostowanych na istniejącym systemie operacyjnym. VirtualBox lub VMware Workstation to typ 2 , natomiast KVM zarządzany przez libvirt na serwerze Linux jest bliższy scenariuszowi typu 1, mimo że współdzieli przestrzeń z samym hostem.

Największą zaletą tego podejścia jest to, że każda maszyna wirtualna ma swój własny, kompletny stos: jądro, przestrzeń użytkownika, usługi, sieć i pamięć masową . Zapewnia to dużą elastyczność i możliwość uruchamiania różnych systemów operacyjnych i wersji jądra na tej samej maszynie fizycznej.

Do zarządzania tymi zwirtualizowanymi platformami w systemie GNU/Linux prawie zawsze używa się biblioteki libvirt jako interfejsu API orkiestracji , oprócz którego obsługiwane są narzędzia graficzne i wiersza poleceń, lub większych projektów, takich jak OpenStack, który tworzy kompletne chmury, łącząc maszyny wirtualne, serwery fizyczne i kontenery.

Wymagania sprzętowe i typowe problemy z KVM

Przed uruchomieniem KVM lub skorzystaniem z rozwiązań od niego zależnych (takich jak niektóre konfiguracje Docker Desktop lub micro-VM) należy upewnić się, że procesor obsługuje wirtualizację sprzętową (VT-x w przypadku komputerów Intel lub SVM/AMD-V w przypadku komputerów AMD) i że jest ona włączona w systemie BIOS/UEFI.

W Linuksie mamy szybką kontrolę: jeśli polecenie `grep -E 'svm|vmx' /proc/cpuinfo` nic nie zwróci lub opcja jest nadal wyłączona w oprogramowaniu układowym, KVM nie będzie działać. Ponadto, w scenariuszach, w których uruchamiamy maszyny wirtualne wewnątrz innej maszyny wirtualnej (wirtualizacja zagnieżdżona), hiperwizor najwyższego poziomu musi jawnie udostępnić te rozszerzenia gościowi.

Gdy coś pójdzie nie tak, pojawiają się typowe komunikaty, takie jak niesławne okno dialogowe Docker Desktop w RHEL 9 w VirtualBox: „KVM nie jest włączony na hoście ”. Problem nie leży bezpośrednio w Dockerze ani w RHEL, ale w tym, że maszyna wirtualna VirtualBox nie otrzymuje niezbędnych rozszerzeń wirtualizacji, aby uruchomić w niej KVM.

Polecenia takie jak `modprobe kvm` lub `modprobe kvm_amd / kvm_intel` powinny ładować moduły jądra bez komunikatów o błędach. Jeśli `dmesg` nie wyświetla niczego istotnego lub `lsmod | grep kvm` wyświetla jedynie puste `kvm` i `irqbypass`, a brakuje modułów specyficznych dla procesora, jest bardzo prawdopodobne, że wirtualizacja sprzętowa nie jest dostępna dla systemu gościa lub jest wyłączona w oprogramowaniu układowym.

W takich scenariuszach, nawet jeśli wszystkie możliwe funkcje są włączone w gościu, a VirtualBox nie oferuje wirtualizacji zagnieżdżonej lub jest błędnie skonfigurowany, KVM po prostu nie będzie działać . Rozwiązaniem jest sprawdzenie konfiguracji hiperwizora hosta (VirtualBox, VMware itp.) i włączenie wirtualizacji zagnieżdżonej, jeśli jest dostępna.

Kontenery: lekka wirtualizacja na poziomie systemu operacyjnego

W przeciwieństwie do tradycyjnych maszyn wirtualnych kontenery oferują inne podejście: nie emulują całego sprzętu, lecz wykorzystują jądro hosta i izolują procesy oraz zasoby przy użyciu funkcji jądra systemu Linux.

Kontener to w zasadzie zestaw procesów hermetyzowanych za pomocą przestrzeni nazw i grup c . W tym „środowisku” aplikacja uważa, że ​​działa na własnej maszynie, z własnym systemem plików, interfejsami sieciowymi i identyfikatorami PID, ale w rzeczywistości współdzieli jądro z hostem.

Kontenery oferują wydajność zbliżoną do natywnej, ponieważ nie wymagają użycia drugiego jądra ani pełnej emulacji sprzętowej . Narzut jest minimalny: wystarczający jedynie do montowania przestrzeni nazw, ograniczania zasobów za pomocą cgroups i egzekwowania zasad bezpieczeństwa (seccomp, AppArmor, SELinux itp.).

Taka konstrukcja ma jednak istotne konsekwencje: wszystkie obciążenia współdzielą to samo jądro fizyczne . Poważna luka w zabezpieczeniach tego jądra może nagle stać się potencjalnym wektorem ucieczki dla wszystkich kontenerów uruchomionych na tym węźle.

Dlatego często mówi się, że izolacja kontenerów nie jest „absolutna”, jak w przypadku maszyny wirtualnej . Jeśli komuś uda się wykorzystać krytyczny błąd jądra, przestrzenie nazw przestają być skuteczną barierą, a granice między kontenerami a hostami mogą zostać przełamane.

Przestrzenie nazw i grupy c: podstawa izolacji kontenerów

W systemie Linux izolacja kontenerów opiera się na dwóch głównych filarach: przestrzeniach nazw, służących do oddzielania widoków systemowych , oraz grupach cgroups, służących do ograniczania i rozliczania zasobów.

  Od Windows XP do Windows 11: ostateczne porównanie wydajności

Przestrzenie nazw izolują takie elementy, jak identyfikatory PID, sieć, punkty montowania, IPC, nazwę hosta (UTS) i użytkowników . W ten sposób proces „widzi” tylko procesy, interfejsy sieciowe, system plików i nazwę hosta swojej własnej przestrzeni nazw, co daje mu wrażenie, że znajduje się w innym systemie.

Z kolei cgroups pozwalają określić, ile mocy obliczeniowej procesora, pamięci, operacji wejścia/wyjścia na dysku, liczby procesów itp. może wykorzystać kontener . Zapobiega to niekontrolowanemu przeciążeniu całego hosta, co jest kluczowe w przypadku współdzielenia węzłów między zespołami lub projektami.

Należy jednak pamiętać, że same przestrzenie nazw i grupy cgroups nie stanowią kompletnego systemu bezpieczeństwa . Nie zapobiegają one wykorzystywaniu luk w jądrze, nie filtrują wywołań systemowych ani nie zarządzają szczegółowymi zasadami dostępu. Stanowią fundament, ale wymagają wzmocnienia.

Rozsądnym sposobem na wzmocnienie środowiska jest połączenie filtrów wywołań systemowych z seccomp, zasadami MAC (AppArmor lub SELinux) i drastycznym ograniczeniem możliwości procesów, najlepiej wraz z przestrzeniami nazw użytkowników i trybem rootless, aby zminimalizować szkody, jeśli komuś uda się uciec z kontenera.

Zagrożenia bezpieczeństwa na platformach kontenerowych

Na rzeczywistej platformie kontenerowej powierzchnia ataku rozkłada się na kilka warstw: jądro i środowisko wykonawcze (runc, containerd, CRI-O), łańcuch dostaw obrazów, konfiguracja kontenera/orkiestratora oraz podstawowa infrastruktura (chmura, pamięć masowa, IAM, sieć).

Do typowych wektorów ataków zaliczają się luki w zabezpieczeniach oprogramowania w jądrze lub środowisku wykonawczym kontenera, używanie niezabezpieczonych lub nieutrzymywanych obrazów, popełnianie błędów konfiguracji w Kubernetes lub Dockerze (uprzywilejowane kontenery, niebezpieczne montowania hostów, nadmiernie otwarte tryby sieciowe) oraz luki w zabezpieczeniach rejestrów lub procesów CI/CD.

W wielu rzeczywistych incydentach nie występuje pojedynczy „magiczny błąd”, lecz raczej kombinacja znanych luk w zabezpieczeniach i niedostatecznej konfiguracji : kontenery uruchamiane jako root, użycie flagi --privileged, montowanie systemu plików hosta w kontenerze i brak seccomp lub MAC.

Do tego dochodzi problem łańcucha dostaw: publiczne obrazy bazowe często zawierają luki bezpieczeństwa (CVE), nieaktualne pakiety i słabo kontrolowane zależności . Złośliwe oprogramowanie może stosunkowo łatwo się przedostać lub skompromitowana biblioteka może pozostać uśpiona, dopóki warunki nie będą sprzyjające jej uruchomieniu.

Dlatego w środowisku produkcyjnym nie jest to opcjonalne: należy skanować obrazy pod kątem luk w zabezpieczeniach za pomocą narzędzi takich jak Trivy, Clair lub Grype , kontrolować, które rejestry są używane (Harbor, Quay, GHCR z politykami) oraz podpisywać/weryfikować obrazy przed ich wdrożeniem w klastrze.

Docker kontra Podman: wpływ na model zagrożeń

W świecie kontenerów aplikacji Docker i Podman oferują podobne funkcje, ale ich architektura znacznie się różni, co zmienia model bezpieczeństwa, z którym pracujemy na hoście.

Docker, w swoim klasycznym trybie rootful, opiera się na centralnym demonie (dockerd), który działa jako root . Interfejs wiersza poleceń komunikuje się z tym demonem poprzez /var/run/docker.sock lub przez TCP i to właśnie ten uprzywilejowany proces tworzy i usuwa kontenery, zarządza obrazami, sieciami i woluminami oraz komunikuje się z rejestrami.

Oznacza to, że każdy, kto ma dostęp do gniazda Docker, ma praktycznie uprawnienia roota do hosta , ponieważ może uruchamiać uprzywilejowane kontenery, montować dowolne systemy plików i modyfikować krytyczną konfigurację. Demon staje się w efekcie pojedynczym punktem awarii.

Podman z kolei powstał z myślą o stworzeniu bezdemonowego silnika kontenerowego, który byłby jak najbardziej „natywny” dla Linuksa . Nie ma stałego centralnego procesu; kontenerami steruje użytkownik lub systemd, a integracja z tym ostatnim umożliwia sterowanie kontenerami za pośrednictwem jednostek usług.

To podejście lepiej wpisuje się w uniksowy model „każdy proces należy do użytkownika, który go uruchamia”, i pozwala uniknąć konieczności korzystania z demona o wysokich uprawnieniach . Co więcej, Podman oferuje zgodność z poleceniami Dockera, upraszczając migrację (można nawet użyć aliasu `docker=podman` w środowiskach, w których nie chce się instalować Docker CE).

Tryb bezrootowy i przestrzenie nazw użytkowników

Jednym z głównych praktycznych postępów w ograniczaniu wpływu potencjalnej ucieczki kontenera jest tryb bez roota w połączeniu z przestrzeniami nazw użytkownika . Pytanie, na które chcemy odpowiedzieć, brzmi: „Co się stanie, jeśli kontener rzeczywiście ucieknie?”

Przestrzenie nazw użytkowników umożliwiają przemapowanie identyfikatora UID kontenera 0 na nieuprzywilejowany identyfikator UID na hoście . Innymi słowy, w kontenerze aplikacja uważa się za użytkownika root, ale z perspektywy hosta proces ten jest w rzeczywistości zwykłym użytkownikiem z przypisanym zakresem subuid/subgid.

W ten sposób, nawet jeśli atakujący uzyska uprawnienia roota w kontenerze i zdoła zaatakować lukę w jądrze lub środowisku wykonawczym, po powrocie na hosta będzie to robił jako użytkownik bez uprawnień . Nie będzie mógł nadpisywać plików binarnych roota, montować wrażliwych systemów plików ani manipulować urządzeniami, jeśli nie będzie posiadał niezbędnych uprawnień.

Podman został zaprojektowany od początku z myślą o tym modelu: domyślne konteneryzowanie bez uprawnień roota, kiedy tylko jest to możliwe , używanie SELinux/AppArmor i cgroups nawet bez uprawnień roota oraz silny nacisk na minimalizowanie uprawnień strukturalnych.

Docker oferuje teraz również prawdziwy tryb bez uprawnień roota , w którym dockerd i kontenery znajdują się w przestrzeni nazw użytkownika, w przeciwieństwie do starszego trybu userns-remap, w którym demon pozostawał rootem. Z punktu widzenia bezpieczeństwa zapobiega to exploitowi na dockerd i uniemożliwieniu automatycznego przyznania uprawnień roota hostowi.

Sieci kontenerowe z Podman: interfejsy mostowe, hosta, macvlan i bezrootowe

Kolejnym ważnym elementem bezpieczeństwa i praktycznego działania jest warstwa sieci kontenerowej . Podman oferuje różne mechanizmy zapewniające łączność, ze szczególnym uwzględnieniem scenariuszy bezkorzennych.

  Linux kontra Windows 11: Porównanie szybkości i wydajności

Podman 4 wprowadził netavark, sterownik sieciowy oparty na modelu CNI, który zapewnia kontenerom adresy IP w sieciach mostowych, macvlanach itp. Dzięki netavark kontenery z uprawnieniami roota zazwyczaj łączą się domyślnie z siecią o nazwie „podman” powiązaną z mostem Linux (podman0) na hoście, z adresacją 10.88.0.0/16.

Ta domyślna sieć mostowa zapewnia podstawową łączność internetową za pośrednictwem reguł SNAT i umożliwia udostępnianie portów kontenerów hostowi za pomocą komendy `-po --publish`, która generuje reguły DNAT w iptables/nftables. Ze względu na zgodność z Dockerem, sieć ta nie korzysta z wewnętrznego serwera DNS.

Możemy również tworzyć sieci mostowe definiowane przez użytkownika , które izolują grupy kontenerów od siebie i zapewniają wewnętrzny DNS. Pozwala to kontenerom na rozwiązywanie nazw w ramach ich sieci prywatnej, ułatwia oddzielanie usług, które nie powinny się wzajemnie widzieć, oraz zapewnia większą kontrolę nad MTU, zaporami sieciowymi i innymi funkcjami.

W bardziej zaawansowanych środowiskach możliwe jest użycie sieci macvlan lub ipvlan do bezpośredniego połączenia kontenerów z fizyczną siecią hosta. Macvlan umożliwia kontenerom komunikację między sobą, podczas gdy ipvlan ma tendencję do ich większej izolacji; są to przydatne opcje we wdrożeniach, w których każdy kontener musi być postrzegany jako prawdziwy host przez resztę sieci.

Sieci bezkorzeniowe: slirp4netns i pasta

Gdy użytkownik nie ma uprawnień root, sprawy się komplikują: użytkownik bez uprawnień nie może swobodnie modyfikować globalnej przestrzeni nazw sieciowych ani tworzyć dowolnych interfejsów, więc Podman musi uciec się do rozwiązań w przestrzeni użytkownika, aby zapewnić łączność.

Tutaj pojawia się slirp4netns , klasyczny mechanizm używany przez Podman rootless . Ten projekt tworzy izolowane środowisko sieciowe w kontenerze i wykorzystuje moduł slirp jądra do translacji adresów (NAT) i umożliwia kontenerowi dostęp do internetu przez sieć hosta.

W praktyce slirp4netns tworzy interfejs TAP w przestrzeni nazw sieci kontenera (na przykład tap0 z adresem IP 10.0.2.100 i bramą 10.0.2.2) i kieruje ruch przez stos TCP/IP zaimplementowany w przestrzeni użytkownika. Jest to funkcjonalne, ale wiąże się z pewnym narzutem i ograniczeniami.

Jednym z tych ograniczeń jest to, że użytkownicy bez uprawnień nie mogą korzystać z portów poniżej 1024. Parametr sysctl net.ipv4.ip_unprivileged_port_start określa, do którego portu są oni uważani za „bez uprawnień” (domyślnie 1024), choć można to ostrożnie dostosować, jeśli model zabezpieczeń na to pozwala.

W Podman 5, slirp4netns został zastąpiony przez Pasta jako domyślny mechanizm bez rootowania . Pasta również działa całkowicie w przestrzeni użytkownika, ale dzięki interfejsowi TAP i technikom zerowego kopiowania osiąga wydajność sieci zbliżoną do natywnej, zmniejszając wpływ na opóźnienia i przepustowość w porównaniu ze slirp4netns.

Sieci mostowe i hosta w kontenerach bez roota

Nawet pracując w trybie innym niż root, możemy połączyć kontenery bez uprawnień roota z domyślną siecią mostu „podman” za pomocą `--network=podman`. Wykorzystuje to możliwości Netavarka i mapuje porty na hosta za pomocą `-p`, tak jak w trybie roota.

Możliwe jest również tworzenie sieci mostów definiowanych przez użytkownika w środowiskach bez uprawnień roota . W takim przypadku mosty i powiązane urządzenia nie są tworzone w globalnej przestrzeni nazw sieci hosta, lecz w przestrzeni nazw użytkownika, więc interfejsy te nie będą widoczne z poziomu hosta za pomocą prostego polecenia `sudo ip a`.

Aby sprawdzić te mosty bez roota, Podman oferuje polecenie `podman unshare --rootless-netns` , które otwiera powłokę w przestrzeni nazw sieciowych użytkownika. Stamtąd można obserwować mosty wewnętrzne i weryfikować bezpośrednią łączność z kontenerami.

Ta izolacja ma ciekawy efekt: Może nie być bezpośredniego połączenia między hostem a adresami IP tych kontenerów bez uprawnień root.ale działa z portami mapowanymi na adres IP hosta, które stanowią punkt wejścia do usługi.
Aby umożliwić komunikację między kontenerami, serwer DNS zintegrowany z siecią mostową zdefiniowaną przez użytkownika umożliwia im komunikowanie się po imieniu, co znacznie upraszcza konfigurację rozproszonych aplikacji.

Na drugim końcu znajduje się sieć hosta (--network=host) , w której kontener współdzieli stos sieciowy z hostem bez własnego adresu IP. W tym trybie, jeśli kontener bez uprawnień roota uruchomi serwer na porcie 8080/tcp, usługa będzie bezpośrednio dostępna na porcie 8080 hosta, co oszczędza mapowanie portów, ale zmniejsza izolację.

Podman Desktop, narzędzia do obrazowania i lokalna orkiestracja

Dla użytkowników, którzy wolą coś bardziej wizualnego, Podman Desktop zapewnia graficzne środowisko do zarządzania kontenerami, kontenerami, obrazami i konfiguracjami sieciowymi na komputerach deweloperskich. Stanowi ono bezpośrednią alternatywę dla Docker Desktop, ale opiera się na silniku bezdemonowym.

Obrazy są pobierane za pomocą polecenia `podman pull`, które pobiera dane z rejestrów zdefiniowanych w pliku `/etc/containers/registries.conf` . Jeśli obraz jest określony bez nazwy rejestru, Podman próbuje zlokalizować go w skonfigurowanej kolejności w rejestrach, domyślnie używając znacznika `latest`.

Oprócz interfejsu wiersza poleceń Podman, możemy używać skopeo jako dedykowanego narzędzia do zarządzania, inspekcji i kopiowania obrazów między rejestrami a lokalnymi repozytoriami. Polecenia takie jak copy, delete i sync pozwalają nam zautomatyzować synchronizację między repozytoriami, oznaczać obrazy do czyszczenia pamięci oraz przenosić artefakty między środowiskami.

Po pobraniu obrazu polecenie `podman run` umożliwia uruchomienie kontenerów poprzez określenie transportu i ścieżki (domyślnie transport Dockera i wyszukiwanie w skonfigurowanym rejestrze). Standardowe opcje (-d, -p, --name, --pod itp.) obejmują zarówno scenariusze laboratoryjne, jak i poważniejsze wdrożenia.

Codzienne zarządzanie odbywa się za pomocą `podman ps` do listy kontenerów, `podman stop/start` do zatrzymywania lub uruchamiania istniejących instancji oraz `podman rm` do usuwania zatrzymanych kontenerów . Jeśli kontener został zmodyfikowany i chcemy go przekonwertować na nowy obraz, `podman commit` zapisuje te zmiany pod nową nazwą.

  Kompletny przewodnik po skrótach klawiaturowych dla powłoki Bash

Pody i zaawansowane modele wykonawcze z Podmanem

Zainspirowany Kubernetesem, Podman pozwala grupować kontenery w kontenery, które współdzielą ten sam stos sieciowy i określone zasoby . To idealne rozwiązanie dla takich elementów jak baza danych i jej klient, czy wiele mikrousług, które muszą komunikować się z niskim opóźnieniem.

Polecenie `podman pod create` tworzy nowy kontener i zwraca jego identyfikator, ale domyślnie kontener pozostaje zatrzymany, dopóki nie zostanie uruchomiony powiązany kontener lub nie zostanie jawnie uruchomiony za pomocą polecenia `podman pod start`.

Aby sprawdzić, które kontenery znajdują się w systemie, użyj polecenia `podman pod ls` , które wyświetli również listę kontenerów INFRA powiązanych z każdym z nich. Ten specjalny kontener utrzymuje działanie sieci i innych współdzielonych zasobów kontenera, więc liczba kontenerów nigdy nie jest zerowa.

Podman oferuje konkretne polecenia do uruchamiania, zatrzymywania i ponownego uruchamiania całych kontenerów (podman pod start/stop/restart) , ale możemy również działać tylko na określonym kontenerze w ramach kontenera, nie modyfikując pozostałych, zachowując izolację procesu na poziomie aplikacji.

Aby dodać więcej kontenerów do istniejącego kontenera, użyj komendy `podman run --pod POD_NAME` , stosując tę ​​samą składnię, co w przypadku pojedynczych kontenerów. Nie można usunąć kontenera z kontenera bez jego zniszczenia, ponieważ członkostwo w kontenerze jest powiązane z jego cyklem życia.

Monitorowanie odbywa się za pomocą polecenia podman ps –pod lub określonych poleceń, które umożliwiają monitorowanie procesów wszystkich kontenerów we wszystkich kontenerach , szybko identyfikując, co należy do której grupy i w jaki sposób są dystrybuowane usługi.

Kontenery, LXC i wirtualizacja aplikacji

Chociaż Docker i Podman dominują w dyskusji, nie są to jedyne opcje konteneryzacji w GNU/Linux . Rozwiązania takie jak LXC/LXD, systemd-nspawn i Kata Containers rozwiązują ten problem z nieco innej perspektywy.

LXC zapewnia bardzo lekkie kontenery systemowe z własną nazwą hosta, adresem IP, systemem plików i kompletnym systemem init . W połączeniu z LXD, który działa jako hiperwizor dla kontenerów i maszyn wirtualnych, zapewnia środowisko zbliżone do korzystania z wielu lekkich maszyn o wydajności zbliżonej do gołego metalu.

Podczas gdy Docker/Podman skupiają się na kontenerach aplikacji zgodnych ze standardem OCI , LXC sprawdza się, gdy potrzebne są trwałe środowiska z wieloma usługami i procesami. Działają one jak maszyny wirtualne, ale mają mniejsze obciążenie i bardzo naturalną integrację z jądrem Linux.

Z punktu widzenia wydajności LXC może obsługiwać aplikacje korporacyjne wymagające dużej ilości danych praktycznie bez żadnych kar , co czyni je doskonałym wyborem w przypadku obciążeń wrażliwych na opóźnienia, które nie wymagają silnej izolacji tradycyjnej maszyny wirtualnej.

Równocześnie, technologie ukierunkowane na mikromaszyny wirtualne i wzmocnioną izolację również zyskały na popularności, takie jak Kata Containers , która uruchamia każdy pod w małej maszynie wirtualnej z własnym jądrem, czy gVisor, który umieszcza „piaskownicę jądra” napisaną w Go pomiędzy aplikacją a Linuksem. Oba rozwiązania zmniejszają zależność od współdzielonego jądra i zbliżają się do modelu bezpieczeństwa maszyn wirtualnych, zachowując jednocześnie przyjazność dla użytkownika charakterystyczną dla kontenerów.

Najlepsze praktyki wzmacniania Dockera i Podmana

Biorąc pod uwagę powyższe, rozsądnym podejściem do stworzenia solidnej platformy kontenerowej jest praca warstwowa: segmentacja za pomocą przestrzeni nazw/cgroups, zasady filtrowania za pomocą seccomp i MAC oraz strukturalne ograniczenie uprawnień za pomocą trybu rootless.

W praktyce zaleca się stosowanie standardowej praktyki uruchamiania kontenerów w trybie innym niż root, gdy tylko jest to możliwe , zwłaszcza w środowiskach wielodostępnych lub w chmurach współdzielonych. Podman domyślnie to umożliwia, a Docker bez uprawnień roota realizuje tę samą filozofię, gdy wymagana jest kompatybilność.

Jądro hosta musi być aktualizowane za pomocą poprawek bezpieczeństwa . Luki takie jak Dirty COW, Dirty Pipe i inne są eliminowane za pomocą aktualizacji, które muszą być wdrażane stosunkowo szybko, jeśli nie chcemy pozostawić otwartej furtki dla wycieków kontenerów.

Innym skutecznym sposobem jest korzystanie z niezmiennych dystrybucji zorientowanych na kontenery, takich jak openSUSE MicroOS czy Flatcar Linux . Ich system root z dostępem tylko do odczytu i atomową aktualizacją znacznie zmniejszają powierzchnię ataku i ułatwiają wycofywanie zmian, jeśli coś pójdzie nie tak po wdrożeniu poprawki.

W kwestii konfiguracji: nie należy używać kontenerów z uprawnieniami uprzywilejowanymi w środowisku produkcyjnym, z wyjątkiem ściśle kontrolowanych przypadków ; nie należy uruchamiać aplikacji z uprawnieniami roota w kontenerze; należy w miarę możliwości korzystać z systemów plików tylko do odczytu oraz ograniczyć możliwości do niezbędnego minimum. Profile SELinux/AppArmor i seccomp dostosowane do rzeczywistych wywołań aplikacji są praktycznie obowiązkowe.

Na koniec nie możemy zapomnieć o monitorowaniu środowiska wykonawczego . Narzędzia takie jak Falco, Sysdig Secure czy Aqua pomagają wykrywać anomalie, próby ucieczki (takie jak nietypowy dostęp do /proc lub /sys), nietypowy ruch sieciowy czy podejrzane polecenia, dając czas na reakcję, zanim atak się rozpocznie.

Łącząc klasyczną wirtualizację z KVM, kontenerami zarządzanymi przez Podman (najlepiej w trybie rootless), dobrze segmentowanymi sieciami i dobrymi praktykami wzmacniania zabezpieczeń, można zbudować wysoce elastyczną i dość bezpieczną platformę wirtualizacji. Zrozumienie, że współdzielone jądro jest najważniejszym punktem, poleganie na maszynach wirtualnych lub mikro-maszynach wirtualnych, gdy wymaga tego ryzyko lub zgodność z przepisami, oraz staranne zarządzanie łańcuchem dostaw obrazów decydują o różnicy między środowiskiem laboratoryjnym a infrastrukturą gotową do produkcji.

Typy wirtualizacji serwerów
Podobne artykuły:
Typy wirtualizacji serwerów