sites: Inventar und Zielbild an echte Knoten (pve44–pve61) angepasst; ADR-0001/0002/0006 ergänzt
ci / test (push) Successful in 25s

Aufbauplan Task 0.4:
- inventory.yaml: pve44/46/48/52/61 und GODE-PC-05/06 (Ada, Windows, cpu_roles: false)
- proxmox.yaml: eine GPU-VM pro Knoten mit allen Karten (D2), local-lvm/tank (D1 B),
  192.168.100.0/24 ohne VLAN, Gast-IPs .220–.239 (ANNAHME bis Task 0.2)
- registry.yaml/prometheus.yml: ops-Labels auf gpu-pve44/46/48, Ada ohne pve_node/vmid
- tofu: dynamische hostpci, Speicher je Gast; Ansible: pve_gpu_hosts/pve_kiosk,
  Replikation auf mehrere Ziele
- Placement: cpu_roles=false schließt Arbeitsplätze/Kiosk von CPU-Rollen aus
- PLAN §1.3/§1.4/§9 und ADR-Nachträge (D1 entschieden, D2/D3 Bestätigung offen)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-13 01:39:49 +02:00
co-authored by Claude Opus 5.5
parent 8cf27b48ce
commit c81e372c49
20 changed files with 343 additions and 190 deletions
+25 -14
View File
@@ -1,29 +1,40 @@
# ANNAHME bis Deployment – Hosts und IPs aus sites/knaster/proxmox.yaml
# Hosts und IPs aus sites/knaster/proxmox.yaml (Aufbauplan Task 0.4). Ansible läuft im ops-LXC (Task 3.1).
# Gast-IPs: ANNAHME bis Task 0.2 (DHCP-Ausschluss .220–.239).
all:
vars:
knaster_site: knaster
children:
pve_hosts:
hosts:
pve-ada: {}
pve1: {}
pve2: {}
pve3: {}
pve4: {}
pve_all:
children:
pve_gpu_hosts:
hosts:
pve44: {ansible_host: 192.168.100.210}
pve46: {ansible_host: 192.168.100.209}
pve48: {ansible_host: 192.168.100.212}
pve52: {ansible_host: 192.168.100.207}
pve_kiosk: # keine VFIO-/NVIDIA-Sperre, iGPU bleibt beim Host (Kiosk)
hosts:
pve61: {ansible_host: 192.168.100.214}
vars:
ansible_user: root
gpu_vms:
hosts:
gpu-main: {ansible_host: 10.20.0.201, driver_generation: modern, knaster_role: gpu-vllm}
gpu-flex: {ansible_host: 10.20.0.202, driver_generation: modern, knaster_role: gpu-vllm}
gpu-embed-1: {ansible_host: 10.20.0.221, driver_generation: legacy, knaster_role: gpu-llamacpp, llamacpp_profile: embed}
gpu-embed-2: {ansible_host: 10.20.0.222, driver_generation: legacy, knaster_role: gpu-llamacpp, llamacpp_profile: embed}
gpu-small: {ansible_host: 10.20.0.231, driver_generation: legacy, knaster_role: gpu-llamacpp, llamacpp_profile: chat}
gpu-pve44: {ansible_host: 192.168.100.224}
gpu-pve46: {ansible_host: 192.168.100.226}
gpu-pve48: {ansible_host: 192.168.100.228}
gpu-pve52: {ansible_host: 192.168.100.232}
vars:
ansible_user: knaster
ansible_become: true
driver_generation: legacy # R580, Maxwell/Pascal
knaster_role: gpu-llamacpp
infra:
hosts:
infra: {ansible_host: 10.20.0.101}
infra: {ansible_host: 192.168.100.221}
vars:
ansible_user: root
ops:
hosts:
ops: {ansible_host: 192.168.100.220}
vars:
ansible_user: root
+4 -3
View File
@@ -1,6 +1,7 @@
# Reihenfolge: Hosts vorbereiten → (tofu apply) → GPU-VMs → Infra
- name: Proxmox-Hosts (IOMMU, VFIO, ZFS-Replikation)
hosts: pve_hosts
# Reihenfolge: GPU-Knoten vorbereiten → (tofu apply) → GPU-VMs → Infra
# pve61 (pve_kiosk) bekommt bewusst keine Host-Rolle: keine VFIO-Bindung, keine NVIDIA-Sperre (Review Focus 5).
- name: Proxmox-GPU-Knoten (IOMMU, VFIO, ZFS-Replikation)
hosts: pve_gpu_hosts
roles: [pve-host]
- name: GPU-VMs (Treiber gepinnt, Container-Toolkit, Docker, Xid-Exporter)
@@ -50,21 +50,28 @@
- name: Hinweis, falls tank fehlt (Pool wird bewusst NICHT automatisch angelegt – Datenverlustgefahr)
ansible.builtin.debug:
msg: "Auf {{ inventory_hostname }} fehlt der ZFS-Pool 'tank'. Anlegen z. B.: zpool create -o ashift=12 tank mirror /dev/disk/by-id/<ssd2> /dev/disk/by-id/<ssd3> && pvesm add zfspool tank -pool tank"
when: tank.rc != 0
msg: >-
Auf {{ inventory_hostname }} fehlt der ZFS-Pool 'tank'. Nach Freigabe (D1) und Prüfung mit
`lsblk -o NAME,SIZE,FSTYPE,LABEL /dev/sdb`: zpool create -o ashift=12 -O compression=lz4 -O atime=off
tank /dev/disk/by-id/<ssd2> && pvesm add zfspool tank --pool tank --content images,rootdir
when:
- tank.rc != 0
- knaster_pve.nodes[inventory_hostname].zfs_tank | default(false)
- name: Bestehende Replikationsjobs lesen
ansible.builtin.command: pvesr list
register: pvesr_jobs
changed_when: false
- name: ZFS-Replikation für Infra-Gäste
# Ein Job pro Ziel: <vmid>-0, <vmid>-1, … (Reihenfolge aus replicate_to)
- name: ZFS-Replikation für HA-Gäste
ansible.builtin.command: >
pvesr create-local-job {{ item.value.vmid }}-0 {{ item.value.replicate_to }}
--schedule '{{ knaster_pve.replication_schedule }}' --comment 'knaster {{ item.key }}'
loop: "{{ knaster_pve.containers | dict2items }}"
pvesr create-local-job {{ item.0.value.vmid }}-{{ idx }} {{ item.1 }}
--schedule '{{ knaster_pve.replication_schedule }}' --comment 'knaster {{ item.0.key }}'
loop: "{{ knaster_pve.containers | dict2items | subelements('value.replicate_to', skip_missing=true) }}"
vars:
idx: "{{ item.0.value.replicate_to.index(item.1) }}"
when:
- item.value.node == inventory_hostname
- item.value.replicate_to is defined
- (item.value.vmid | string) + '-0' not in pvesr_jobs.stdout
- item.0.value.node == inventory_hostname
- ((item.0.value.vmid | string) + '-' + (idx | string)) not in pvesr_jobs.stdout
changed_when: true