From 698e67d8c04ffb8adebe692078f75fc4ace7dab7 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Tue, 5 Aug 2025 13:52:33 +0100 Subject: [PATCH] added k3s install --- ansible/install_k3s_3node.yaml | 112 +++++++++++++++++++++++++++++++ scripts/configure_vagrant_k3s.sh | 51 +++++++------- vagrant/dev/ubuntu/Vagrantfile | 35 ++-------- 3 files changed, 142 insertions(+), 56 deletions(-) create mode 100644 ansible/install_k3s_3node.yaml diff --git a/ansible/install_k3s_3node.yaml b/ansible/install_k3s_3node.yaml new file mode 100644 index 0000000..e826648 --- /dev/null +++ b/ansible/install_k3s_3node.yaml @@ -0,0 +1,112 @@ +--- +- name: Install k3s on 3-node cluster + hosts: vm1,vm2,vm3 + become: true + become_user: root + serial: 1 # Ensure tasks are executed one host at a time + + tasks: + - name: Check if k3s is already installed + ansible.builtin.stat: + path: /usr/local/bin/k3s + register: k3s_binary + + - name: Check if k3s token file exists + ansible.builtin.stat: + path: /opt/k3s-token + register: k3s_token_file + when: inventory_hostname == 'vm1' + + - name: Generate and save k3s token if not present (first node) + ansible.builtin.copy: + dest: /opt/k3s-token + content: "{{ lookup('pipe', 'head -c 16 /dev/urandom | sha256sum | cut -d\" \" -f1') }}" + owner: root + group: root + mode: '0600' + force: false + register: generated_k3s_token + when: inventory_hostname == 'vm1' and not k3s_token_file.stat.exists + + - name: Download k3s install script + ansible.builtin.get_url: + url: https://get.k3s.io + dest: /tmp/k3s_install.sh + mode: '0755' + when: not k3s_binary.stat.exists + + - name: Ensure .kube directory exists + ansible.builtin.file: + path: /home/user/.kube + state: directory + mode: '0755' + when: inventory_hostname == 'vm1' and not k3s_binary.stat.exists + + - name: Install k3s on first node + ansible.builtin.shell: | + set -o pipefail + # --write-kubeconfig-mode 644 + K3S_TOKEN=$(cat /opt/k3s-token) /bin/bash /tmp/k3s_install.sh server --cluster-init --disable traefik --disable servicelb --tls-san 192.168.56.80 --node-name vm1 --node-ip 192.168.56.80 + if [ $? -eq 0 ]; then + mkdir -p /home/vagrant/.kube && cp /etc/rancher/k3s/k3s.yaml /home/vagrant/.kube/config && chown vagrant:vagrant /home/vagrant/.kube/config + fi + args: + executable: /bin/bash + creates: /usr/local/bin/k3s + when: inventory_hostname == 'vm1' and not k3s_binary.stat.exists + + - name: Read k3s token from master node (for subsequent nodes) + ansible.builtin.command: cat /opt/k3s-token + register: k3s_token_content + delegate_to: vm1 + when: inventory_hostname != 'vm1' and not k3s_binary.stat.exists + changed_when: false + + - name: Wait for k3s API server to be ready on master node + ansible.builtin.wait_for: + host: 192.168.56.80 + port: 6443 + timeout: 60 + delegate_to: "{{ inventory_hostname }}" + when: inventory_hostname != 'vm1' and not k3s_binary.stat.exists + + - name: Install k3s on subsequent nodes + ansible.builtin.shell: | + set -o pipefail + {% if inventory_hostname == 'vm2' %} + NODE_IP="192.168.56.81" + {% elif inventory_hostname == 'vm3' %} + NODE_IP="192.168.56.82" + {% else %} + NODE_IP="192.168.56.80" + {% endif %} + K3S_URL=https://192.168.56.80:6443 \ + K3S_TOKEN={{ k3s_token_content.stdout }} \ + INSTALL_K3S_EXEC="server --disable traefik --disable servicelb --node-name={{ inventory_hostname }} --node-ip ${NODE_IP}" \ + /bin/bash /tmp/k3s_install.sh 2>&1 + exit_code=$? + if [ $exit_code -ne 0 ]; then + echo "K3S INSTALL FAILED - Service Status:" + systemctl status k3s.service --no-pager -l | head -20 + echo "Recent logs:" + journalctl -u k3s.service --no-pager -l | tail -10 + exit $exit_code + fi + args: + executable: /bin/bash + creates: /usr/local/bin/k3s + register: k3s_install_result + failed_when: false + when: inventory_hostname != 'vm1' and not k3s_binary.stat.exists + + - name: Show k3s failure details + ansible.builtin.debug: + msg: "{{ k3s_install_result.stdout_lines[-30:] }}" + when: inventory_hostname != 'vm1' and not k3s_binary.stat.exists and k3s_install_result.rc != 0 + + - name: Fail if k3s installation failed + ansible.builtin.fail: + msg: "K3S installation failed on {{ inventory_hostname }}" + when: inventory_hostname != 'vm1' and not k3s_binary.stat.exists and k3s_install_result.rc != 0 + + diff --git a/scripts/configure_vagrant_k3s.sh b/scripts/configure_vagrant_k3s.sh index 3e04038..92ce1ca 100755 --- a/scripts/configure_vagrant_k3s.sh +++ b/scripts/configure_vagrant_k3s.sh @@ -70,18 +70,17 @@ echo "Network information gathered successfully." # get vagrant ports echo "Gathering Vagrant port information..." -# vagrant ssh-config | grep Port | while read -r line; do -# echo "Processing line: $line" - -# # Processing line: Port 2222 -# # Processing line: Port 2200 -# # Processing line: Port 2201 -# port=$(echo "$line" | awk '{print $2}') -# echo "Extracted port: $port" -# vagrant_ports+=("$port") -# done +while read -r line; do + echo "Processing line: $line" + + # Extract the port number + port=$(echo "$line" | awk '{print $2}') + echo "Extracted port: $port" + vagrant_ports+=("$port") +done < <(vagrant ssh-config | grep Port) + while read -r line; do @@ -108,21 +107,6 @@ for port in "${vagrant_ports[@]}"; do echo "Port: $port" done -# create an ansible inventory file -# [all] -# vm1 ansible_host= ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm1/virtualbox/private_key -# vm2 ansible_host= ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm2/virtualbox/private_key -# vm3 ansible_host= ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm3/virtualbox/private_key - -# echo "Creating Ansible inventory file..." -# inventory_file="$SCRIPT_DIR/ansible_inventory.ini" -# echo "[all]" > "$inventory_file" -# i=0 -# for vm in $running_vms; do -# port="${vagrant_ports[$i]}" -# echo "$vm ansible_host=127.0.0.1 ansible_port=$port ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/$vm/virtualbox/private_key" >> "$inventory_file" -# ((i++)) -# done echo "Creating Ansible inventory file..." inventory_file="$SCRIPT_DIR/ansible_inventory.ini" echo "[all]" > "$inventory_file" @@ -134,9 +118,6 @@ for vm in $running_vms; do done echo "" >> "$inventory_file" -# echo "[children]" >> "$inventory_file" -# echo "vm_group" >> "$inventory_file" -# echo "" >> "$inventory_file" echo "[vms]" >> "$inventory_file" for vm in $running_vms; do echo $vm >> "$inventory_file" @@ -163,4 +144,18 @@ if [ $? -ne 0 ]; then fi ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook ../../../ansible/install_keepalived.yaml --inventory-file ../../../scripts/ansible_inventory.ini | cat +# exit if error from playbook +if [ $? -ne 0 ]; then + echo "Ansible playbook failed. Please check your Vagrant VMs and network configuration." + exit 1 +fi +echo "Keepalived installation completed successfully." + +ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook ../../../ansible/install_k3s_3node.yaml --inventory-file ../../../scripts/ansible_inventory.ini | cat + +if [ $? -ne 0 ]; then + echo "Ansible playbook failed. Please check your Vagrant VMs and network configuration." + exit 1 +fi +echo "K3s installation completed successfully." \ No newline at end of file diff --git a/vagrant/dev/ubuntu/Vagrantfile b/vagrant/dev/ubuntu/Vagrantfile index 6e33efc..d2e882c 100644 --- a/vagrant/dev/ubuntu/Vagrantfile +++ b/vagrant/dev/ubuntu/Vagrantfile @@ -10,33 +10,12 @@ Vagrant.configure("2") do |config| config.vm.define "vm1" do |vm1| vm1.vm.box = "ubuntu/jammy64" - # run ip link to list network interfaces on linux - # run ipconfig to list network interfaces on Windows - # Example output: - # Ethernet adapter vEthernet (WSL): - # Connection-specific DNS Suffix . : - # IPv6 Address. . . . . . . . . . . : fe80::xxxx:xxxx:xxxx:xxxx%xx - # IPv4 Address. . . . . . . . . . . : 192.168.x.x - # Subnet Mask . . . . . . . . . . . : - # on macOS, run ifconfig to list network interfaces - # Example output: - # en0: flags=8863 mtu 1500 - # options=400 - # ether xx:xx:xx:xx:xx:xx - # inet6 fe80::xxxx:xxxx:xxxx:xxxx%en0 prefixlen 64 scopeid 0x4 - # inet 192.168.x.x netmask 0xffffff00 broadcast 192.168.x.255 + # Fixed private network IP + vm1.vm.network "private_network", ip: "192.168.56.80" - # This configuration sets up a private network for inter-VM communication - # and a public network for external access. - # The private network uses DHCP to assign IP addresses automatically. - # Private network for inter-VM communication using DHCP - - # Uncomment the following line to use a specific network interface for the public network - # and replace "wlp0s20f3" with your actual network interface name. + # Public network for external access vm1.vm.network "public_network", bridge: "wlp0s20f3" - vm1.vm.network "private_network", type: "dhcp" - vm1.vm.provider "virtualbox" do |vb| vb.memory = "2048" # 2GB memory vb.cpus = 2 @@ -53,8 +32,8 @@ Vagrant.configure("2") do |config| config.vm.define "vm2" do |vm2| vm2.vm.box = "ubuntu/jammy64" - # Private network for inter-VM communication using DHCP - vm2.vm.network "private_network", type: "dhcp" + # Fixed private network IP + vm2.vm.network "private_network", ip: "192.168.56.81" # Public network for external access vm2.vm.network "public_network", bridge: "wlp0s20f3" @@ -75,8 +54,8 @@ Vagrant.configure("2") do |config| config.vm.define "vm3" do |vm3| vm3.vm.box = "ubuntu/jammy64" - # Private network for inter-VM communication using DHCP - vm3.vm.network "private_network", type: "dhcp" + # Fixed private network IP + vm3.vm.network "private_network", ip: "192.168.56.82" # Public network for external access vm3.vm.network "public_network", bridge: "wlp0s20f3"