Ein Namensraum hüllt eine globale Systemressource in eine
Abstraktion ein, so dass es den Prozessen innerhalb des Namensraums so
erscheint, als ob sie ihre eigene, isolierte Instanz der globalen Ressource
hätten. Änderungen an der globalen Ressource sind für
andere Prozesse, die Mitglied des Namensraums sind, sichtbar, sind aber
für alle anderen Prozesse unsichtbar. Ein Anwendungsfall für
Namensräume ist die Implementierung von Containern.
Diese Seite stellt Verweise auf Informationen über die
verschiedenen Namensraumtypen bereit, beschreibt die zugehörigen
Dateien in /proc und fasst das API zum Arbeiten mit
Namensräumen zusammen.
Die nachfolgende Tabelle zeigt die unter Linux verfügbaren
Namensraumtypen. Die zweite Spalte der Tabelle zeigt den Schalterwert, der
zur Angabe des Namensraumtyps in verschiedenen APIs verwandt wird. Die
dritte Spalte identifiziert die Handbuchseite, die Details über den
Namensraumtyp bereitstellt. Die letzte Spalte ist eine Zusammenfassung der
Ressourcen, die durch den Namensraumtyp isoliert werden.
Namensraum |
Schalter |
Seite |
isoliert |
Cgroup |
CLONE_NEWCGROUP |
cgroup_namespaces(7) |
Cgroup-Wurzelverzeichnis |
IPC |
CLONE_NEWIPC |
ipc_namespaces(7) |
System V IPC, POSIX-Nachrichtenwarteschlangen |
Netzwerk |
CLONE_NEWNET |
network_namespaces(7) |
Netzwerkgeräte, Stacks, Ports, usw. |
Einhängungen |
CLONE_NEWNS |
mount_namespaces(7) |
Einhängepunkte |
PID |
CLONE_NEWPID |
pid_namespaces(7) |
Prozesskennungen |
Zeit |
CLONE_NEWTIME |
time_namespaces(7) |
Startzeit und monotone Uhren |
User |
CLONE_NEWUSER |
user_namespaces(7) |
Benutzer- und Gruppenkennungen |
UTS |
CLONE_NEWUTS |
uts_namespaces(7) |
Rechnername und NIS- Domain-Name |
Neben verschiedenen, nachfolgend beschriebenen Dateien in
/proc enthält das Namensraum-API die folgenden
Systemaufrufe:
- clone(2)
- Der Systemaufruf clone(2) erstellt einen neuen Prozess. Falls das
Argument Schalter des Aufrufs einen oder mehrere der oben
aufgeführten Schalter CLONE_NEW* enthält, dann werden
für jeden der Schalter neue Namensräume erstellt und der
Kindprozess wird zum Mitglied in jedem dieser Namensräume gemacht.
(Dieser Systemaufruf implementiert auch eine Reihe von
Funktionalitäten ohne Bezug zu Namensräumen.)
- setns(2)
- Der Systemaufruf setns(2) erlaubt es dem aufrufenden Prozess, einem
bestehenden Namensraum beizutreten. Der beizutretende Namensraum wird
über einen Dateideskriptor festgelegt, der sich auf eine der
nachfolgend beschriebenen Dateien in /proc/PID/ns
bezieht.
- unshare(2)
- Der Systemaufruf unshare(2) verschiebt den aufrufenden Prozess in
einen neuen Namensraum. Falls das Argument Schalter des Aufrufs
einen oder mehrere der oben aufgeführten Schalter CLONE_NEW*
enthält, dann werden für jeden der Schalter neue
Namensräume erstellt und der Kindprozess wird zum Mitglied in jedem
dieser Namensräume gemacht. (Dieser Systemaufruf implementiert auch
eine Reihe von Funktionalitäten ohne Bezug zu
Namensräumen.)
- ioctl(2)
- Verschiedene ioctl(2)-Aktionen können zum Ermitteln von
Informationen über Namensräume verwandt werden. Diese
Aktionen sind in ioctl_ns(2) beschrieben.
In den meisten Fällen benötigt die Erstellung neuer
Namensräume mittels clone(2) und unshare(2) die
Capability CAP_SYS_ADMIN, da der Ersteller in den neuen
Namensräumen die Macht hat, globale Ressourcen zu ändern, die
für andere Prozessen sichtbar sind, die nachfolgend in dem Namensraum
erstellt werden oder diesem beitreten. Benutzernamensräume sind eine
Ausnahme: seit Linux 3.8 werden keine Privilegien zur Erstellung eines
Benutzernamensraums benötigt.
Jeder Prozess verfügt über ein Unterverzeichnis
/proc/PID/ns/, das einen Eintrag für jeden Namensraum
enthält, der die Manipulation mittels setns(2) erlaubt:
$ ls -l /proc/$$/ns | awk '{print $1, $9, $10, $11}'
insgesamt 0
lrwxrwxrwx. cgroup -> cgroup:[4026531835]
lrwxrwxrwx. ipc -> ipc:[4026531839]
lrwxrwxrwx. mnt -> mnt:[4026531840]
lrwxrwxrwx. net -> net:[4026531969]
lrwxrwxrwx. pid -> pid:[4026531836]
lrwxrwxrwx. pid_for_children -> pid:[4026531834]
lrwxrwxrwx. time -> time:[4026531834]
lrwxrwxrwx. time_for_children -> time:[4026531834]
lrwxrwxrwx. user -> user:[4026531837]
lrwxrwxrwx. uts -> uts:[4026531838]
Durch Bind-Einhängungen (siehe mount(2)) einer der
Dateien in diesem Verzeichnis an einen anderen Platz im Dateisystem wird der
entsprechende Namensraum des durch PID festgelegten Prozesses am
Leben erhalten, selbst wenn alle derzeit im Namensraum befindlichen Prozesse
beendet werden.
Öffnen einer der Dateien in diesem Verzeichnis (oder einer
Datei, die auf eine dieser Dateien bind-eingehängt ist) liefert einen
Datei-Handle auf den Namensraum zurück, der dem durch PID
festgelegten Prozess entspricht. Solange dieser Dateideskriptor offen
bleibt, wird der Namensraum am Leben bleiben, selbst falls alle Prozesse in
diesem Namensraum beendet werden. Der Dateideskriptor kann an
setns(2) weitergegeben werden.
Unter Linux 3.7 und älter waren diese Dateien als harte
Links sichtbar. Seit Linux 3.8 erscheinen sie als symbolische Links. Falls
zwei Prozesse im gleichen Namensraum sind, dann werden die
Gerätekennungen und Inode-Nummern ihrer symbolischen Links
/proc/PID/ns/xxx identisch sein; die Anwendung kann dies
mittels der von stat(2) zurückgelieferten Felder
stat.st_dev und stat.st_ino überprüfen. Der
Inhalt dieses symbolischen Links ist eine Zeichenkette, die den
Namensraumtyp und die Inode-Nummer wie im folgenden Beispiel
enthält:
$ readlink /proc/$$/ns/uts
uts:[4026531838]
Die symbolischen Links in diesem Unterverzeichnis sind wie
folgt:
- /proc/PID/ns/cgroup (seit Linux 4.6)
- Diese Datei ist ein Handle für den Cgroup-Namensraum des
Prozesses.
- /proc/PID/ns/ipc (seit Linux 3.0)
- Diese Datei ist ein Handle für den IPC-Namensraum des
Prozesses.
- /proc/PID/ns/mnt (seit Linux 3.8)
- Diese Datei ist ein Handle für den Einhänge-Namensraum des
Prozesses.
- /proc/PID/ns/net (seit Linux 3.0)
- Diese Datei ist ein Handle für den Netzwerk-Namensraum des
Prozesses.
- /proc/PID/ns/pid (seit Linux 3.8)
- Diese Datei ist ein Handle für den PID-Namensraum des Prozesses.
Dieses Handle ist für die Lebenszeit des Prozesses dauerhaft (d.h.
die PID-Namensraumzugehörigkeit eines Prozesses ändert sich
niemals).
- /proc/PID/ns/pid_for_children (seit Linux 4.12)
- Diese Datei ist ein Handle für den PID-Namensraum des durch diesen
Prozess erstellten Kind-Prozesses. Dieser kann sich als Konsequenz aus
Aufrufen von unshare(2) und setns(2) ändern (siehe
pid_namespaces(7)), daher kann sich die Datei von
/proc/PID/ns/pid unterscheiden. Der symbolische Link wird
erst nach der Erstellung des ersten Kindprozesses in den Namensraum
wertvoll. (Vorher wird ein readlink(2) von dem symbolischen Link
einen leeren Puffer zurückgeben.)
- /proc/PID/ns/time (seit Linux 5.6)
- Diese Datei ist ein Handle für den Zeit-Namensraum des
Prozesses.
- /proc/PID/ns/time_for_children (seit Linux 5.6)
- Diese Datei ist ein Handle für den Zeit-Namensraum des durch diesen
Prozess erstellten Kind-Prozesses. Dieser kann sich als Konsequenz aus
Aufrufen von unshare(2) und setns(2) ändern (siehe
time_namespaces(7)), daher kann sich die Datei von
/proc/PID/ns/time unterscheiden.
- /proc/PID/ns/user (seit Linux 3.8)
- Diese Datei ist ein Handle für den Benutzer-Namensraum des
Prozesses.
- /proc/PID/ns/uts (seit Linux 3.0)
- Diese Datei ist ein Handle für den UTS-Namensraum des
Prozesses.
Die Berechtigungen, diese symbolischen Links zu dereferenzieren
oder zu lesen (readlink(2)) werden durch eine
Ptrace-Zugriffsmodusüberprüfung
PTRACE_MODE_READ_FSCREDS gesteuert; siehe ptrace(2).
Die Dateien im Verzeichnis /proc/sys/user (das seit Linux
4.9 vorhanden ist) legen die Begrenzungen für die Anzahl der
Namensräume der verschiedenen Typen fest, die erstellt werden
können. Die Dateien sind wie folgt:
- max_cgroup_namespaces
- Der Wert in dieser Datei definiert eine benutzerbezogene Begrenzung
für die Anzahl der Cgroup-Namensräume, die in dem
Benutzernamensraum erstellt werden können.
- max_ipc_namespaces
- Der Wert in dieser Datei definiert eine benutzerbezogene Begrenzung
für die Anzahl der IPC-Namensräume, die in dem
Benutzernamensraum erstellt werden können.
- max_mnt_namespaces
- Der Wert in dieser Datei definiert eine benutzerbezogene Begrenzung
für die Anzahl der Einhänge-Namensräume, die in dem
Benutzernamensraum erstellt werden können.
- max_net_namespaces
- Der Wert in dieser Datei definiert eine benutzerbezogene Begrenzung
für die Anzahl der Netzwerk-Namensräume, die in dem
Benutzernamensraum erstellt werden können.
- max_pid_namespaces
- Der Wert in dieser Datei definiert eine benutzerbezogene Begrenzung
für die Anzahl der PID-Namensräume, die in dem
Benutzernamensraum erstellt werden können.
- max_time_namespaces
(seit Linux 5.7)
- Der Wert in dieser Datei definiert eine benutzerbezogene Begrenzung
für die Anzahl der Zeit-Namensräume, die in dem
Benutzernamensraum erstellt werden können.
- max_user_namespaces
- Der Wert in dieser Datei definiert eine benutzerbezogene Begrenzung
für die Anzahl der Benutzer-Namensräume, die in dem
Benutzernamensraum erstellt werden können.
- max_uts_namespaces
- Der Wert in dieser Datei definiert eine benutzerbezogene Begrenzung
für die Anzahl der UTS-Namensräume, die in dem
Benutzernamensraum erstellt werden können.
Beachten Sie die folgenden Details über diese Dateien:
- •
- Die Werte in diesen Dateien können von privilegierten Prozessen
verändert werden.
- •
- Die in diesen Dateien offengelegten Werte sind die Begrenzungen für
die Benuzernamensräume, in denen sich der öffnende Prozess
befindet.
- •
- Die Begrenzungen gelten pro Benutzer. Jeder Benutzer in dem gleichen
Benutzernamensraum kann Namensräume bis zu der definierten
Begrenzung erstellen.
- •
- Die Begrenzungen gelten für alle Benutzer, einschließlich
UID 0.
- •
- Diese Begrenzungen gelten zusätzlich zu anderen, auf
Namensräume bezogenen Begrenzungen (wie diese für PID- und
Benutzernamensräume), die durchgesetzt werden könnten.
- •
- Beim Erreichen dieser Beschränkungen werden clone(2) und
unshare(2) mit dem Fehler ENOSPC fehlschlagen.
- •
- Für den anfänglichen Benutzernamensraum ist der Vorgabewert
für jede dieser Dateien die Hälfte der Begrenzungen
für die Anzahl der Threads, die erstellt werden dürfen
(/proc/sys/kernel/threads-max). In allen abgeleiteten
Benutzernamensräumen ist der Vorgabewert in jeder Datei
MAXINT.
- •
- Wenn ein Namensraum erstellt wird, wird das Objekt auch gegen die
Vorgängernamensräume verrechnet. Genauer:
- •
- Jeder Benutzernamensraum hat eine Ersteller-UID.
- •
- Wenn ein Namensraum erstellt wird, wird er gegen die Ersteller-UIDs in
jedem der Vorgängernamensräume verrechnet und der Kernel
stellt sicher, dass die entsprechende Namensraumbegrenzung für die
Ersteller-UID in den Vorgängernamensräumen nicht
überschritten wird.
- •
- Der vorgehend erwähnte Punkt stellt sicher, dass das Erzeugen eines
neuen Benutzernamensraums nicht als Mittel verwandt werden kann, um den im
aktuellen Benutzernamensraum in Kraft gesetzten Beschränkungen zu
entfliehen.
Falls keine weiteren Faktoren vorliegen, wird ein Namensraum
automatisch entsorgt, wenn der letzte Prozess in dem Namensraum beendet wird
oder den Namensraum verlässt. Allerdings gibt es eine Reihe von
weiteren Faktoren, die einen Namensraum in der Existenz halten
können, obwohl er keine Mitgliedprozesse hat. Zu diesen Faktoren
gehören die folgenden:
- •
- Ein offener Dateideskriptor oder eine Bind-Einhängung für
die entsprechende Datei /proc/PID/ns/*.
- •
- Der Namensraum ist hierarchisch (d.h. ein PID- oder Benutzernamensraum)
und hat einen Kindnamensraum.
- •
- Es ist ein Benutzernamensraum, der einen oder mehrere
nicht-Benutzer-Namensräume besitzt.
- •
- Es ist ein PID-Namensraum und es gibt einen Prozess, der sich mittels
eines symbolischen Links /proc/PID/ns/pid_for_children auf
einen Namensraum bezieht.
- •
- Es ist ein Zeitnamensraum und es gibt einen Prozess, der sich mittels
eines symbolischen Links /proc/PID/ns/time_for_children auf
einen Namensraum bezieht.
- •
- Es ist ein IPC-Namensraum und eine entsprechende Einhängung eines
mqueue-Dateisystems (siehe mq_overview(7)) bezieht sich auf
diesen Namensraum.
- •
- Es ist ein PID-Namensraum und eine entsprechende Einhängung eines
proc(5)-Dateisystems bezieht sich auf diesen Namensraum.
nsenter(1), readlink(1), unshare(1),
clone(2), ioctl_ns(2), setns(2), unshare(2),
proc(5), capabilities(7), cgroup_namespaces(7),
cgroups(7), credentials(7), ipc_namespaces(7),
network_namespaces(7), pid_namespaces(7),
user_namespaces(7), uts_namespaces(7), lsns(8),
switch_root(8)