Deployment von Knoten¶
Dieses How-to ist veraltet. Es wird bald aktualisiert.
Jeder Cluster erhält einen eigenen Deployment-Host. Dieser Host wird verwendet, um individuelle Images für jeden Knoten zu bauen. Gleichzeitig fungiert der Host als Ansible-Controller, der die Knotenkonfiguration mittels Ansible aktualisieren kann.
Es gibt nur eine zentrale Ansible-Konfiguration für jeden Host. Diese Konfiguration wird während des Build-Prozesses (OpenWrt Imagebuilder) verwendet, um die individuelle Host-Konfiguration in das Image zu integrieren. Sie wird auch verwendet, um aktualisierte Konfigurationen auf einen bereits deployten und laufenden Knoten auszuspielen.
Etwas konkreter: Die Ansible-Roles für OpenWrt können Konfigurationsdateien nicht nur direkt auf ein OpenWrt-System deployen, sondern auch in ein beliebiges Verzeichnis schreiben. Das ist besonders nützlich, wenn man mit dem Imagebuilder eigene Images bauen und die richtige Konfiguration für den jeweiligen Knoten direkt einbinden möchte.
Passen Sie die Release-Version nach Belieben an.
mkdir pplznetdraft
cd pplznetdraft
wget https://downloads.openwrt.org/releases/22.03.0-rc5/targets/x86/64/openwrt-imagebuilder-22.03.0-rc5-x86-64.Linux-x86_64.tar.xz
tar -xvf openwrt-imagebuilder-22.03.0-rc5-x86-64.Linux-x86_64.tar.xz
cd openwrt-imagebuilder-22.03.0-rc5-x86-64.Linux-x86_64
#!/usr/bin/env bash
ansibledir="/pvedisk/ansible_pplznet"
workdir="/pvedisk/pplznetdraft"
imagebuilderdir="openwrt-imagebuilder-22.03.0-rc5-x86-64.Linux-x86_64"
imagepath="bin/targets/x86/64/openwrt-22.03.0-rc5-x86-64-generic-ext4-combined.img.gz"
PACKAGES="python3 bind-host luci-app-ddns ddns-scripts-services ddns-scripts-nsupdate ddns-scripts bind-client tcpdump babeld collectd collectd-mod-cpu collectd-mod-interface collectd-mod-iwinfo collectd-mod-load collectd-mod-memory collectd-mod-network collectd-mod-rrdtool e2fsprogs htop iftop luci luci-app-babeld luci-app-statistics luci-app-vnstat2 luci-app-wireguard mtr nmap-full prometheus-node-exporter-lua vim-fuller vnstat2 vnstati2 wg-installer-client wireguard-tools zlib"
FILES="files/"
oldindex=359
for index in {300..359}; do
# delete old configs
rm -rf ${workdir}/${imagebuilderdir}/files/*
# run ansible to deploy host specific config
cd ${ansibledir}
ansible-playbook buildimage_n${index}.yml
# build image
cd ${workdir}/${imagebuilderdir}
# if you want to build without packages:
#make image FILES="${FILES}"
make image PACKAGES="${PACKAGES}" FILES="${FILES}"
# mv and extract
cp ${imagepath} ../n${index}.img.gz
gunzip -f ../n${index}.img.gz
oldindex=${index}
done
Dieses Script führt Ansible aus, um die Konfigurationsdateien lokal zu deployen, damit sie in das jeweilige Image eingebaut werden.
Im Ansible-Pfad habe ich diese 60 Hosts konfiguriert. Für jeden Host gibt es ein Playbook, wie in diesem Beispiel für n300:
- hosts: n300.demo.junicast.de
become: true
gather_facts: false
connection: local
ignore_errors: yes
vars:
ansible_host: 127.0.0.1
skip_handlers: true
openwrt_deployroot: "/pvedisk/pplznetdraft/openwrt-imagebuilder-22.03.0-rc5-x86-64.Linux-x86_64/files/"
openwrt_system_deployroot: "{{ openwrt_deployroot }}"
openwrt_dropbear_deployroot: "{{ openwrt_deployroot }}"
openwrt_network_deployroot: "{{ openwrt_deployroot }}"
openwrt_firewall_deployroot: "{{ openwrt_deployroot }}"
openwrt_babeld_deployroot: "{{ openwrt_deployroot }}"
openwrt_dropbear_runimagebuilder: true
openwrt_network_runimagebuilder: true
openwrt_firewall_runimagebuilder: true
openwrt_babeld_runimagebuilder: true
roles:
- imp1sh.ansible_pplznet.pplznet_node_deploy
- imp1sh.ansible_openwrt.ansible_openwrtsystem
- imp1sh.ansible_openwrt.ansible_openwrtdropbear
- imp1sh.ansible_openwrt.ansible_openwrtnetwork
- imp1sh.ansible_openwrt.ansible_openwrtfirewall
- imp1sh.ansible_openwrt.ansible_openwrtbabeld
Am Ende entstehen einzelne img-Dateien, die ich mit folgendem Script in Proxmox importiere.
#!/usr/bin/python3
# difference to create_virtenv2 is that all interfaces on vmbbr1
import os
vlans = [
{'guestid': 300,
'vlanid': 1300,
'nic': 'net0',
'bridge': 'vmbr1'},
{'guestid': 300,
'vlanid': 71,
'nic': 'net1',
'bridge': 'vmbr1'},
{'guestid': 300,
'vlanid': 2300,
'nic': 'net2',
'bridge': 'vmbr1'
{'guestid': 300,
'vlanid': 3000,
'nic': 'net3',
'bridge': 'vmbr1'},
{'guestid': 300,
'vlanid': 2999,
'nic': 'net4',
'bridge': 'vmbr1'},
[...] define all your vlans
]
for index in range(300, 360):
# print("qm create", index, "--agent 0 --autostart 0 --balloon 0 --cores 1 --cpu host --memory 128 --name node" + str(index))
runcommandqm = "qm create " + str(index) + " --agent 0 --autostart 0 --balloon 0 --cores 1 --cpu host --memory 128 --name node" + str(index)
print(runcommandqm)
os.system(runcommandqm)
runcommandimportdisk = "qm importdisk " + str(index) + " /pvedisk/pplznetdraft/n" + str(index) + ".img pvedisk"
# this for zfs
# runcommandactivatedisk = "qm set " + str(index) + " --scsihw virtio-scsi-pci --scsi0 pvedisk:vm-" + str(index) + "-disk-0"
# this for raw eg btrfs
runcommandactivatedisk = "qm set " + str(index) + " --scsihw virtio-scsi-pci --scsi0 pvedisk:" + str(index) + "/vm-" + str(index) + "-disk-0.raw"
print(runcommandimportdisk)
os.system(runcommandimportdisk)
print(runcommandactivatedisk)
os.system(runcommandactivatedisk)
#runcommandvlan = "qm set " + str(vlans[0]['guestid']) + " --" + str(vlans[0]['nic']) + " virtio,bridge=" + str(vlans[0]['bridge']) + ",tag=" + str(vlans[0]['vlanid'])
#print(runcommandvlan)
#os.system(runcommandvlan)
for vlan in vlans:
runcommandvlan = "qm set " + str(vlan['guestid']) + " --" + str(vlan['nic']) + " virtio,bridge=" + str(vlan['bridge']) + ",tag=" + str(vlan['vlanid'])
print(runcommandvlan)
os.system(runcommandvlan)
for index in range(300, 360):
runcommandstart ="qm start " + str(index)
print(runcommandstart)
os.system(runcommandstart)