GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Erstellen eines Containers von Hand unter Verwendung von Namensräumen:Der UTS-Namensraum

Dieser Artikel baut auf meinen vorherigen Artikeln über Namespaces, Die 7 am häufigsten verwendeten Linux-Namespaces und meiner Serie zum manuellen Erstellen eines Linux-Containers mit Namespaces, mit dem Mount-Namespace und mit dem PID-Namespace auf. Dieser Artikel behandelt den UTS-Namespace und seine Beziehung zu Containern.

Der zufällige Beobachter missversteht den Namensraum des Unix Timesharing System (UTS), vor allem weil sein Name nicht mehr seinem Zweck entspricht. Trotz seines Namens kontrolliert der UTS-Namespace tatsächlich den Hostnamen und die NIS-Domäne. So beschreibt die Manpage den UTS-Namespace:

Diese Kennungen werden mit sethostname(2) gesetzt und setdomainname(2) , und kann mit uname(2) abgerufen werden , gethostname(2) und getdomainname(2) . An diesen Bezeichnern vorgenommene Änderungen sind für alle anderen Prozesse im selben UTS-Namensraum sichtbar, jedoch nicht für Prozesse in anderen UTS-Namensräumen.

Dies bedeutet, dass einige moderne Tools (systemd und andere) möglicherweise nicht die erwarteten Änderungen bewirken.

Wie Sie sich vorstellen können, kann es mehrere Anwendungsfälle geben, in denen Prozesse unterschiedliche Hostnamen haben sollen. Webserver beispielsweise neigen dazu, eine Warnung auszugeben, wenn der Hostname nicht mit dem SSL-Zertifikat übereinstimmt, das sie bereitstellen. Andererseits können einige Prozesse den Hostnamen an einen Netzwerkprozess anhängen. Ein falscher Hostname kann fehlgeschlagene oder verweigerte Verbindungen oder unzählige andere Probleme verursachen.

Kommen wir nun zu einigen Beispielen.

Erkunden Sie den UTS-Namespace

Sie können den UTS-Namensraum aufrufen mit:

$ unshare --uts /bin/bash

Möglicherweise stellen Sie jedoch fest, dass Sie, sobald Sie sich im neuen Namespace befinden, hostnamectl set-hostname verwenden ändert den Hostnamen im neuen Namespace nicht.

# unshare --uts
# hostname
bastion.stratus.lab
# hostnamectl set-hostname tux
# hostname
bastion.stratus.lab

Wenn Sie jedoch eine neue Shell öffnen, hat sich der Hostname tatsächlich geändert:

[user@host ~]$ ssh root@bastion
Last login: Tue Dec 7 08:17:48 2021 from 192.168.99.198
[root@tux ~]# hostname
tux

Warum ist das? Systemd führt den sethostname nicht aus Systemaufruf. Stattdessen schließt systemd die Aufgabe ab, indem es sich mit einem Socket verbindet. Da der Socket mit dem alten Namespace verknüpft ist, wird der Hostname des alten Namespace angepasst, aber nicht der neue Namespace.

Root-Namespaces verwenden

In meinem Mount-Namespace-Artikel schreibe ich:

Jetzt, da Sie sich im neuen Namespace befinden, erwarten Sie möglicherweise nicht, einen der ursprünglichen Einhängepunkte des Hosts zu sehen. Dies ist jedoch nicht der Fall. Der Grund dafür ist, dass systemd standardmäßig die Einhängepunkte rekursiv mit allen neuen Namespaces teilt.

Zufällig leitet systemd viele seiner Informationen von /run ab , die in den Namensraum geteilt wird, den ich hier erstellt habe.

Im Mount-Namespace-Artikel mounte ich tmpfs in den neuen Namensraum in einem Verzeichnis, das ich nicht mit dem alten Namensraum teilen möchte.

Ich kann die meisten systemd-Aufrufe deaktivieren, indem ich den neuen Namespace mit den folgenden Optionen einhänge:

$ unshare --mount --uts /bin/bash

Hängen Sie dann /run erneut ein :

$ mount -t tmpfs tmpfs /run

Der gesamte Prozess sieht folgendermaßen aus:

# unshare --fork --mount --uts /bin/bash
# mount -t tmpfs tmpfs /run
# hostnamectl set-hostname bastion.stratus.lab
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
# hostname tux
# hostname
tux

Ich kann dies bestätigen, indem ich eine neue Shell für die Box öffne:

[user@host ~]$ ssh root@bastion
Last login: Tue Dec 7 08:33:04 2021 from 192.168.99.198
[root@bastion ~]# hostname
bastion.stratus.lab

Ich kann den passenden Namensraum finden, indem ich lsns verwende Befehl:

