Initial commit: Turbo Mothership bare metal management cluster
- k0s bootstrap with Cilium and OpenEBS - ArgoCD apps for infra, CAPI, Tinkerbell, and Netris - Ansible playbooks for virtual baremetal lab and Netris switches - CAPI provider manifests for k0smotron and Tinkerbell
This commit is contained in:
120
ansible/virtual-bm/br-mgmt-nat.yml
Normal file
120
ansible/virtual-bm/br-mgmt-nat.yml
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
- name: Configure br-mgmt bridge for libvirt and Tinkerbell
|
||||
hosts: local
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
br_mgmt_name: br-mgmt
|
||||
br_mgmt_ip: 172.16.81.254
|
||||
br_mgmt_cidr: 24
|
||||
br_mgmt_netmask: 255.255.255.0
|
||||
|
||||
tasks:
|
||||
- name: Ensure bridge-utils is installed
|
||||
ansible.builtin.apt:
|
||||
name: bridge-utils
|
||||
state: present
|
||||
update_cache: false
|
||||
|
||||
- name: Create bridge interface configuration file
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/network/interfaces.d/br-mgmt
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
content: |
|
||||
# Management bridge for libvirt VMs and Tinkerbell
|
||||
# This bridge provides the 172.16.81.0/24 network for bare metal provisioning
|
||||
|
||||
auto {{ br_mgmt_name }}
|
||||
iface {{ br_mgmt_name }} inet static
|
||||
address {{ br_mgmt_ip }}
|
||||
netmask {{ br_mgmt_netmask }}
|
||||
bridge_ports none
|
||||
bridge_stp off
|
||||
bridge_fd 0
|
||||
bridge_maxwait 0
|
||||
|
||||
- name: Check if bridge already exists
|
||||
ansible.builtin.command: ip link show {{ br_mgmt_name }}
|
||||
register: bridge_exists
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Create bridge interface
|
||||
ansible.builtin.command: ip link add name {{ br_mgmt_name }} type bridge
|
||||
when: bridge_exists.rc != 0
|
||||
|
||||
- name: Set bridge interface up
|
||||
ansible.builtin.command: ip link set {{ br_mgmt_name }} up
|
||||
when: bridge_exists.rc != 0
|
||||
|
||||
- name: Check current IP on bridge
|
||||
ansible.builtin.shell: ip addr show {{ br_mgmt_name }} | grep -q '{{ br_mgmt_ip }}'
|
||||
register: ip_configured
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Assign IP address to bridge
|
||||
ansible.builtin.command: ip addr add {{ br_mgmt_ip }}/{{ br_mgmt_cidr }} dev {{ br_mgmt_name }}
|
||||
when: ip_configured.rc != 0
|
||||
|
||||
- name: Enable IP forwarding
|
||||
ansible.posix.sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: "1"
|
||||
sysctl_set: true
|
||||
state: present
|
||||
reload: true
|
||||
|
||||
- name: Install iptables-persistent
|
||||
ansible.builtin.apt:
|
||||
name: iptables-persistent
|
||||
state: present
|
||||
update_cache: false
|
||||
environment:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: Configure NAT masquerade for br-mgmt network
|
||||
ansible.builtin.iptables:
|
||||
table: nat
|
||||
chain: POSTROUTING
|
||||
source: 172.16.81.0/24
|
||||
out_interface: enp41s0
|
||||
jump: MASQUERADE
|
||||
comment: "NAT for br-mgmt network"
|
||||
|
||||
- name: Allow forwarding from br-mgmt to external
|
||||
ansible.builtin.iptables:
|
||||
chain: FORWARD
|
||||
in_interface: "{{ br_mgmt_name }}"
|
||||
out_interface: enp41s0
|
||||
jump: ACCEPT
|
||||
comment: "Forward br-mgmt to internet"
|
||||
|
||||
- name: Allow forwarding return traffic to br-mgmt
|
||||
ansible.builtin.iptables:
|
||||
chain: FORWARD
|
||||
in_interface: enp41s0
|
||||
out_interface: "{{ br_mgmt_name }}"
|
||||
ctstate: ESTABLISHED,RELATED
|
||||
jump: ACCEPT
|
||||
comment: "Return traffic to br-mgmt"
|
||||
|
||||
- name: Save iptables rules
|
||||
ansible.builtin.shell: iptables-save > /etc/iptables/rules.v4
|
||||
|
||||
- name: Display bridge status
|
||||
ansible.builtin.shell: |
|
||||
echo "=== Bridge Status ==="
|
||||
ip addr show {{ br_mgmt_name }}
|
||||
echo ""
|
||||
echo "=== Bridge Details ==="
|
||||
brctl show {{ br_mgmt_name }}
|
||||
register: bridge_status
|
||||
changed_when: false
|
||||
|
||||
- name: Show bridge status
|
||||
ansible.builtin.debug:
|
||||
var: bridge_status.stdout_lines
|
||||
159
ansible/virtual-bm/create-vms.yml
Normal file
159
ansible/virtual-bm/create-vms.yml
Normal file
@@ -0,0 +1,159 @@
|
||||
---
|
||||
- name: Create virtual baremetal VMs with VirtualBMC
|
||||
hosts: local
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
vbmc_user: admin
|
||||
vbmc_password: password
|
||||
bridge_name: br-mgmt
|
||||
vm_vcpus: 6
|
||||
vm_ram: 6144
|
||||
vm_disk_size: 60
|
||||
disk_path: /var/lib/libvirt/images
|
||||
|
||||
vms:
|
||||
- name: vm1
|
||||
mac: "52:54:00:12:34:01"
|
||||
vbmc_port: 6231
|
||||
- name: vm2
|
||||
mac: "52:54:00:12:34:02"
|
||||
vbmc_port: 6232
|
||||
- name: vm3
|
||||
mac: "52:54:00:12:34:03"
|
||||
vbmc_port: 6233
|
||||
|
||||
tasks:
|
||||
- name: Install required packages
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- python3-pip
|
||||
- ovmf
|
||||
state: present
|
||||
update_cache: false
|
||||
|
||||
- name: Install virtualbmc
|
||||
ansible.builtin.pip:
|
||||
name: virtualbmc
|
||||
state: present
|
||||
break_system_packages: true
|
||||
|
||||
- name: Ensure vbmcd service file exists
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/system/vbmcd.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Virtual BMC daemon
|
||||
After=network.target libvirtd.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/vbmcd --foreground
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
- name: Enable and start vbmcd service
|
||||
ansible.builtin.systemd:
|
||||
name: vbmcd
|
||||
daemon_reload: true
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
- name: Wait for vbmcd to be ready
|
||||
ansible.builtin.pause:
|
||||
seconds: 3
|
||||
|
||||
- name: Check if VMs already exist
|
||||
ansible.builtin.command: virsh dominfo {{ item.name }}
|
||||
loop: "{{ vms }}"
|
||||
register: vm_exists
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Create VMs with virt-install
|
||||
ansible.builtin.command: >
|
||||
virt-install
|
||||
--name "{{ item.item.name }}"
|
||||
--vcpus "{{ vm_vcpus }}"
|
||||
--ram "{{ vm_ram }}"
|
||||
--os-variant "debian12"
|
||||
--connect "qemu:///system"
|
||||
--disk "path={{ disk_path }}/{{ item.item.name }}-disk.img,bus=virtio,size={{ vm_disk_size }},sparse=yes"
|
||||
--disk "device=cdrom,bus=sata"
|
||||
--network "bridge:{{ bridge_name }},mac={{ item.item.mac }}"
|
||||
--console "pty,target.type=virtio"
|
||||
--serial "pty"
|
||||
--graphics "vnc,listen=0.0.0.0"
|
||||
--import
|
||||
--noautoconsole
|
||||
--noreboot
|
||||
--boot "uefi,firmware.feature0.name=enrolled-keys,firmware.feature0.enabled=no,firmware.feature1.name=secure-boot,firmware.feature1.enabled=yes,bootmenu.enable=on,network,hd"
|
||||
loop: "{{ vm_exists.results }}"
|
||||
when: item.rc != 0
|
||||
|
||||
- name: Check existing VBMC entries
|
||||
ansible.builtin.command: vbmc list
|
||||
register: vbmc_list
|
||||
changed_when: false
|
||||
|
||||
- name: Add VMs to VirtualBMC
|
||||
ansible.builtin.command: >
|
||||
vbmc add {{ item.name }}
|
||||
--port {{ item.vbmc_port }}
|
||||
--username {{ vbmc_user }}
|
||||
--password {{ vbmc_password }}
|
||||
--address 0.0.0.0
|
||||
loop: "{{ vms }}"
|
||||
when: item.name not in vbmc_list.stdout
|
||||
|
||||
- name: Start VBMC for each VM
|
||||
ansible.builtin.command: vbmc start {{ item.name }}
|
||||
loop: "{{ vms }}"
|
||||
register: vbmc_start
|
||||
changed_when: "'started' in vbmc_start.stdout or vbmc_start.rc == 0"
|
||||
failed_when: false
|
||||
|
||||
- name: Get VBMC status
|
||||
ansible.builtin.command: vbmc list
|
||||
register: vbmc_status
|
||||
changed_when: false
|
||||
|
||||
- name: Display VBMC status
|
||||
ansible.builtin.debug:
|
||||
var: vbmc_status.stdout_lines
|
||||
|
||||
- name: Get VM list
|
||||
ansible.builtin.command: virsh list --all
|
||||
register: vm_list
|
||||
changed_when: false
|
||||
|
||||
- name: Display VM list
|
||||
ansible.builtin.debug:
|
||||
var: vm_list.stdout_lines
|
||||
|
||||
- name: Display summary
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
Virtual Baremetal VMs created!
|
||||
|
||||
| VM | MAC Address | VBMC Port | VBMC Address |
|
||||
|-----|-------------------|-----------|------------------|
|
||||
| vm1 | 52:54:00:12:34:01 | 6231 | 172.16.81.254 |
|
||||
| vm2 | 52:54:00:12:34:02 | 6232 | 172.16.81.254 |
|
||||
| vm3 | 52:54:00:12:34:03 | 6233 | 172.16.81.254 |
|
||||
|
||||
Test IPMI with:
|
||||
ipmitool -I lanplus -U admin -P password -H 172.16.81.254 -p 6231 power status
|
||||
|
||||
Start a VM:
|
||||
ipmitool -I lanplus -U admin -P password -H 172.16.81.254 -p 6231 power on
|
||||
|
||||
Set PXE boot:
|
||||
ipmitool -I lanplus -U admin -P password -H 172.16.81.254 -p 6231 chassis bootdev pxe
|
||||
52
ansible/virtual-bm/destroy-vms.yml
Normal file
52
ansible/virtual-bm/destroy-vms.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
- name: Destroy virtual baremetal VMs and VirtualBMC
|
||||
hosts: local
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
disk_path: /var/lib/libvirt/images
|
||||
vms:
|
||||
- name: vm1
|
||||
- name: vm2
|
||||
- name: vm3
|
||||
|
||||
tasks:
|
||||
- name: Stop VBMC for each VM
|
||||
ansible.builtin.command: vbmc stop {{ item.name }}
|
||||
loop: "{{ vms }}"
|
||||
failed_when: false
|
||||
changed_when: true
|
||||
|
||||
- name: Delete VBMC entries
|
||||
ansible.builtin.command: vbmc delete {{ item.name }}
|
||||
loop: "{{ vms }}"
|
||||
failed_when: false
|
||||
changed_when: true
|
||||
|
||||
- name: Destroy VMs
|
||||
ansible.builtin.command: virsh destroy {{ item.name }}
|
||||
loop: "{{ vms }}"
|
||||
failed_when: false
|
||||
changed_when: true
|
||||
|
||||
- name: Undefine VMs with NVRAM
|
||||
ansible.builtin.command: virsh undefine {{ item.name }} --nvram
|
||||
loop: "{{ vms }}"
|
||||
failed_when: false
|
||||
changed_when: true
|
||||
|
||||
- name: Remove VM disk images
|
||||
ansible.builtin.file:
|
||||
path: "{{ disk_path }}/{{ item.name }}-disk.img"
|
||||
state: absent
|
||||
loop: "{{ vms }}"
|
||||
|
||||
- name: Get remaining VM list
|
||||
ansible.builtin.command: virsh list --all
|
||||
register: vm_list
|
||||
changed_when: false
|
||||
|
||||
- name: Display VM list
|
||||
ansible.builtin.debug:
|
||||
var: vm_list.stdout_lines
|
||||
4
ansible/virtual-bm/inventory.yml
Normal file
4
ansible/virtual-bm/inventory.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
all:
|
||||
hosts:
|
||||
local:
|
||||
ansible_connection: local
|
||||
Reference in New Issue
Block a user