So erstellen Sie einen Linux-Container, der das Root-Dateisystem des Hosts erbt, möglicherweise mit zfs?

588
hak8or

Was

Hoffentlich macht die Frage im Titel Sinn. Ich möchte eine Kopie des Host-Betriebssystems mit geringem Overhead (also keine virtuelle Maschine) erstellen, wobei es in einem Linux-Container ausgeführt wird.

Ich denke irgendwie daran, mit zfs eine Momentaufnahme der rootfs des Hosts zu erstellen und diese dann irgendwie in lxc einzugeben. Auf diese Weise werden alle Änderungen im Container über die ZFS-Funktion zum Schreiben beim Schreiben auf den Container beschränkt, und zukünftige Änderungen an den rootfs des Hosts werden nicht an den Container weitergegeben.

Gibt es mögliche Probleme, die ich berücksichtigen muss, wie z. B. rekursive Verzeichnisse, die Chaos anrichten, oder etwas anderes?

Warum

Der Grund dafür ist, dass ich den Host schnell als Vorlage verwenden und damit spielen kann, z. B. neue Build-Tools installieren, die die rootfs verschmutzen, ohne dass der Host davon betroffen ist, und dass nicht viel Speicherplatz verschwendet wird, wenn die Hosts kopiert werden rootfs. Außerdem habe ich eine anständige Zeit damit verbracht, den Host so einzurichten, wie ich es möchte, und möchte nicht noch ein paar Tage damit verbringen, eine Vorlage für den Prozess zu erstellen (obwohl ich sollte, ist es eine gute Idee, es aufzuschreiben Automatisieren ist sogar noch besser. Da dies in einem Linux-Container wäre, kann ich mehrere Instanzen gleichzeitig ausführen.

3

1 Antwort auf die Frage

3
Deltik

Ich habe ein manuelles Verfahren entworfen, das dies erreichen kann.

Voraussetzungen

Diese Verfahren treffen die folgenden Annahmen:

  • Deine Schale ist /bin/bash.
  • Du bist wurzel
  • Sie haben das Betriebssystem im ZFS-Pool bereitgestellt rpoolund möchten, dass sich der LXD-Container im selben ZFS-Pool ( rpool) befindet.
  • Ihre Host-Rootfs werden im rpool/ROOT/osZFS-Dataset installiert .
  • Sie haben eine Momentaufnahme Ihrer Host-Rootfs gemacht und diese aufgerufen rpool/ROOT/os@20180516T091126CDT.
  • Sie führen das Snappy- Paket von LXD aus.
  • Sie haben einen lxc storageNamen rpool, der den zfsTreiber in der Quelle verwendet rpool/lxd.
  • Sie möchten einen nicht privilegierten Container namens erstellen demo.

Sie müssen das Verfahren für jede Abweichung von den obigen Anforderungen anpassen.

Anleitung

  1. Erstellen Sie einen LXC-Container mit einem Image, das Ihrem Host-Betriebssystem ähnlich ist:

    root@node51 [~]# lxc launch images:ubuntu/18.04 demo -s rpool Creating demo Starting demo 
  2. Stoppen Sie den Container:

    root@node51 [~]# lxc stop demo 
  3. Mounten Sie das LXC-Speichervolume, um einige Metadaten von ihm abzurufen:

    root@node51 [~]# zfs mount rpool/lxd/containers/demo 
  4. Kopieren Sie die Metadaten irgendwo (wie /tmp/demo/):

    root@node51 [~]# rsync -avHXShPs --exclude rootfs/ /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/ /tmp/demo/ sending incremental file list created directory /tmp/demo ./ backup.yaml 2.05K 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=4/6) metadata.yaml 529 100% 516.60kB/s 0:00:00 (xfr#2, to-chk=3/6) templates/ templates/hostname.tpl 21 100% 20.51kB/s 0:00:00 (xfr#3, to-chk=1/6) templates/hosts.tpl 140 100% 136.72kB/s 0:00:00 (xfr#4, to-chk=0/6)  sent 3.12K bytes received 135 bytes 6.50K bytes/sec total size is 2.74K speedup is 0.84 
  5. Löschen Sie das von LXC erstellte ZFS-Dataset:

    root@node51 [~]# zfs destroy rpool/lxd/containers/demo 
  6. Klonen Sie das ZFS-Dataset unter demselben Namen, den LXC erwarten würde:

    root@node51 [~]# zfs clone rpool/ROOT/os@20180516T091126CDT rpool/lxd/containers/demo 
  7. Setzen Sie den Mountpoint auf den ursprünglichen Mountpoint:

    root@node51 [~]# zfs set mountpoint=/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo rpool/lxd/containers/demo 
  8. Erstellen Sie ein rootfs-Verzeichnis für die neuen Containerdaten:

    root@node51 [~]# mkdir -v /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/rootfs/ mkdir: created directory '/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/rootfs/' 
  9. Erweitern Sie die Globbing-Funktionalität Ihrer Shell, um sicherzustellen, dass die kommende mvDatei alle Dateisystemdaten übernimmt:

    root@node51 [~]# shopt -s extglob ; shopt -s dotglob 
  10. Kürzen Sie die kommenden Befehle ein wenig, indem cdSie in das Dataset des Containers gehen:

    root@node51 [~]# cd /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/ root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# 
  11. Verschieben Sie alle Daten des Containers in den rootfs/Ordner:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mv !(rootfs) rootfs/ 
  12. Erstellen Sie einige Ordner, die zum Starten des Containers benötigt werden:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mkdir rootfs/ 
  13. Verschieben Sie die zuvor gesicherten Metadaten in das Dataset des Containers:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mv /tmp/demo/* . 
  14. Entfernen Sie das leere temporäre Verzeichnis aus der Metadatensicherung:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# rm -rfv /tmp/demo removed directory '/tmp/demo' 
  15. Kehren Sie zu Ihrem vorherigen Verzeichnis zurück, damit Sie die Dataset des Containers aushängen können:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# cd - /root 
  16. Hängen Sie das Dataset des Containers ab, damit LXC es übernehmen kann:

    root@node51 [~]# zfs umount rpool/lxd/containers/demo 
  17. Um LXC anzuweisen, die Dateien des Containers beim nächsten Start in unprivilegierte Dateien zu konvertieren, führen Sie Folgendes aus

    lxc config edit demo 

    und ändern Sie die Zeile, die liest

    volatile.last_state.idmap: '[{"Isuid":true,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]' 

    zu

    volatile.last_state.idmap: '[{"Isuid":true,"Isgid":true,"Hostid":1,"Nsid":0,"Maprange":1000000000}]' 
  18. Starten Sie den Container.
    Dies dauert eine Weile, da jede Datei in den rootfs des Containers in nicht privilegierte Dateien umgewandelt wird. Es gibt keine Fortschrittsanzeige.

    root@node51 [~]# lxc start demo 
  19. Geben Sie den Container ein:

    root@node51 [~]# lxc exec demo -- bash 

    Hier können Sie das Netzwerk, die Startsequenz Ihres Systems und / oder andere Dinge konfigurieren, die Sie benötigen, um diesen LXC-Container-Klon Ihres Hosts zum Laufen zu bringen.