[root@bastion ~]# lsns |grep uts
4026531838 uts 133 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 31
4026532250 uts 1 645 root /usr/lib/systemd/systemd-udevd
4026532405 uts 1 743 root /usr/lib/systemd/systemd-logind
4026532479 mnt 2 11507 root unshare --fork --mount --uts /bin/bash
4026532480 uts 2 11507 root unshare --fork --mount --uts /bin/bash

Den Namensraum kann ich dann mit dem nsenter eingeben Befehl:

[root@bastion ~]# nsenter -t 11507 -a 
[root@tux /]#

Einen Benutzernamensraum verwenden

In meinem Artikel über Benutzernamensräume erwähne ich einige zusätzliche Überlegungen beim Erstellen von Namensräumen als nicht privilegierter Benutzer:

Wenn Sie einen neuen Benutzernamensraum erstellen, wird Ihr aktueller Benutzer dem Benutzer nobody zugeordnet . Dies liegt daran, dass standardmäßig keine Benutzer-ID-Zuordnung stattfindet. Wenn keine Zuordnung definiert ist, verwendet der Namensraum einfach die Regeln Ihres Systems, um zu bestimmen, wie mit einem nicht definierten Benutzer umzugehen ist.

Weitere Informationen zur Benutzerzuordnung finden Sie in diesem Artikel. In diesem Fall möchte ich den Stamm haben Benutzer automatisch zugeordnet. Auf diese Weise habe ich "root" im neuen Namensraum. (Siehe auch hier den Artikel über Namensräume für Benutzer für eine Diskussion über Namensräume und Berechtigungen).

Wenn ich meine kombinierten Lektionen auf einem CentOS Stream 9-Host in die Praxis umsetze, beobachte ich:

ocp@bastion ~  $ unshare --map-root-user --user --mount --uts --fork /bin/bash
root@bastion ~  $ hostnamectl set-hostname tux
Could not set static hostname: Interactive authentication required.

Das liegt daran, wie polkit ist auf der RHEL-Familie von Distributionen konfiguriert. Andere Distributionen werfen diesen Fehler nicht unbedingt aus. Arch Linux (ohne spezielles polkit configuration) erlaubt es dem Container beispielsweise weiterhin, den Hostnamen zu ändern. Daher ist es unabhängig von Ihrer Distribution immer noch eine gute Sicherheitspraxis, /run neu zu mounten .

Es ist wichtig zu beachten, dass die Ausgabe von lsns könnte einfacher zu lesen sein, indem Sie --fork verwenden beim Erstellen von Namespaces.

So sieht es ohne aus --fork Flagge:

[root@bastion ~]# lsns |grep uts
4026531838 uts 135 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 31
4026532250 uts 1 645 root /usr/lib/systemd/systemd-udevd
4026532405 uts 1 743 root /usr/lib/systemd/systemd-logind
4026532414 uts 1 11962 ocp /bin/bash

Und mit dem --fork Flagge:

[root@bastion ~]# lsns |grep uts
4026531838 uts 134 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 31
4026532250 uts 1 645 root /usr/lib/systemd/systemd-udevd
4026532405 uts 1 743 root /usr/lib/systemd/systemd-logind
4026532412 user 2 11939 ocp unshare --map-root-user --user --mount --uts --fork /bin/bash

Während --fork ist in diesem Szenario nicht unbedingt erforderlich, kann aber nützlich oder sogar erforderlich sein, wenn ein neuer PID-Namespace erforderlich ist (weitere Informationen finden Sie in meinem PID-Namespace-Artikel).

Abschluss

Der UTS-Namespace ist nicht der komplizierteste Linux-Namespace. Es ist jedoch sehr nützlich, insbesondere im Zusammenhang mit Containern.

Um den UTS-Namespace optimal zu nutzen, kombinieren Sie ihn mindestens mit dem Mount-Namespace, wenn Sie den Root-Namespace und Mount- und Benutzer-Namespaces verwenden, wenn Sie von einem nicht privilegierten Benutzer spawnen.

[ Laden Sie den mittleren Linux-Spickzettel herunter, um die wichtigsten Befehle immer griffbereit zu haben. ]

In meinem nächsten Artikel werde ich den Net-Namespace besprechen und wie man ihn verwendet, um Namespaces zu ermöglichen, ihre eigenen IP- und Port-Spaces zu haben.


Linux
  1. Fehlerbehebung mit dem proc-Dateisystem unter Linux

  2. Entmystifizierung von Namespaces und Containern in Linux

  3. Linux – Wie listet man Namespaces in Linux auf?

  4. Ausführen einer Qt-App über das Web

  5. Was ist ein UTS-Namespace?

Verwenden des kostenlosen Linux-Befehls

Verwenden der SSH-Konfigurationsdatei

Manuelles Erstellen eines Linux-Containers mithilfe von Namespaces

Erstellen eines Containers von Hand unter Verwendung von Namespaces:Der Mount-Namespace

Eine Einführung in die Containerregistrierung von Quay

Tutorial zur Verwendung des Timeout-Befehls unter Linux