Linux Namespaces – fundament kontenerów i izolacji procesów
Gdy większość administratorów słyszy słowo Docker, najczęściej myśli o kontenerach, obrazach i pliku Dockerfile. W rzeczywistości Docker jest jedynie warstwą zarządzającą. Prawdziwa magia dzieje się znacznie niżej – w jądrze Linux.
Jednym z najważniejszych mechanizmów, który umożliwił rozwój konteneryzacji, są Linux Namespaces.
To właśnie dzięki nim proces uruchomiony w kontenerze może mieć wrażenie, że działa na osobnym systemie operacyjnym, mimo że w rzeczywistości współdzieli to samo jądro z innymi aplikacjami.
Bez namespaces nie byłoby:
- Dockera,
- Kubernetes,
- Podmana,
- LXC,
- większości współczesnych platform kontenerowych.
Czym są Linux Namespaces?
Namespace to mechanizm jądra Linux, który izoluje wybrane zasoby systemowe pomiędzy grupami procesów.
Najprościej można powiedzieć, że namespace tworzy dla procesu „oddzielny świat”.
Proces uruchomiony wewnątrz namespace może widzieć:
- własne procesy,
- własny system plików,
- własne interfejsy sieciowe,
- własne punkty montowania,
- własnych użytkowników.
Jednocześnie inne procesy działające na tym samym serwerze pozostają od niego odseparowane.
Schemat działania:
Kernel Linux
├── Namespace A
│ ├── Proces 1
│ ├── Proces 2
│
├── Namespace B
│ ├── Proces 3
│ └── Proces 4
│
└── Namespace C
├── Proces 5
└── Proces 6
Każda grupa procesów widzi jedynie własne środowisko.
Dlaczego namespaces są potrzebne?
Wyobraźmy sobie serwer uruchamiający dwie aplikacje.
Obie chcą korzystać z:
- portu 80,
- użytkownika o identyfikatorze UID 0,
- własnych procesów systemowych,
- osobnego katalogu
/proc.
Bez izolacji byłoby to niemożliwe.
Namespace pozwala stworzyć środowisko, w którym każda aplikacja ma własny widok systemu.
Jak działa izolacja?
Załóżmy, że uruchamiamy kontener.
Wewnątrz kontenera polecenie:
ps aux
zwraca:
PID 1
nginx
PID 2
worker
Administrator hosta wykonuje to samo polecenie:
ps aux
i widzi setki procesów.
Dlaczego?
Procesy znajdują się w różnych PID Namespaces.
Rodzaje Namespaces
Linux obsługuje kilka rodzajów namespaces.
Każdy odpowiada za izolację innego elementu systemu.
PID Namespace
Izoluje identyfikatory procesów.
Proces działający w kontenerze może być:
PID 1
mimo że na hoście posiada:
PID 28453
Schemat:
Host
PID 28453
↓
Kontener
PID 1
Dzięki temu każdy kontener posiada własne drzewo procesów.
TIP administratora
Jeżeli proces o PID 1 zakończy działanie wewnątrz kontenera, większość platform uzna kontener za zatrzymany.
Dlatego proces uruchamiany jako PID 1 powinien poprawnie obsługiwać sygnały systemowe, takie jak SIGTERM.
Mount Namespace
Izoluje system plików.
Proces może widzieć zupełnie inny zestaw punktów montowania.
Przykład:
Host:
/
├── home
├── var
├── opt
Kontener:
/
├── app
├── data
├── tmp
Proces nie ma dostępu do całego systemu plików hosta.
Network Namespace
Izoluje konfigurację sieci.
Każdy namespace może posiadać:
- własny adres IP,
- własne tablice routingu,
- własne interfejsy,
- własne reguły firewalla.
Przykład:
Kontener A:
eth0
172.18.0.2
Kontener B:
eth0
172.18.0.3
Oba posiadają interfejs o nazwie eth0, mimo że działają na tym samym serwerze.
Warto wiedzieć
Docker wykorzystuje tzw. veth pairs – wirtualne pary interfejsów sieciowych, które łączą namespace kontenera z mostem sieciowym (docker0) na hoście.
IPC Namespace
Izoluje mechanizmy komunikacji między procesami.
Dotyczy między innymi:
- pamięci współdzielonej,
- semaforów,
- kolejek komunikatów.
Procesy z różnych namespaces nie mogą przypadkowo korzystać z tych samych zasobów IPC.

