Detaillierte Erläuterung des Befehls zum Freigeben
1. Name
unshare - run program with some namespaces unshared from parent(使用与父程序不共享的名称空间运行程序)
2. Zusammenfassung
unshare [options] program [arguments]
3. Beschreibung
Hebt die Freigabe der angegebenen Namespaces vom übergeordneten Prozess auf und führt dann das angegebene Programm aus. Die freizugebenden Namespaces werden über Optionen angezeigt. Nicht gemeinsam nutzbare Namespaces sind (hebt die Freigabe der angegebenen Namespaces vom übergeordneten Prozess auf und führt dann das angegebene Programm aus. Der Leerzeichen wird durch Optionen angezeigt. Namespaces, die nicht gemeinsam genutzt werden können, umfassen)
Für die Freigabe können insgesamt 6 nicht freigegebene Namespaces festgelegt werden:
mount namespace
UTS namespace
IPC namespace
network namespace
pid namespace
user namespace
4. Optionen
Es gibt insgesamt folgende Optionen:
(1)-i, --ipc
unshare the IPC namespace.
(2)-m, --mount
Unshare the mount namespace.
(3)-n, --net
Unshare the network namespace.
(4) -p, --pid
Unshare the pid namespace. See also the --fork and --mount-proc options.
(5)-u, --uts
Unshare the UTS namespace.
(6) -U, --user
Unshare the user namespace.
(7)-f, --fork
Fork the specified program as a child process of unshare rather than running it directly. This is useful when creating a new pid namespace.
(8)--mount-proc[=mountpoint]
Just before running the program, mount the proc filesystem at mountpoint (default is /proc). This is useful when creating a new pid namespace. It also implies creating a new mount names‐pace since the /proc mount would otherwise mess up existing programs on the system. The new proc filesystem is explicitly mounted as private (by MS_PRIVATE|MS_REC).
(9)-r, --map-root-user
Run the program only after the current effective user and group IDs have been mapped to the superuser UID and GID in the newly created user namespace. This makes it possible to conve‐niently gain capabilities needed to manage various aspects of the newly created namespaces (such as configuring interfaces in the network namespace or mounting filesystems in the mount namespace) even when run unprivileged. As a mere convenience feature, it does not support more sophisticated use cases, such as mapping multiple ranges of UIDs and GIDs. This option implies --setgroups=deny.
(10) --propagation private|shared|slave|unchanged
Recursively sets mount propagation flag in the new mount namespace. The default is to set the propagation to private, this feature is possible to disable by unchanged argument. The options is silently ignored when mount namespace (--mount) is not requested.
(11)--setgroups allow|deny
Allow or deny setgroups(2) syscall in user namespaces.
setgroups(2) is only callable with CAP_SETGID and CAP_SETGID in a user namespace (since Linux 3.19) does not give you permission to call setgroups(2) until after GID map has been set. The GID map is writable by root when setgroups(2) is enabled and GID map becomes writable by unprivileged processes when setgroups(2) is permanently disabled.
(12) -V, --version
Display version information and exit.
(13)-h, --help
Display help text and exit.
5. Beispiele
# unshare --fork --pid --mount-proc readlink /proc/self
1
Establish a PID namespace, ensure we're PID 1 in it against newly mounted procfs instance.
(建立一个PID命名空间,确保我们在新安装的procfs实例中是PID 1。)
$ unshare --map-root-user --user sh -c whoami
root
Establish a user namespace as an unprivileged user with a root user within it.
(将用户命名空间建立为非特权用户,其中包含根用户。)
6. Welche Rolle spielen verschiedene Namespaces?
(1) Mount-Namespace
Mount Namespace ist der erste vom Linux-Kernel implementierte Namespace, der seit Version 2.4.19 des Kernels hinzugefügt wurde. Es kann verwendet werden, um Einhängepunkte zu isolieren, die von verschiedenen Prozessen oder Prozessgruppen gesehen werden. Für Laien ist es möglich, verschiedene Mount-Verzeichnisse in verschiedenen Prozessen zu sehen. Durch die Verwendung des Mount-Namespace kann festgestellt werden, dass nur Ihre eigenen Mount-Informationen im Container angezeigt werden und der Mount-Vorgang im Container keine Auswirkungen auf das Mount-Verzeichnis des Hosts hat.
Lassen Sie uns ein Beispiel verwenden, um den Mount-Namespace zu demonstrieren. Wir verwenden ein Kommandozeilen-Tool zum Freigeben. unshare ist ein Tool im util-linux Toolkit. CentOS 7 hat dieses Tool standardmäßig integriert. Mit dem Befehl unshare können Sie verschiedene Arten von Namespaces erstellen und darauf zugreifen.
Zunächst verwenden wir die folgenden Befehle, um einen Bash-Prozess und einen neuen Mount-Namespace zu erstellen:
unshare --mount --fork /bin/bash
Nach dem Ausführen des obigen Befehls haben wir einen neuen Mount-Namespace auf dem Host erstellt, und der neu erstellte Mount-Namespace wurde dem aktuellen Befehlszeilenfenster hinzugefügt. Lassen Sie mich anhand eines Beispiels überprüfen, ob das Erstellen eines Mount-Verzeichnisses in einem unabhängigen Mount-Namespace keine Auswirkungen auf das Mount-Verzeichnis des Hosts hat.
Nach dem Ausführen des obigen Befehls haben wir einen neuen Mount-Namespace auf dem Host erstellt, und der neu erstellte Mount-Namespace wurde dem aktuellen Befehlszeilenfenster hinzugefügt. Lassen Sie mich anhand eines Beispiels überprüfen, ob das Erstellen eines Mount-Verzeichnisses in einem unabhängigen Mount-Namespace keine Auswirkungen auf das Mount-Verzeichnis des Hosts hat.
Erstellen Sie zunächst ein Verzeichnis unter dem Verzeichnis / tmp.
[root@centos7 centos]# mkdir /tmp/tmpfs
Verwenden Sie nach dem Erstellen des Verzeichnisses den Befehl mount, um ein Verzeichnis vom Typ tmpfs bereitzustellen. Der Befehl lautet wie folgt:
[root@centos7 centos]# mount -t tmpfs -o size=20m tmpfs /tmp/tmpfs
Verwenden Sie dann den Befehl df, um die bereitgestellten Verzeichnisinformationen anzuzeigen:
[root@centos7 centos]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 500G 1.4G 499G 1% /
devtmpfs 16G 0 16G 0% /dev
tmpfs 16G 0 16G 0% /dev/shm
tmpfs 16G 0 16G 0% /sys/fs/cgroup
tmpfs 16G 57M 16G 1% /run
tmpfs 3.2G 0 3.2G 0% /run/user/1000
tmpfs 20M 0 20M 0% /tmp/tmpfs
Sie können sehen, dass das Verzeichnis / tmp / tmpfs korrekt bereitgestellt wurde. Um zu überprüfen, ob dieses Verzeichnis nicht auf dem Host bereitgestellt ist, öffnen wir ein neues Befehlszeilenfenster und führen den Befehl df aus, um die Bereitstellungsinformationen des Hosts anzuzeigen:
[centos@centos7 ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 16G 0 16G 0% /dev
tmpfs 16G 0 16G 0% /dev/shm
tmpfs 16G 57M 16G 1% /run
tmpfs 16G 0 16G 0% /sys/fs/cgroup
/dev/vda1 500G 1.4G 499G 1% /
tmpfs 3.2G 0 3.2G 0% /run/user/1000
Aus der obigen Ausgabe können wir ersehen, dass / tmp / tmpfs nicht auf dem Host gemountet ist. Es ist ersichtlich, dass die Mount-Operation in unserem unabhängigen Mount-Namespace keinen Einfluss auf den Host hat.
Um unsere Ideen weiter zu überprüfen, überprüfen wir weiterhin die Namespace-Informationen des aktuellen Prozesses im aktuellen Befehlszeilenfenster. Der Befehl lautet wie folgt:
[root@centos7 centos]# ls -l /proc/self/ns/
total 0
lrwxrwxrwx. 1 root root 0 Sep 4 08:20 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 root root 0 Sep 4 08:20 mnt -> mnt:[4026532239]
lrwxrwxrwx. 1 root root 0 Sep 4 08:20 net -> net:[4026531956]
lrwxrwxrwx. 1 root root 0 Sep 4 08:20 pid -> pid:[4026531836]
lrwxrwxrwx. 1 root root 0 Sep 4 08:20 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 Sep 4 08:20 uts -> uts:[4026531838]
Öffnen Sie dann ein neues Befehlszeilenfenster und überprüfen Sie mit demselben Befehl die Namespace-Informationen auf dem Host:
[centos@centos7 ~]$ ls -l /proc/self/ns/
total 0
lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 net -> net:[4026531956]
lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 pid -> pid:[4026531836]
lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 user -> user:[4026531837]
lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 uts -> uts:[4026531838]
Durch Vergleichen der Ausgabeergebnisse der beiden Befehle können wir feststellen, dass die ID-Werte anderer Namespaces mit Ausnahme der ID-Werte von Mount Namespace identisch sind.
Aus den obigen Ergebnissen können wir schließen, dass mit dem Befehl unshare ein neuer Mount-Namespace erstellt werden kann und der Mount im neu erstellten Mount-Namespace vollständig von außen isoliert ist.
(2) PID-Namespace
Die Funktion des PID-Namespace besteht darin, den Prozess zu isolieren. In verschiedenen PID-Namespaces können Prozesse dieselbe PID-Nummer haben. Mithilfe des PID-Namespace kann erkannt werden, dass der Hauptprozess jedes Containers Prozess Nr. 1 ist, während die Prozesse im Container unterschiedliche PIDs auf dem Host haben. Beispielsweise beträgt die PID eines Prozesses auf dem Host 122, und der PID-Namespace kann verwendet werden, um zu erkennen, dass der Prozess die PID 1 im Container sieht.
Im Folgenden wird anhand eines Beispiels die Rolle des PID-Namespace demonstriert. Zuerst verwenden wir den folgenden Befehl, um einen Bash-Prozess zu erstellen und einen neuen PID-Namespace zu erstellen:
unshare --fork --pid --mount-proc /bin/bash
Nach dem Ausführen des obigen Befehls haben wir einen neuen PID-Namespace auf dem Host erstellt und den neu erstellten PID-Namespace zum aktuellen Befehlszeilenfenster hinzugefügt. Verwenden Sie den Befehl ps aux im aktuellen Befehlszeilenfenster, um die Prozessinformationen anzuzeigen:
[root@centos7 centos]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 115544 2004 pts/0 S 10:57 0:00 bash
root 10 0.0 0.0 155444 1764 pts/0 R+ 10:59 0:00 ps aux
Durch die Ausgabe des obigen Befehls können Sie sehen, dass bash der Prozess Nr. 1 unter dem aktuellen Namespace ist und wir keine anderen Prozessinformationen auf dem Host sehen können.
(3) UTS-Namespace
Der UTS-Namespace wird hauptsächlich zum Isolieren von Hostnamen verwendet und ermöglicht es jedem UTS-Namespace, einen unabhängigen Hostnamen zu haben. Unser Hostname ist beispielsweise Docker. Mit UTS Namespace können Sie den Hostnamen im Container als Ladoudocker oder einen anderen benutzerdefinierten Hostnamen realisieren.
In ähnlicher Weise verwenden wir ein Beispiel, um die Rolle des UTS-Namespace zu überprüfen. Zunächst verwenden wir den Befehl unshare, um einen UTS-Namespace zu erstellen:
unshare --fork --uts /bin/bash
Nachdem der UTS-Namespace erstellt wurde, befindet sich das aktuelle Befehlszeilenfenster bereits in einem unabhängigen UTS-Namespace. Als Nächstes verwenden wir den Befehl hostname (Hostname kann zum Anzeigen des Hostnamens verwendet werden), um den Hostnamen festzulegen:
hostname -b lagoudocker
Überprüfen Sie dann den Hostnamen erneut:
[root@centos7 centos]# hostname
lagoudocker
Durch die Ausgabe des obigen Befehls können wir sehen, dass der Hostname im aktuellen UTS-Namespace in Lagudocker geändert wurde. Dann öffnen wir ein neues Befehlszeilenfenster und überprüfen mit demselben Befehl den Hostnamen des Hosts:
[centos@centos7 ~]$ hostname
centos7
Sie können sehen, dass der Name des Hosts immer noch centos7 lautet und nicht geändert wurde. Hieraus kann überprüft werden, ob der UTS-Namespace zum Isolieren von Hostnamen verwendet werden kann.
(4) IPC-Namespace
Der IPC-Namespace wird hauptsächlich zum Isolieren der Kommunikation zwischen Prozessen verwendet. Beispielsweise können PID-Namespace und IPC-Namespace zusammen verwendet werden, um zu erkennen, dass Prozesse innerhalb desselben IPC-Namespace miteinander kommunizieren können, Prozesse mit unterschiedlichen IPC-Namespaces jedoch nicht.
In ähnlicher Weise verwenden wir ein Beispiel, um die Rolle des IPC-Namespace zu überprüfen. Zunächst verwenden wir den Befehl unshare, um einen IPC-Namespace zu erstellen:
unshare --fork --ipc /bin/bash
Als Nächstes müssen zwei Befehle verwendet werden, um den IPC-Namespace zu überprüfen.
Befehl ipcs -q: Wird verwendet, um die Liste der Kommunikationswarteschlangen zwischen Systemen anzuzeigen.
Befehl ipcmk -Q: Wird zum Erstellen einer Kommunikationswarteschlange zwischen Systemen verwendet.
Wir verwenden zuerst den Befehl ipcs -q, um die Liste der Systemkommunikationswarteschlangen unter dem aktuellen IPC-Namespace anzuzeigen:
[centos@centos7 ~]$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
Aus dem obigen können wir erkennen, dass derzeit keine Systemkommunikationswarteschlange vorhanden ist, und dann verwenden wir den Befehl ipcmk -Q, um eine Systemkommunikationswarteschlange zu erstellen:
[root@centos7 centos]# ipcmk -Q
Message queue id: 0
Verwenden Sie den Befehl ipcs -q erneut, um die Liste der Systemkommunikationswarteschlangen unter dem aktuellen IPC-Namespace anzuzeigen
[root@centos7 centos]# ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x73682a32 0 root 644 0 0
Sie sehen, dass wir erfolgreich eine Systemkommunikationswarteschlange erstellt haben. Dann öffnen wir ein neues Befehlszeilenfenster und überprüfen mit dem Befehl ipcs -q die Systemkommunikationswarteschlange des Hosts:
[centos@centos7 ~]$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
Durch das obige Experiment kann festgestellt werden, dass die in einem separaten IPC-Namespace erstellte Systemkommunikationswarteschlange auf dem Host nicht sichtbar ist. Das heißt, IPC Namespace realisiert die Isolation von Systemkommunikationswarteschlangen.
(5) Benutzernamensraum
Der Benutzername wird hauptsächlich zum Isolieren von Benutzern und Benutzergruppen verwendet. Ein typisches Anwendungsszenario besteht darin, dass ein Prozess, der als Nicht-Root-Benutzer auf dem Host ausgeführt wird, einem Root-Benutzer in einem separaten Benutzernamensraum zugeordnet werden kann. Durch die Verwendung des Benutzernamensraums kann festgestellt werden, dass der Prozess über Root-Berechtigungen im Container verfügt, es sich jedoch nur um einen normalen Benutzer auf dem Host handelt.
User Namesapce kann ohne Rootberechtigung erstellt werden. Im Folgenden erstellen wir einen Benutzernamenraum als normalen Benutzer. Der Befehl lautet wie folgt:
[centos@centos7 ~]$ unshare --user -r /bin/bash
[root@centos7 ~]#
CentOS7 erlaubt standardmäßig die Erstellung eines Benutzernamensraums auf 0. Wenn die Ausführung des obigen Befehls fehlschlägt (der vom Befehl unshare zurückgegebene Fehler lautet unshare: unshare failed: Ungültiges Argument), müssen Sie den folgenden Befehl verwenden, um die Anzahl zu ändern Benutzernamen, die vom System erstellt werden dürfen. Der Befehl lautet: echo 65535> / proc / sys / user / max_user_namespaces, und versuchen Sie dann erneut, Benutzernamen zu erstellen.
Führen Sie dann den Befehl id aus, um die aktuellen Benutzerinformationen zu überprüfen:
[root@centos7 ~]# id
uid=0(root) gid=0(root) groups=0(root),65534(nfsnobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Anhand der obigen Ausgabe können wir erkennen, dass wir bereits der Root-Benutzer im neuen Benutzernamensraum sind. Im Folgenden verwenden wir den Befehl reboot, der nur vom Root-Benutzer des Hosts ausgeführt werden kann, um ihn zu überprüfen, und führen den Befehl reboot im aktuellen Befehlszeilenfenster aus:
[root@centos7 ~]# reboot
Failed to open /dev/initctl: Permission denied
Failed to talk to init daemon.
Wie Sie sehen, sind wir zwar der Root-Benutzer im neu erstellten Benutzernamensraum, haben jedoch nicht die Berechtigung, den Befehl zum Neustart auszuführen. Dies zeigt, dass im isolierten Benutzernamensraum die Stammberechtigung des Hosts nicht abgerufen werden kann, was bedeutet, dass der Benutzernamensraum die Isolation von Benutzern und Benutzergruppen realisiert.
(6) Net Namespace
Der Net Namespace wird verwendet, um Informationen wie Netzwerkgeräte, IP-Adressen und Ports zu isolieren. Mit Net Namespace kann jeder Prozess seine eigenen unabhängigen IP-Adressen-, Port- und Netzwerkkarteninformationen haben. Beispielsweise lautet die Host-IP-Adresse 172.16.4.1, und eine unabhängige IP-Adresse kann im Container auf 192.168.1.1 festgelegt werden.
Verwenden Sie auch die Beispielüberprüfung. Zuerst verwenden wir den Befehl ip a, um die Netzwerkinformationen auf dem Host zu überprüfen:
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:11:b0:14:01:0c brd ff:ff:ff:ff:ff:ff
inet 172.20.1.11/24 brd 172.20.1.255 scope global dynamic eth0
valid_lft 86063337sec preferred_lft 86063337sec
inet6 fe80::11:b0ff:fe14:10c/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:82:8d:a0:df brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:82ff:fe8d:a0df/64 scope link
valid_lft forever preferred_lft forever
Dann verwenden wir den folgenden Befehl, um einen Net Namespace zu erstellen:
unshare --net --fork /bin/bash
In ähnlicher Weise verwenden wir den Befehl ip a, um die Netzwerkinformationen zu überprüfen:
[root@centos7 centos]# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
Wie Sie sehen können, befinden sich auf dem Host Netzwerkgeräte wie lo, eth0 und docker0, und die Netzwerkgeräte in unserem neu erstellten Net Namespace unterscheiden sich von denen auf dem Host.