TIL: automatischer zfs mount innerhalb einer Jail - per /etc/jail.conf

SolarCatcher

Well-Known Member
Gestern stellte ich auf einem weiteren meiner Server das Jail-Management um von sysutils/iocage auf die Tools aus dem Basis-System (/etc/jail.conf). Eine Sache, die sich dabei als schwieriger erwies, als erwartet, war das automatische Mounten eines ZFS Datasets in einer Jail.

Viele der Hinweise im Netz betreffen iocage (wo es im wesentliche eine Konfigurationszeile ist, s.u.). Eine leicht verständliche Anleitung, wie man das mit /etc/jail.conf macht, ist schwer zu finden. Selbst das ansonsten immer so hilfreiche Buch von Allan Jude und Michael W Lucas "FreeBSD Mastery. Advanced ZFS" hat mir hier nur teilweise weiter geholfen. Daher will ich meine Konfiguration hier mit Euch teilen - auch damit ich sie in Zukunft bei Bedarf wiederfinde.

Hintergrund - wofür ich Kontrolle über ein ZFS Dataset innerhalb einer Jail benötige:
In meiner Webserver-Jail läuft ein WordPress mit einer selbst gestrickten Caching-Funktion. Der Cache muss natürlich ab und zu geleert werden. Bei zig tausenden von Web-Seiten, die dann roh, sowie vor-komprimiert als *.html.gz und *.html.br abgelegt sind, dauert ein rm -rf schon etwas Zeit. Viel schneller und Resourcen schonender ist da ein zfs rollback auf einen leeren Snapshot (ich glaube, das habe ich mal von Colin Percival aufgeschnappt), bei mir heißt der Snapshot @empty. Also muss der Webserver in der Jail selbst ein zfs rollback dieses Datasets ausführen dürfen.

Dazu benötigen wir ein "jailed dataset" und die Delegation von ZFS (dem User www wird zugestanden, u.a. ein Rollback durchzuführen).

Das Dataset (zroot/jail-mounts/www/wordpress-cache) hatte ich schon, daher zeige ich jetzt nicht, wie man es anlegt (man muss ein jailed=on hinzufügen).

Anschließend muss man mit zfs allow die notwendigen Rechte an dem dataset delegieren. Bei mir sieht das dann so aus (Hinweis: rollback allein tut es nicht; ich meine, create,destroy,mount,rollback,snapshot war die kleinste Kombination an Rechten, die ein Rollback erlaubt):
Code:
$ zfs allow zroot/jail-mounts/www/wordpress-cache
---- Permissions on zroot/jail-mounts/www/wordpress-cache -----------
Local+Descendent permissions:
    user root mount,rollback
    user www create,destroy,mount,rollback,snapshot

Wie gesagt, soweit hatte ich das Dataset schon seit Jahren. Jetzt muss es aber noch beim Starten der Jail, in der Jail gemounted werden. Das mache ich in der /etc/jail.conf
Code:
www {
  path="/jails/www/root";

  # Diese 3 allow-Regeln sind notwendig für das Mounten/die Kontrolle über das ZFS Dataset in der Jail
  allow.mount=true;
  allow.mount.zfs=true;
  enforce_statfs=1;

  # Hier wird das mit jailed=on ausgestattete Dataset an die Jail www gebunden
  exec.poststart="/sbin/zfs jail www zroot/jail-mounts/www/wordpress-cache";

  # Hier wird es dann in der Jail gemounted
  exec.poststart+="/usr/sbin/jexec -l www zfs mount zroot/jail-mounts/www/wordpress-cache";

  # Und wieder unmounten
  exec.prestop="/usr/sbin/jexec -l www zfs umount zroot/jail-mounts/www/wordpress-cache";

  # Und die Bindung an die www Jail aufheben
  exec.prestop+="/sbin/zfs unjail www zroot/jail-mounts/www/wordpress-cache";
}

Statt exec.poststart kann man offenbar auch exec.created verwenden, statt exec.prestop dann exec.release (siehe https://forums.freebsd.org/threads/...exec-inside-a-jail-native-zfs-solution.96178/)

In der www-Jail ist es nun gemounted unter /zroot/jail-mounts/www/wordpress-cache (hätte den Mountpoint auch anders setzen können). Mount sagt:
Code:
zroot/jail-mounts/www/wordpress-cache on /zroot/jail-mounts/www/wordpress-cache (zfs, local, noatime, nfsv4acls)

Fertig. Nun kann der Webserver (User www) innerhalb der Jail ein zfs rollback zroot/jail-mounts/www/wordpress-cache@empty durchführen, um den Cache zu leeren.

Der Vollständigkeit halber: So ging das, was ich oben in /etc/jail.conf gezeigt habe, unter iocage (Auszug aus der config.json der Jail www):
Code:
{
    ...
    "allow_mount": 1,
    "allow_mount_zfs": 1,
    "enforce_statfs": "1",
    "jail_zfs": 1,
    "jail_zfs_dataset": "jail-mounts/www/wordpress-cache",
    ...
}
 
@Rob

Erstens, weil es ausschließlich in jener Jail benötigt wird.

Aber viel wichtiger - ich hab's gerade getestet: Die Kontrolle über das Dataset in der Jail geht verloren, wenn man die Jail neustartet ohne das Dataset zu unmounten und zu unjailen. Man kann dann in der Jail kein Rollback oder umount ausführen. Der Vorteil des jailed Datasets ist dann komplett futsch.
 
Hast du das mal geprüft, ob nur jail/unjail auch reichen würde?
Hab's jetzt mal probiert: Nein, auch das funktioniert nicht. Das Dataset bleibt gemounted, aber wenn ich dann die Jail wieder starte, habe ich von drinnen keine Kontrolle über das Dataset (kann z.B. kein zfs mount ausführen; es fehle mir die Berechtigung).

Aber ich sähe für mich auch keinen Sinn darin. Dieses Dataset wird nur in dieser Jail benötigt. Wenn ich diese Jail runterfahre, benötige ich auch das Dataset nicht mehr. Höchstens bei einem Restart dieser Jail könnte es theoretisch Sinn machen, um ein paar Millisekunden für die Abfolge unmount, unjail, jail, mount zu sparen. Aber selbst das wäre für mich nicht relevant und würde die Komplexität nur unnötig erhöhen: Man müsste in jail.conf immer erst testen, ob das Dataset schon gemounted ist, wenn die Jail gestartet wird und dieses nur bei Bedarf nach-mounten.

Ich bin happy mit dieser Lösung und jail.conf.
 
Zurück
Oben