UTS Namespace
Pozwala każdemu środowisku posiadać własną nazwę hosta.
Przykład:
Host:
server01
Kontener:
web01
Polecenie:
hostname
zwróci różne wyniki.
User Namespace
To jeden z najciekawszych mechanizmów bezpieczeństwa.
Pozwala mapować identyfikatory użytkowników.
Przykład:
W kontenerze:
UID 0
(root)
Na hoście:
UID 100000
Oznacza to, że proces myślący, iż działa jako root, w rzeczywistości nie posiada pełnych uprawnień poza swoim namespace.
TIP bezpieczeństwa
User Namespace znacząco ogranicza skutki ucieczki z kontenera (container escape). Nawet jeśli aplikacja działa jako root wewnątrz kontenera, nie oznacza to automatycznie pełnych uprawnień na hoście.
Cgroup Namespace
Powiązany jest z mechanizmem cgroups v2.
Pozwala procesom widzieć wyłącznie własną grupę kontroli zasobów.
Przykład:
Proces nie zobaczy limitów innych kontenerów.
Time Namespace
Jedna z nowszych funkcji jądra Linux.
Pozwala procesom korzystać z różnych ustawień czasu systemowego.
Jest wykorzystywana głównie w:
- testach,
- środowiskach developerskich,
- symulacjach.
Jak sprawdzić Namespaces?
Lista aktywnych namespaces:
lsns
Przykładowy wynik:
NS TYPE
4026531836 pid
4026531837 net
4026531840 uts
4026531841 ipc
Polecenie pokazuje wszystkie przestrzenie nazw działające w systemie.
Tworzenie Namespace ręcznie
Linux udostępnia narzędzie:
unshare
Przykład:
unshare --fork --pid bash
Nowa powłoka otrzymuje własny PID Namespace.
Polecenie:
echo $$
może zwrócić:
1
choć nie uruchomiliśmy nowego systemu operacyjnego.
Namespaces i Docker
Podczas uruchamiania kontenera Docker automatycznie tworzy zestaw namespaces.
Schemat:
Docker Engine
↓
Namespaces
↓
cgroups
↓
Kernel Linux
↓
Kontener
Każdy kontener otrzymuje własne:
- PID,
- NET,
- MOUNT,
- IPC,
- UTS,
- USER (opcjonalnie),
- CGROUP.
Namespaces a maszyny wirtualne
To częste źródło nieporozumień.
Maszyna wirtualna:
Aplikacja
↓
System operacyjny
↓
Kernel
↓
Hypervisor
Kontener:
Aplikacja
↓
Namespaces
↓
cgroups
↓
Kernel hosta
Kontenery współdzielą jądro Linux, dzięki czemu uruchamiają się znacznie szybciej i zużywają mniej pamięci niż klasyczne maszyny wirtualne.
Najczęstsze błędy administratorów
Uruchamianie kontenerów jako --privileged
Opcja ta wyłącza wiele mechanizmów izolacji i powinna być używana wyłącznie wtedy, gdy jest to naprawdę konieczne.
Brak User Namespace
W wielu środowiskach funkcja mapowania użytkowników nadal nie jest włączona.
To zmniejsza poziom bezpieczeństwa.
Łączenie wielu usług w jednym kontenerze
Choć technicznie możliwe, utrudnia izolację i zarządzanie procesami.
Lepszą praktyką jest uruchamianie jednej głównej usługi na kontener.
Najlepsze praktyki
- Korzystaj z aktualnych wersji jądra Linux.
- Łącz namespaces z cgroups v2 i mechanizmami bezpieczeństwa, takimi jak AppArmor lub SELinux.
- Unikaj uruchamiania kontenerów z nadmiernymi uprawnieniami.
- Regularnie monitoruj aktywne namespaces (
lsns) oraz procesy (ps,systemd-cgls). - W środowiskach produkcyjnych rozważ użycie User Namespace, aby ograniczyć ryzyko eskalacji uprawnień.
Podsumowanie
Linux Namespaces są jednym z najważniejszych mechanizmów współczesnego jądra Linux. To właśnie one sprawiają, że proces może działać w odizolowanym środowisku i mieć wrażenie, że korzysta z własnego systemu operacyjnego.
W połączeniu z cgroups v2, mechanizmami bezpieczeństwa oraz systemem systemd, namespaces tworzą fundament działania kontenerów Docker, Kubernetes i wielu innych platform.
Dla administratora serwerów zrozumienie namespaces oznacza nie tylko lepsze poznanie działania kontenerów, ale również świadome projektowanie bezpiecznej i wydajnej infrastruktury Linux.






