Zum Inhalt

Proxmox-Cluster mit Ceph

Basissetup

  1. Proxmox installieren (mit ZFS)
  2. Proxmox-Root verschlüsseln 1
    1. System von einem externen Medium mit ZFS-Support starten (z.B. Ubuntu oder im Proxmox-Installer Ctrl+Alt+F3 drücken, das ist jedoch sehr unkomfortabel).
    2. In der Shell folgende Schritte ausführen:
      # Aktuellen Root-Pool importieren
      zpool import -f rpool
      
      # Einen Snapshot erstellen
      zfs snapshot -r rpool/ROOT@copy
      
      # Ein temporäres Dateisystem aus dem Snapshot erzeugen
      zfs send -R rpool/ROOT@copy | zfs receive rpool/copyroot
      
      # Das alte Dateisystem löschen
      zfs destroy -r rpool/ROOT
      
      # Ein neues Dateisystem mit aktivierter Verschlüsselung erstellen
      zfs create -o encryption=on -o keyformat=passphrase rpool/ROOT
      
      # Die Dateien vom temporären in das neue Dateisystem kopieren
      zfs send -R rpool/copyroot/pve-1@copy | zfs receive\
          -o encryption=on rpool/ROOT/pve-1
      
      # Den Mountpoint des neuen Dateisystems setzen
      
      # Falls dies hängt, das System booten, im initramfs den Pool
      # importieren und dort den Mountpoint setzen. Danach weiter
      # wie beschrieben.
      
      zfs set mountpoint=/ rpool/ROOT/pve-1
      
      # Prüfen, dass alles verschlüsselt ist
      zfs get encryption
      
      # Das temporäre Dateisystem löschen
      zfs destroy -r rpool/copyroot/pve-1@copy
      zfs destroy -r rpool/copyroot
      
      # Den Pool wieder exportieren
      zpool export rpool
      
    3. System neustarten
  3. System updaten

    1. Packagelists anpassen
      # No-Subscription Repo anlegen
      echo "deb http://download.proxmox.com/debian/pve\
          bullseye pve-no-subscription" >\
          /etc/apt/sources.list.d/pve-no-subscription.list
      
      # Enterprise-Repo löschen
      rm /etc/apt/sources.list.d/pve-enterprise.list
      
    2. Updaten
      apt update
      apt full-upgrade
      
  4. SSH einrichten

    1. SSH-Keys hinterlegen (/root/.ssh/authorized_keys)
    2. SSHD-Konfiguration anpassen (/etc/ssh/sshd_config)
      # Port 22 wird immer für die Clusterkommunikation benötigt,
      # kann aber natürlich später mit Firewallregeln auf die
      # betroffenen Hosts beschränkt werden. Auf jeden Fall muss Port
      # 22 hier zusätzlich angegeben werden.
      # Port 2222
      Port 22
      
      # Root-Login nur mit Key
      PermitRootLogin prohibit-password
      
      # Passwort-Login verbieten
      PasswordAuthentication no
      
      # TCP-Forwarding (Tunnel) erlauben
      AllowTcpForwarding yes
      
      # X11-Weiterleitung verbieten
      X11Forwarding no
      
  5. Remote-Unlock aktivieren

    1. dropbear-initramfs installieren (apt install dropbear-initramfs)
    2. initramfs mit fester IP ausstatten (/etc/initramfs-tools/initramfs.conf)
      IP=192.168.1.100::192.168.1.1:255.255.255.0::enp2s0:off
      
    3. dropbear konfigurieren (/etc/dropbear-initramfs/config)
      # z.B. -p2222 für Port 2222
      DROPBEAR_OPTIONS=
      
    4. Keys für dropbear hinterlegen
      # Autorisierte Schlüssel hinterlegen
      cp /root/.ssh/authorized_keys /etc/dropbear-initramfs
      
      # Hostkeys konvertieren
      rm /etc/dropbear-initramfs/*_key
      cd /etc/ssh
      for file in ssh_host_*_key; do
          echo Konvertiere $file
          cp $file /tmp/$file
          ssh-keygen -m PEM -p -f /tmp/$file
          newfile=${file/ssh_host/dropbear}
          newfile=${newfile/key/host_key}
          dropbearconvert openssh dropbear /tmp/$file /tmp/$newfile
          mv /tmp/$newfile /etc/dropbear-initramfs/ 
          rm /tmp/$file
      done
      
      # Ramdisk updaten
      update-initramfs -u
      
  6. Datenset verschlüsseln

Info

Die Datenpartition wird mit einem Key verschlüsselt, der im Dateisystem des Servers liegt. Dieser ist durch die Verschlüsselung des Root-Sets geschützt, wenn der Server ausgeschaltet ist, ist jedoch prinzipiell lesbar, wenn der Server läuft.

Die Rechte des Keyfiles sind konservativ gesetzt (Zugriff nur für root) dennoch bleibt dies eine Abwägung zwischen Komfort und Sicherheit.

Besser wäre eine spezifische Key-Partition, die nach dem Booten wieder gesperrt würde. Dies ist bei Nutzung von Ceph jedoch ohnehin nicht möglich, da die Keys für Ceph im Root-Dateisystem der Monitore liegen und verfügbar sein müssen.

Tip

Optional: Insbesondere bei Clustereinrichtung sollte in Proxmox der Storage (local-zfs) gelöscht und nach der Verschlüsselung ein passender neuer angelegt werden, der der Storage-ID im Cluster entspricht.

# Key generieren
dd if=/dev/urandom of=/root/local.key bs=32 count=1
chmod 600 /root/local.key

# Datenset löschen
zfs destroy -r rpool/data

# Neues, verschlüsseltes Datenset anlegen
zfs create -o encryption=on -o keyformat=raw \
    -o keylocation=file:///root/local.key rpool/data

# Dienst zum Unlock beim Systemstart anlegen
cat > /etc/systemd/system/zfs-load-key.service <<EOF
[Unit]
Description=Load encryption keys
DefaultDependencies=false
Before=zfs-mount.service
After=zfs-import.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/zfs load-key -a

[Install]
WantedBy=zfs-mount.service
EOF

# Dienst aktivieren
systemctl enable zfs-load-key.service

Warning

Anschließend den Key (/root/local.key) sichern!

  1. Netzwerkkonfiguration vornehmen
    1. Alle Schnittstellen auf MTU 9000 einstellen (unter Advanced)
    2. Mindestens ein eigenes Netz für den Cluster und Ceph erstellen (vorzugsweise 10G)
    3. Bridge anlegen für VLANs für die VMs anlegen (vmbr1, vorzugsweise 10G)
    4. IPs passend festlegen
    5. Konnektivität prüfen

Clusterkonfiguration

  1. Einrichtung des Clusters auf einer der Nodes über die GUI. Der Link sollte auf das schnelle Netz zeigen.

  2. Die anderen Nodes über die GUI joinen.

  3. Bei komplexeren Setups mit Failover etc. bietet es sich an, die Adressen der Hosts in den Hosts-Datei zu spezifizieren und die /etc/corosync/corosync.conf manuell anzupassen. Siehe Seperate Cluster Network im Proxmox-Wiki.

Warning

Bei jeder Änderung der /etc/corosync/corosync.conf muss die config_version erhöht werden, damit die Datei im Cluster aktiv wird!

  1. Das Migration-Netzwerk sollte vom Cluster-Netzwerk getrenn sein und muss dann manuell festgelegt werden. Dies erfolgt in der /etc/pve/datacenter.cfg:
migration: secure,network=192.168.10.0/24

Ceph-Einrichtung

Grundeinrichtung

  1. Ceph auf dem ersten Node in der GUI installieren (Advanced aktivieren), Netzwerke passend auswählen, Replicas passend einstellen.
  2. Ceph auf den anderen Nodes in der GUI installieren (Adcanced aktivieren).
  3. Monitore, Manager und Metadata-Server auf den weiteren Nodes hinzufügen.
  4. OSDs auf allen Nodes hinzufügen, dabei für HDD evtl. WAL+DB auf SSD auslagern sowie Encryption aktivieren.

Tip

Wenn WAL+DB auf einer Partition angelegt werden soll, muss zunächst das LVM vorbereitet werden, dazu: 1. Mit fdisk Partition anlegen (Typ 30) 2. LVM anlegen

# Physival Volume erstellen
pvcreate /dev/sdX4

# Volumegroup erstellen
vgcreate ceph-db-0 /dev/sdX4

Pools einrichten

Replikation verwenden

  1. Wenn SSDs und HDDs zum Einsatz kommen, können unterschiedliche Crush-Regeln angelegt werden, um Pools für schnellen und langsamen Speicher zu erstellen:

    ceph osd crush rule create-replicated replicated_hdd default host hdd
    ceph osd crush rule create-replicated replicated_ssd default host ssd
    

  2. Pools anlegen und dabei die Crush-Regeln und die Redundanz (Replicas = Original + Anzahl Kopien) passend auswählen.

Erasurecode verwenden

Es ist auch möglich, Erasurecode zu verwenden. So werden Daten nicht vollständig repliziert, sondern Prüfsummen erstellt (ähnlich zu RAID5 etc.). Dies benötigt mehr Rechenleistung und etwas bis erheblich weniger Speicherplatz. Hier wird von einer Konfiguration analog zu RAID5 ausgegangen, d.h. auf zwei Datenblöcke (k=2) kommt ein Paritätsblock (m=1). Somit kann der Ausfall einer Einheit kompensiert werden. Dies ist nur für unwichtige Daten sinnvoll, denn es ist sehr wahrscheinlich, dass beim Recovery eine zweite Einheit ausfällt (analog zu RAID5). Es geht also lediglich darum, den Betrieb aufrecht zu erhalten. Notfalls kann später ein vorhandenes Backup eingespielt werden.

Dieses Problem lässt sich durch weitere Nodes / OSDs verkleinern, sodass es nicht mehr so kritisch wie bei einem RAID5 ist. Außerdem können natürlich mehr redundante Blöcke vorgehalten werden (m>1).

k+m entspricht der Anzahl der benötigten Nodes (wenn die Fehlerdomain auf 'host' eingestellt wird).

# EC-Profil anlegen
ceph osd erasure-code-profile set erasure_medien_hdd\
    plugin=jerasure k=2 m=1 technique=reed_sol_van\
    crush-root=default crush-failure-domain=host\
    crush-device-class=hdd

# Pool erstellen
ceph osd pool create cephfs_ec_data 128 erasure erasure_medien_hdd

# Overwrites für CephFS-Nutzung erlauben
ceph osd pool set cephfs_ec_data allow_ec_overwrites true

# Gleichzeitiges lesen von mehreren OSDs
ceph osd pool set cephfs_ec_data fast_read true

VM-Disks anlegen

Die Pools können direkt als Storage genutzt werden. Wichtig ist, dass als Dateisystem XFS verwendet wird. Dies ist etwas schneller und deutlich stabiler in den Transferraten als ext4. Außerdem kann man zur Leistungssteigerung den Writeback-Cache aktivieren und den IO-Thread aktivieren (dazu als SCSI-Controller in der VM Virtio SCSI single auswählen.

CephFS nutzen

Wenn man CephFS nutzt, können die angelegten Pools entsprechenden Crush-Regeln zugewiesen werden. Der Metadata-Pool sollte immer auf SSDs liegen!

  1. Zugangsdaten auf dem Cluster anlegen
    # ceph fs authorize <cephfs-name> client.<nutzername> 
    # <verzeichnis> <berechtigung> ... <verzeichnis> <berechtigung>
    ceph fs authorize cephfs client.daniel / rw
    
  2. Den angezeigten Key in eine Datei auf dem Client kopieren
  3. Vom Client aus mounten
    mount.ceph <monitor-ip>:/ /mnt -o name=daniel,secretfile=ceph.key
    
  4. Oder in der /etc/fstab eintragen:
    <mon1_ip>,<mon2_ip>,<mon3_ip>:/       /mnt/cephfs/    ceph    name=<username>,secretfile=<keyfile>,noatime,_netdev      0 0
    

Sehr viele weitere Einstellungen und sehr differenzierte Berechtigungen sind möglich. Siehe Client-Auth.

CephFS mit Erasurecode-Pool nutzen

Es kann, aufgrund des geringeren Speicherplatzbedarfs, sinnvoll sein, für den CephFS-Pool einen Erasurecode-Pool zu verwenden. Dies ist nur für den Datenpool möglich, der Metadatenpool muss immer ein replizierter Pool sein.

# Zu CephFS hinzufügen
ceph fs add_data_pool cephfs cephfs_ec_data

Auf dem Client im (als client.admin) gemounteten Filesystem:

# Unterverzeichnis anlegen
mkdir ec

# Verzeichnis an neuen Pool binden
setfattr -n ceph.dir.layout.pool -v cephfs_ec_data ec

VM-Disk vs. gemountetes CephFS

Man kann statt eine VM-Disk anzulegen auch ein CephFS direkt mounten. Dies hat verschiedene Vor- und Nachteile.

Eigenschaft Disk Mount
einfachere Einrichtung
Backup in Proxmox möglich
als Systemlaufwerk nutzbar
Nutzung von verschiedenen Clients gleichzeitig
"unbegrenztes" Wachstum
geringfügig höhere Geschwindigkeit

Fußnoten


  1. Native ZFS-Verschlüsselung mit Proxmox: Quelle