====== Proxmox VE ======
Proxmox VE (Proxmox Virtual Environment; kurz PVE) ist eine auf Debian basierende Open-Source-Virtualisierungsplattform zum Betrieb von virtuellen Maschinen mit einer Web-Oberfläche zur Einrichtung und Steuerung von x86-Virtualisierungen. Die Umgebung basiert auf QEMU mit der Kernel-based Virtual Machine (KVM). PVE bietet neben den Betrieb von klassischen virtuellen Maschinen (Gastsystemen), die auch den Einsatz von Virtual Appliances erlauben, auch LinuX Containers ([[linux:LXC]]) an.
Durch die Verwendung einer Web-Oberfläche wird ein Großteil der einfachen Arbeiten wie das Einrichten, Starten und Stoppen, Erstellen von Backups und Verwaltung der Netzwerkinfrastruktur und der laufende Betrieb von virtuellen Maschinen und den dazugehörigen Speichersystemen am Hostsystem erleichtert. Weiters können Cluster von mehreren PVE-Hostsystemen basierend auf der Corosync Cluster Engine gebildet werden welche gemeinsam verwaltet werden und zwischen welchen virtuelle Maschinen und deren virtuelle Festplattenspeicher ausgetauscht werden können. Dies ermöglicht den Aufbau von Hochverfügbarkeitsclustern.
Quelle: [[wpde>Proxmox VE|Wikipedia]]
[[https://www.proxmox.com/en/news/press-releases/proxmox-ve-6-0|PVE 6.0]] bietet eine Integration von [[software:ceph storage cluster|Ceph Nautilus]] und [[https://www.proxmox.com/en/downloads?task=callelement&format=raw&item_id=54&element=f85c494b-2b32-4109-b8c1-083cca2b7db6&method=download&args[0]=7761f1fd3732b531f946a3c5cdaf601d|weitere Verbessserungen]].
===== Links =====
* [[https://github.com/Corsinvest/awesome-proxmox-ve|AWESOME Proxmox VE documentation, tools, and resources for any user or developer.]]
* [[https://forum.proxmox.com/threads/problem-ipv6-f%C3%BCr-vms-im-subnetz-von-hetzner.36211/|Problem: IPv6 für VMs im Subnetz von Hetzner]]
* [[https://www.thielomat.de/proxmox-server-bei-hetzner-einrichten/|Proxmox Server bei Hetzner einrichten]]
* [[https://www.silvesterlangen.de/?Proxmox_PVE___Proxmox_Haertung|Proxmox Härtung]]
* https://bobcares.com/blog/proxmox-failed-to-run-vncproxy/
* [[https://github.com/dustinrue/proxmox-packer|CentOS Packer Builder for Proxmox]]
===== Installation und Einrichtung =====
Bei der Installation vom Proxmox-ISO werden abgefragt:
- root-Passwort (aktuell x...)
- E-Mail-Adresse für fail-over-Warnungen etc.
Leider kann die Partitionierung nicht beeinflusst werden, daher kann es Sinn machen Proxmox auf einem Debian nachzuinstallieren: [[https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_Stretch|Install Proxmox VE on Debian Stretch]].
==== Installation auf debian 10 (veraltet) ====
https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_Buster
nano /etc/hosts
hostname --ip-address
echo "deb http://download.proxmox.com/debian/pve buster pve-no-subscription" > /etc/apt/sources.list.d/pve-install-repo.list
wget http://download.proxmox.com/debian/proxmox-ve-release-6.x.gpg -O /etc/apt/trusted.gpg.d/proxmox-ve-release-6.x.gpg
chmod +r /etc/apt/trusted.gpg.d/proxmox-ve-release-6.x.gpg
apt update && apt full-upgrade
apt install proxmox-ve postfix open-iscsi
apt remove os-prober
==== Installation auf debian 11 ====
:!: Vor der Installation sollte man schon mal ifconfig2 installieren und phsykalischen Zugriff (bzw. via Konsole) haben. Es kann nämlich sein das interfaces umbenannt werden (z.B. nach eno1) und dann die config nicht mehr funktioniert wenn die alten Gerätenamen in bridges etc. referenziert werden.
https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_11_Bullseye
wget https://enterprise.proxmox.com/debian/proxmox-release-bullseye.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bullseye.gpg
echo "deb [arch=amd64] http://download.proxmox.com/debian/pve bullseye pve-no-subscription" > /etc/apt/sources.list.d/pve-install-repo.list
sha512sum /etc/apt/trusted.gpg.d/proxmox-release-bullseye.gpg
# 7fb03ec8a1675723d2853b84aa4fdb49a46a3bb72b9951361488bfd19b29aab0a789a4f8c7406e71a69aabbc727c936d3549731c4659ffa1a08f44db8fdcebfa /etc/apt/trusted.gpg.d/proxmox-release-bullseye.gpg
apt update && apt full-upgrade
apt install proxmox-ve
systemctl disable rpcbind
systemctl stop rpcbind
apt remove os-prober
# create bridge
reverse-Proxy-Config 443 -> https://localhost:8006
=== /etc/network/interfaces ===
proxmox schreibt die /etc/network/interfaces um, evtl. wird dadurch eine vorhandene config durcheinander gebracht.
auto lo
iface lo inet loopback
iface eno1 inet manual
iface eno2 inet manual
iface eno3 inet manual
iface eno4 inet manual
auto vmbr0
iface vmbr0 inet static
address 1.2.3.4/27
gateway 5.6.7.8
bridge-ports eno4
bridge-stp off
bridge-fd 0
#Kommentar
==== Upgrade von 6.x (buster) auf 7.x (bullseye) ====
https://pve.proxmox.com/wiki/Upgrade_from_6.x_to_7.0
Wechsel auf ifupdown2 (wenn nicht bereits installiert): ''apt install ifupdown2''
Unpacking intel-microcode (3.20230214.1~deb10u1) over (3.20200616.1~deb10u1) ...
Errors were encountered while processing:
/tmp/apt-dpkg-install-uXKy99/171-amd64-microcode_3.20230719.1~deb10u1_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
''apt remove amd64-microcode''
zusätzlich bridge_hw wenn die Umgebung die gleiche MAC auf der bridge erwartet wie auf dem Interface: ''bridge_hw eno3''
(vor die Zeile von ''bridge_ports eno3'').
siehe auch: https://www.stefanux.de/wiki/doku.php/debian/debian#upgrade-deb10-buster-deb11-bullseye
==== Upgrade von 7.x (bullseye) auf 8.x (bookworm) ====
https://pve.proxmox.com/wiki/Upgrade_from_7_to_8
==== VLAN Config ====
VLANS können (bei entsprechender Unterstützung durch den Switch via tagging) unterschiedliche virtuelle Netze aufspannen.
Dazu wird eine "Vlan aware"-bridge einrichtet und anschließend in der Konfiguration der VM das entsprechende VLAN gesetzt werden (oder im Betriebssystem angeben werden falls es eine Firewall ist).
Achtung: Falls die Netzwerkkarte oder der Switch nicht 4096-Vlans unterstützt, muss die komplette Liste:
bridge-vlan-aware yes
bridge-vids 1-4096
durch eine spezfischere Angabe ersetzt werden:
bridge-vlan-aware yes
bridge-vids 100 101 102
https://forum.proxmox.com/threads/question-how-to-create-vlan-aware-bridge-with-linux-bridge.85170
==== LDAP Config ====
Konfigurationsdatei: /etc/pve/domains.cfg
* $SERVER hostname vom LDAP-Server
* $DOMAIN domain
* $TLD Endung
Beispiel sind der Baum proxmox.apps.$DOMAIN.$TLD mit Filter auf die Gruppe mit gid 1000 oder gid 1001
pam: pam
comment Linux PAM standard authentication
pve: pve
comment Proxmox VE authentication server
ldap: LDAP
base_dn cn=users,dc=$DOMAIN,dc=$TLD
comment my LDAP-Directory ($SERVER.$DOMAIN.$TLD)
server1 $SERVER.$DOMAIN.$TLD
user_attr uid
bind_dn cn=proxmox,cn=apps,dc=$DOMAIN,dc=$TLD
filter (|(gidNumber=1000)(gidNumber=1001))
group_filter cn=proxceph_admins
group_dn dc=$DOMAIN,dc=$TLD
group_classes groupOfNames
default 1
secure 1
sync-defaults-options enable-new=1,full=1,purge=0,scope=both
==== nginx umleitung Standard-Host auf https ====
echo "" > /var/www/html/index.nginx-debian.html
/etc/nginx/sites-enabled/default (SERVER.DOMAIN.TLD durch den korrekten FQDN ersetzen)
server{
listen 80;
listen [::]:80;
server_name SERVER.DOMAIN.TLD;
server_tokens off;
return 301 https://SERVER.DOMAIN.TLD$request_uri;
}
==== nginx config GUI ====
Achtung: Fehler bei der Websocket-Configuration bricht die Funktionalität der Oberfläche und die Konsolen-Funktion kann kaputt gehen.
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=APP_cache:10m max_size=3g inactive=120m use_temp_path=off;
upstream proxmox {
server 127.0.0.1:8006;
}
server {
listen 80;
listen [::]:80;
server_name SERVER.DOMAIN.TLD;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name SERVER.DOMAIN.TLD;
ssl_certificate /etc/letsencrypt/live/SERVER.DOMAIN.TLD/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/SERVER.DOMAIN.TLD/privkey.pem;
# Disable broken TLS precursors. (Newer nginx versions already disable SSLv3.0 by default, but it doesn't hurt to be explicit.)
# If this is an internal server and you don't have to support legacy clients, try disabling TLS 1.0 and TLS 1.1, too!
ssl_protocols TLSv1.2 TLSv1.3;
# Don't let clients pick the cipher suite, it's insecure. Let the server pick the strongest one supported by the client.
ssl_prefer_server_ciphers on;
# https://serverfault.com/questions/417512/disable-deflate-compression-in-nginx-ssl/417557#417557
# SSL compression is turned off by default in nginx 1.1.6+/1.0.9+ (if OpenSSL 1.0.0+ used) and nginx 1.3.2+/1.2.2+ (if older versions of OpenSSL are used).
# If you see SSL compression, you probably want to upgrade nginx.
# Another obvious solution is to recompile OpenSSL without zlib compression support (which is actually the default).
# Debug these cipher suite strings with 'openssl ciphers -v ', `man (1) ciphers` is also helpful.
# Bonus round: if you feel like it, enable and prefer Chacha20-Poly1305 stream cipher (TLS 1.3 preview):
ssl_ciphers CHACHA20:-AES:AESGCM:AESCCM:!kRSA:!PSK:!aECDSA:!aDSS:!aNULL:!eNULL:!SHA1:!MD5;
# See here about safety of elliptic curves: https://safecurves.cr.yp.to/
# Pick strong curves for ECDHE key exchange (keep in mind that all commonly used curves in TLS <= 1.2 came from the NSA):
# Bonus round: if you feel like it, enable and prefer the new Ed25519 curve (TLS 1.3 preview):
ssl_ecdh_curve X25519:secp521r1:secp384r1;
# Diffie Hellman parameters for DH(E) key exchange.
# Generate these using our ansible role diffie_hellman_parameters or manually using 'openssl dhparam -outform PEM -out /etc/ssl/private/dhparam2048.pem 2048'. Make sure to set appropiate access rights!
# DH param size should match RSA key size, so if you use RSA 4096 make sure you use 4096 bit DH params, too! (Some legacy clients will choke on 4096 bit DH though.)
ssl_dhparam "/etc/ssl/private/dhparam.pem";
# HSTS (ngx_http_headers_module is required) (63072000 seconds: 1 year)
add_header Strict-Transport-Security "max-age=31536000";
# Enable tls session cache and tickets, so clients can re-use their existing tls session in multiple successive tcp sessions.
ssl_session_cache shared:SSL:10m;
ssl_session_tickets on;
ssl_session_timeout 30m;
# Enable OCSP stapling.
ssl_stapling on;
ssl_stapling_verify on;
# For a resolution of the OCSP responder hostname, the resolver directive should also be specified.
# resolver 127.0.0.1;
add_header Strict-Transport-Security "max-age=31536000";
client_max_body_size 25m;
charset utf-8;
access_log /var/log/nginx/SERVER.DOMAIN.TLD-access.log;
error_log /var/log/nginx/SERVER.DOMAIN.TLD-error.log;
# ask search engines not to index the site
add_header X-Robots-Tag "noindex, nofollow";
gzip on;
gzip_types text/plain text/css application/javascript application/json;
gzip_vary on;
proxy_redirect off;
location / {
client_max_body_size 50M;
# proper websocket proxying
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_connect_timeout 3600s;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
# don't buffer anything
proxy_request_buffering off;
proxy_buffering off;
proxy_pass https://proxmox;
}
}
* DH-Parameter erzeugen (hier 4096 wenn Zertifikat 4096 ist): ''openssl dhparam -outform PEM -out /etc/ssl/private/dhparam.pem 4096''
* Zugriffsrechte: ''chmod 600 /etc/ssl/private/dhparam.pem''
* aktivieren: ''ln -s /etc/nginx/sites-available/SERVER.DOMAIN.TLD.conf /etc/nginx/sites-enabled/SERVER.DOMAIN.TLD.conf''
* nginx-service restarten: ''systemctl restart nginx''
* rpc deaktivieren: ''systemctl stop rpcbind.socket && systemctl stop rpcbind && systemctl disable rpcbind''
==== Import von Qcow2-Images ====
* Images auf einen proxmox-Host kopieren
* Config anlegen und ID unten angeben
* Import (kopiert Daten um!)qm importdisk $IMAGE.qcow2 $POOL
* Config ändern (import ist "unused disk0"):
* virtio
* boot einstellen!
==== ISO-Dateien ablegen ====
Ablage:
* lokal: auf /var/lib/vz/template/iso
* alle storages die "ISO Image" haben
==== Cloud-init ====
Proxmox unterstützt Cloud-init, auch in der GUI:
In den Eigenschaften jeder VM kann der Punkt "Cloud-init" ausgewählt werden, dort sind die folgenden Eigenschaften veränderbar:
* User
* Password (wird intern als SHA256crypt $5$ gespeichert, Beispiel aus /etc/pve/nodes/$NODE/qemu-server/$ID.conf: //cipassword: $5$vlbrCF8u$VQPgETDENSxDIi0fgxoLGLa3P.p6/mbYq4eblMvR2Q2//
* DNS-Domain
* DNS-Servers
* SSH-Public key
* IP-config (grafisch editierbar: v4: static oder DHCP v6: static, DHCP, SLAAC
Grundsätzlich ist dafür ein storage mit der Eigenschaft "Snippet" notwendig, dort wird die (aus den o.g. Parametern automatisch generierte) qcow2-Datei (ein ISO) abgelegt.
Diese wird bei der Migration auf eine andere Proxmox-Node ebenfalls migriert.
:!: Achtung: Falls eine Custom-config benutzt wird (eine extra yaml-Datei mit mehr Optionen) muss der snippet-storage allerdings auf allen Nodes verfügbar sein (Clusterdateisystem). Warum?
Proxmox generiert die cloud-init-Datei bei Start neu, dazu fehlt ihm aber die custom-config und folglich sclägt der Start der VM fehl.
=== Links ===
* https://pve.proxmox.com/wiki/Cloud-Init_Support
* https://pve.proxmox.com/wiki/Cloud-Init_FAQ
* [[https://gist.github.com/KrustyHack/fa39e509b5736703fb4a3d664157323f|Prepare Cloud-Init Templates]]
* [[https://www.yanboyang.com/clouldinit/|Create Proxmox cloud-init template]]
* [[https://bugzilla.proxmox.com/show_bug.cgi?id=2208|Snippet management using the API]] (offen)
* https://www.youtube.com/watch?v=shiIi38cJe4
* https://docs.technotim.live/posts/cloud-init-cloud-image/
* https://gist.github.com/aw/ce460c2100163c38734a83e09ac0439a
* https://www.yanboyang.com/clouldinit/
=== cloud-init with CLI-tools ===
* https://www.reddit.com/r/Proxmox/comments/108ctxf/looking_for_a_script_to_automatically_pull_the/
* https://austinsnerdythings.com/2023/01/10/proxmox-ubuntu-22-04-jammy-lts-cloud-image-script/
=== ansible ===
**[[https://github.com/selfhostx/ansible/tree/main/playbooks/proxmox|selfhostx playbooks]]**
- name: Clone VM
community.general.proxmox_kvm:
ciuser: "user
cipassword: "$6$password_hash"
=== CLI ===
Beispiele via CLI:
qm set $ID --sshkey $Pfad
qm set $ID --ipconfig0 $PFconfig
qm set $ID --ciuser $username
intern wird für die VM ein ISO erzeugt, das geht mit dem folgenden GUI
''qm set $ID --ide2 $SNIPPET_STORAGE:cloudinit''
Beispielausgabe für ID 139 mit storage "local" auf /var/lib/vz:
update VM 139: -ide2 local:cloudinit
Formatting '/var/lib/vz/images/139/vm-139-cloudinit.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=metadata compression_type=zlib size=4194304 lazy_refcounts=off refcount_bits=16
ide2: successfully created disk 'local:139/vm-139-cloudinit.qcow2,media=cdrom'
generating cloud-init ISO
=== custom config ===
Die Konfigurationsoptionen in der Oberfläche sind sehr begrenzt, daher gibt es schnell Bedarf eigene user, network oder meta-data einzubinden.
Wenn also im Speicher local (im Ordner snippets) die Datei user-data liegt, muss diese so angegeben werden:
**[[software:ansible]]**
- name: Configure VM
community.general.proxmox_kvm:
cicustom: "user=local:snippets/user-data"
# [...]
**CLI**: ''qm set 100 --cicustom "user=local:snippets/user-data,network=snippets:snippets/network-config,meta=snippets:snippets/meta-data"''
[[https://gist.github.com/aw/ce460c2100163c38734a83e09ac0439a|Quelle]]
=== Regenerate Template ===
VM --> Cloud-Init --> Regenerate Template
Leider ist dies nicht über einen Kommandozeilenbefehl realisierbar, sondern nur über den workaround zurück auf cdrom, dann wieder typ cloudinit zu stellen.
Hier ein [[https://forum.proxmox.com/threads/regenerate-cloud-init-image-using-ansible.89964/|Beispiel mit dem alten proxmox_api-Modul]].
=== Anforderungen an den Snippet-Storage ===
Der snippet-Storage sollte im ganzen proxmox-Cluster verfügbar sein (Cluster-Dateisystem, KEIN local-storage!):
Bei einer Migration wird zwar augenscheinlich die ISO mitmigriert:
2022-05-29 22:50:35 successfully imported 'local:139/vm-139-cloudinit.qcow2'
2022-05-29 22:50:35 volume 'local:139/vm-139-cloudinit.qcow2' is 'local:139/vm-139-cloudinit.qcow2' on the target
2022-05-29 22:50:36 migration finished successfully (duration 00:00:04)
Der Start funktioniert jedoch dennoch nicht: TASK ERROR: can't open '/var/lib/vz/snippets/user-data-$hostname.yml' - No such file or directory ...weil er die Quelle des Cloud-Init-Laufwerks halt nicht mehr verfügbar hat.
==== Login Banner verändern ====
''https://\4{vmbr0}:8006/''
[[https://www.reddit.com/r/Proxmox/comments/118i6ct/tutorialguide_how_to_make_the_prelogin_banner/|Quelle]]
===== Kosten =====
Ohne eine Subskription:
- wird bei Web-Login eine Warnmeldung angezeigt
- Zugriff auf das enterprise-Repo von Proxmox ist nicht möglich -> keine Kernel-Updates oder Zugriff auf kernel-header
Die [[https://www.proxmox.com/de/proxmox-ve/preise|Preise]] beginnen bei ~85€ pro Jahr und CPU-Sockel.
Anzahl der Sockel anzeigen (auch via GUI möglich).
dmidecode -t4 | egrep 'Designation|Status'
Socket Designation: CPU1
Status: Populated, Enabled
Socket Designation: CPU2
Status: Unpopulated
===== Fail-over Konzept =====
Proxmox bildet ein quorum über die laufendene Clustermitglieder, solange die Mehrheit der nodes sich einig sind ist der Cluster Ok (healthy).
Fällt eine Node aus, können die laufenden VMs auf einem anderen Server neu gestartet werden solange ein shared-storage bestand (Ceph, Gluster, ...).
Ohne shared storage bleibt nur
* [[https://pve.proxmox.com/wiki/Storage_Replication|Storage Replication]] (siehe auch https://www.youtube.com/watch?v=Os29FB_xpLM ), Vorraussetzung: der lokale Storage heißt gleich.
* [[https://pve.proxmox.com/wiki/PVE-zsync|PVE-zsync]]
* oder jemand müsste manuell physikalisch die Daten aus dem Server ausbauen und woanders wieder lauffähig machen.
VM aus dem letzen backup wiederherstellen:
* via backup-storage
* aus einem manuellen backup (gesicherte Datei oder zfs-volume ((''zfs list -o name,type,mountpoint'' z.B. local_storage_srv1/vm-100-disk-0)) )
===== Balancing =====
Proxmox bietet von sich aus kein balancing von VMs (vergleichbar zu VMware DRS). Es gibt aber zwei Implementierungen die das erledigen:
* [[https://github.com/PLUTEX/pve_balance|PVE Balance]]
* [[https://github.com/HeinleinSupport/proxmox-tools/blob/master/proxmox_migrate.py|proxmox_migrate.py]]
===== Backup =====
https://pve.proxmox.com/wiki/Backup_and_Restore
https://cyberpersons.com/2016/09/13/backup-transfer-proxmox-vm-another-proxmox-node/
Nach Transfer von VMs auf einen anderen Node sind ggf. iso-Einbindungen anzupassen (:!: Wichtig! sonst funktioniert auch das automatisierte Backup nicht), zusätzlich könnten die network devices anders heißen (vmbr0 -> vmbr1 o.ä.).
===== Automatisierung =====
* Tool: proxmox-deploy
* Proxmox-eigene Tools: pvesh and pvesm
* [[https://pve.proxmox.com/wiki/Proxmox_VE_API|Proxmox VE API]]
* Ansible+Kickseed a Proxmox VM https://gitlab.com/snippets/1548093
* Ansible+cloud-init https://github.com/LordGaav/proxmox-deploy
* Ansible+Kickstart or Preseed: https://gitlab.com/morph027/pve-infra-poc - benutzt das [[https://docs.ansible.com/ansible/latest/modules/proxmox_kvm_module.html|Ansible-Modul: proxmox_kvm]]
==== interessante Befehle ====
* Liste von nodes ''pvesh get /nodes --noborder 1 --noheader 1''
* VMs finden ''pvesh get /cluster/resources -type=vm --noborder 1 --noheader 1 | tr -s ' '''
* laufende VMs anzeigen: ''qm list'' ((eine ID prod Zeile: ''qm list | tr -s ' ' | awk '{$1=$1};1' | cut -d " " -f 1'')), siehe auch: https://wiki.itadmins.net/doku.php?id=virtualization:proxmox:pvefind
* VM-Config anzeigen:''qm config $ID''
* storage auflisten: ''pvesh get /nodes/$NODE/storage/$STORAGENAME/content --noborder 1 --noheader 1 --output-format yaml''
* VMs migrieren: ''qm move_disk $ID $device_name $target_storage'' (Beispiel: ''qm move_disk 100 scsi0 local-zfs'')
===== HA-Konzepte =====
Hochverfügbarkeit ergibt sich bei Proxmox einerseits aus dem Cluster-Quorum (wo läuft welche VM) und dem Speicherbackend.
* Clusterstatus''pvecm status''
* Konfigurationsdatei: ''/etc/pve/corosync.conf''
==== Speicherbackends ====
[[https://pve.proxmox.com/wiki/Storage|Übersicht]]
* lokales LVM (thin)
* lokale ZFS-pools mit Replication (asynchron):
* 1min Datenverlust ((da der ReplikationsJob nur jede Minute läuft)) falls eine Node bzw. das lokale Speichersystem dauerhaft ausfällt)
* [[https://github.com/zfsonlinux/zfs-auto-snapshot|zfsautosnapshot]] ([[https://packages.debian.org/bullseye/zfs-auto-snapshot|debian-package]])
* **Clusterdateisystem** (synchron):
* [[software:ceph storage cluster|ceph]] (syncron, aber erhöhte Latenz)
* **glusterfs** (syncron)
* **drbd** (offiziell nicht unterstützt) https://linbit.com/blog/linstor-setup-proxmox-ve-volumes/
* [[https://www.starwindsoftware.com/starwind-virtual-san-free|StarWind Virtual SAN]] (offiziell nicht unterstützt) [[https://www.starwindsoftware.com/resource-library/starwind-virtual-san-free-vs-paid/|Vergleich free vs. paid]]
* ZFS over iSCSI
* Fibrechannel SAN mit OCFS2 (offiziell nicht unterstützt)
Anmerkung: Werden VMs auf einen anderen Speicher migriert, müssen snapshots vorher gelöscht werden (mindestens beim Wechsel von Blockbasierten auf Dateibasierten Storage).
==== Migrations-interface wählen ====
Datacenter -> Options -> Migration Settings
unverschlüsselte Migration: /etc/pve/datacenter.cfg: type=secure -> type=insecure
==== Cross-Cluster Live-Migration ====
qm remote-migrate ${local_vmid} ${remote_vmid} \
'host=${remote_host_or_ip},apitoken=PVEAPIToken=${token}=${token_secret},fingerprint=${fingerprint}' \
--target-bridge=${bridge} --target-storage ${local_storage}:${remote_storage} --online
${local_vmid} : Die VMID auf dem Quellserver, eine 3- oder 4-stellige Zahl, z. B. 191
${remote_vmid}: Die VMID auf dem Zielserver. Die ID darf natürlich auf dem Zielserver noch nicht belegt sein. z. B. 191
${remote_host_or_ip}: Die IP-Adresse oder der voll qualifizierte Hostname des Zielsystems, z. B. pvetarget.dom.tld
${token}: Ein gültiger Tokenname. z. B. meinusername@pam!meintokenname
${token_secret}: Das zum Token zugehörige Tokenpasswort. Dieses wird nur beim anlegen einmal gezeigt. Ansonsten ist es nicht mehr sichtbar. z. B. : 444a7f17-41a5-4114-1140-f1a44410f714.
${fingerprint}: Der Zertifikats-Fingerprint des Zielservers, wie man diesen auf dem Zielserver mittels ...
pvenode cert info --output-format json | jq -r '.[1]["fingerprint"]'
... anzeigen lassen kann (Wichtig: Paket "jq" vorher installieren) z. B. A9:53:31:55:90:52:54:B4:A4:42:31:53:44:45:35:AB:09:B9:A2:19:CC:C3:54:11:93:94:45:B4:94:BC:9A:41.
${bridge}: Die Bridge, die auf dem Zielhost der Netzwerkschnittstelle zugewiesen werden soll. z. B. vmbr0
${local_storage} / ${remote_storage}: Das lokale und entfernte Storage, in der VM-Daten gespeichert werden. z. B. local für beide Werte.
--online: Der Schalter, damit eine VM im hochgefahrenen Zustand migriert wird, d. h. mit Downtime im Millisekundenbereich.
Quelle: https://debianforum.de/forum/viewtopic.php?t=186538#p1322964
Links:
* https://forum.proxmox.com/threads/framework-for-remote-migration-to-cluster-external-proxmox-ve-hosts.118444/
==== CIFS ====
Samba oder Windows als Speicherserver.
==== ZFS ====
Durch ZFS on Linux ist unter Proxmox die Nutzung von ZFS möglich.
=== Proxmox VE ZFS replication manager (pve-zsync) ===
Durch [[https://pve.proxmox.com/wiki/PVE-zsync|PVE-zsync]] kann via cron-job (Intervall bis runter auf 1min) ZFS-Pools asynchron replizieren. Damit verliert man "nur" die Daten seit dem letzen Sync.
==== Ceph ====
:!: NTP-Dienst muss laufen, clock skew kommt schon mit Standardeinstellungen (Warnung bei 0,05s Unterschied) - entweder die skew höher erlauben oder NTP-intervall erhöhen "server xxx iburst minpoll 4 maxpoll 7")
# -> creating /etc/pve/priv/ceph.client.admin.keyring
/etc/network/interfaces :
auto vmbr0:1
iface vmbr0:1 inet static
address 10.1.2.1/24
/etc/hosts (alle nodes!):
# ceph
10.1.2.1 srv1-ceph.domain.tld srv1-ceph
10.1.2.2 srv2-ceph.domain.tld srv2-ceph
10.1.2.3 srv3-ceph.domain.tld srv3-ceph
* auf jeder Node: ''pveceph install''
* Netzwerk definieren (Beispielnetz: 10.1.2.0/24): ''pveceph init --network 10.1.2.0/24'' (dieser Wert wird für public network + cluster network benutzt!)
* mon/mgr anlegen (mind. 3x):
- über SSH: ''pveceph createmon''
- oder über web auf einem beliebigem Node
Festplatten als OSD hinzufügen (hier sda bis sdh):
for disk in sda sdb sdc sdd sde sdf sdg sdh
do
pveceph createosd /dev/$disk
done
ceph osd crush rule create-replicated replicated_hdd default host hdd
ceph osd crush rule create-replicated replicated_ssd default host ssd
# ceph osd crush rule create-replicated replicated_nvme default host nvme
#ceph osd getcrushmap > crush.map.lng.bin # CRUSH-Map extrahieren
#crushtool -d crush.map.lng.bin -o crush.map.txt
#nano crush.map.txt
ceph osd pool create proxmox_3repl_hdd replicated
ceph osd pool create proxmox_3repl_ssd replicated
ceph osd pool create proxmox_2repl_hdd replicated
ceph osd pool create proxmox_2repl_ssd replicated
ceph osd pool set proxmox_3repl_hdd size 3
ceph osd pool set proxmox_3repl_hdd min_size 2
ceph osd pool set proxmox_3repl_ssd size 3
ceph osd pool set proxmox_3repl_ssd min_size 2
ceph osd pool set proxmox_2repl_hdd size 2
ceph osd pool set proxmox_2repl_hdd min_size 1
ceph osd pool set proxmox_2repl_ssd size 2
ceph osd pool set proxmox_2repl_ssd min_size 1
ceph osd pool set proxmox_3repl_hdd crush_rule replicated_hdd
ceph osd pool set proxmox_2repl_hdd crush_rule replicated_hdd
ceph osd pool set proxmox_3repl_ssd crush_rule replicated_ssd
ceph osd pool set proxmox_2repl_ssd crush_rule replicated_ssd
# ceph osd pool set $POOL_NAME crush_rule replicated_ssd
# ceph osd pool set $POOL_NAME crush_rule replicated_nvme
# RBD zuweisen:
ceph osd pool application enable proxmox_3repl_hdd rbd
ceph osd pool application enable proxmox_2repl_hdd rbd
ceph osd pool application enable proxmox_3repl_ssd rbd
ceph osd pool application enable proxmox_2repl_ssd rbd
==== cephfs entfernen ====
via gui oder:
- MDS entfernen: via GUI oder pveceph mds destroy NAME
- ceph rm fs NAME --yes-i-really-mean-it
==== Crush-Rule für gemixte Setups (SSDs, HDDs) ====
(leider nicht über GUI möglich)
Schema: ''ceph osd crush rule create-replicated ''
**Erklärung**:
* name of the rule, to connect with a pool (seen in GUI & CLI)
* which crush root it should belong to (default ceph root "default")
* at which failure-domain the objects should be distributed (usually host)
* what type of OSD backing store to use (eg. nvme, ssd, hdd)
''ceph osd crush rule create-replicated ssd_only default host ssd
ceph osd crush rule create-replicated hdd_only default host hdd
ceph osd crush rule ls''
replicated_rule -> mixed
ssd_only -> ssd
hdd_only -> hdd
Welche OSDs gehören zur Klasse SSD?
- den kompletten Baum: ''ceph osd tree'' (Spalten CLASS, NAME)
- ''ceph osd crush class ls-osd ssd'' -> zeigt die osd.NUMMERN an
For replicated pools it is the ruleset specified by the osd pool default crush replicated ruleset config variable. -> http://docs.ceph.com/docs/luminous/rados/operations/pools/
anschließend einem Pool zuweisen.
- GUI
- Shell
ceph osd pool set {pool-name} {key} {value}
Beispiel: der pool "cephfs_metadata" bekommt nun die rule "ssd_only":
ceph osd pool set cephfs_metadata crush_rule ssd_only
Ausgabe: "set pool 7 crush_rule to ssd_only"
-> Achtung: Die Daten werden nun ggf. umkopiert!
==== GlusterFS ====
[[software:glusterfs]]
==== 2 Node Cluster ====
Um das Quorum zu erhalten und [[wpde>https://de.wikipedia.org/wiki/Split_Brain_(Informatik)|Split-Brain]] zu vermeiden muss sich eine Mehrheit der Nodes einig sein. Wenn es nur zwei davon gibt und eine nicht mehr verfügbar ist, dann ist das nicht mehr gegeben und /etc/pve wird auf Read-Only gesetzt, es können also keine Änderungen mehr vorgenommen werden.
Falls ein Clusterdateisystem benutzt wird bzw. HA-Regeln existieren: VMs werden abgeschaltet um Datenverlust zu vermeiden!
Befehl auf der Shell: pvecm expected 1
**Dauerhaft**: /etc/pve/cluster.conf
===== Fehlerbehebung =====
==== Konsole geht nicht (timeout) ====
Funktionieren muss:
* pveproxy
* Port 8006 for alle Nodes untereinander erlaubt
* korrekte nginx-config
rpcbind muss nur aktiv sein wenn glusterfs benutzt wird aber nicht für proxmox oder console.
===== Verbesserungsvorschläge / Limitationen =====
* Corosync limitiert die maximale Anzahl der nodes auf irgendwas um die 32 - 64 Nodes (Vorraussetzung geringe Latenz, kein Paketverlust)
* Backup-Job (System)
- manuell starten können (einzelne VMs können jedoch via "Backup now" gesichert werden)
- inkrementelle Jobs möglich machen (Lösung: proxmox backup server)
- run before/run after-Hooks
- freier definierbar Backup-Jobs via GUI (Quelle z.B. ein Verzeichnis)
* Replikation: als Ziel wären auch nicht-cluster-nodes interessant (z.B. ein externer ZFS-Backup-server)
* ZFS storage von der Oberfläche löschen können
- Erweiterung der bulk Aktionen "Bulk config change":
- bridge ändern (MAC bleibt!)
- boot-CD ändern
- autostart-Modus
* ceph
* crush-rules editierbar machen
* storage
- Spalte Dateidatum bei Content-auflistung würde z.B. beim Backup-Restore helfen (ggf. auch nicht nur IDs sondern auch VM-Namen anzeigen)
- Festplatte "sauber" machen (use-case: zfs auf ehemals gebrauchten Festplatten anlegen, zfs-Befehl erkennt das mal ein ext4 drauf lag und verlangt -f/force was die gui aber nicht mitgibt. daher ssh-login und dd notwendig)
* Permission-System anhand der Pfade -> ggf. verbesserungswürdig
* Upload von Dateien über Web >2G nicht möglich (Lösung: scp nehmen)
* die IDs der VM werden linear vergeben, d.h. theoretisch kann es zu race-conditions kommen wenn zwischen API-calls VMs gelöscht und neu erzeugt werden (es gibt keine UUIDS). Name kann mehrfach verwendet werden, nur die ID muss einzigartig sein.
==== Problembehebung ====
=== VM locked ===
Manchmal gibt es Situation wo ein Lock bestehen bleibt weil die auslösende Aktion abgebrochen wurde. Dann ist manuelle Abhilfe notwendig:
qm unlock $ID
====== Proxmox Backup Server ======
PBS kann effizientes Backup mit dedup und sogar während des restores schon die VM laufen zu lassen "[[https://pve.proxmox.com/pve-docs/chapter-vzdump.html#_live_restore|Live-Restore]]".
===== best practise =====
* eingeschränkten Benutzer im pve Realm für das Backup einrichten (Role "Datastore.backup" d.h. reinschreiben aber nichts löschen)
* retention time wird von PBS gesteuert
* alle administrativen Benutzer mit 2FA ausstatten
===== CLI-Restore =====
''proxmox-backup-client list''
# -> $snapshotname raussuchen:
''proxmox-backup-client catalog dump $snapshotname''
''proxmox-backup-client catalog shell $snapshotname $Ordner''