commit 7f4ac7485b9e1014d32babb09a01120f672e30a7 Author: BENEDEK László Date: Sat Nov 23 22:46:13 2024 +0100 init diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..c4a0280 --- /dev/null +++ b/Readme.md @@ -0,0 +1,28 @@ +# K3S cluster deployment using Ansible +Setup a K3S cluster on Debian servers. + +## How to use +First, edit the inventory file and set the k3s token in *`group_vars/all.yml`*. + +Then: +```sh +# allow ansible to use the ssh key +ssh-agent $SHELL +ssh-add ~/.ssh/id_rsa + +# setup nodes +ansible-playbook -i inventory -u root node.yml + +# create primary master +ansible-playbook -i inventory -u root master-primary.yml + +# create more masters +ansible-playbook -i inventory -u root master-secondary.yml + +# create workers +ansible-playbook -i inventory -u root workers.yml +``` + +## Features +- static IP using systemd-networkd (using the last IP of the server before running the playbook) +- multiple masters \ No newline at end of file diff --git a/group_vars/all.yml b/group_vars/all.yml new file mode 100644 index 0000000..52e52e2 --- /dev/null +++ b/group_vars/all.yml @@ -0,0 +1 @@ +K3S_TOKEN: aicaaSi8Air8ohph \ No newline at end of file diff --git a/inventory b/inventory new file mode 100644 index 0000000..e2c90b5 --- /dev/null +++ b/inventory @@ -0,0 +1,22 @@ +[nodes] +192.168.50.1 +192.168.50.2 +192.168.50.3 +# 192.168.50.11 +# 192.168.50.12 +# 192.168.50.13 + +[master-primary] +192.168.50.1 + +# do one at a time +# the k3s service restarts +# on the primary when a node joins +[master-secondary] +192.168.50.2 +192.168.50.3 + +[workers] +# 192.168.50.11 +# 192.168.50.12 +# 192.168.50.13 diff --git a/master-primary.yml b/master-primary.yml new file mode 100644 index 0000000..ba398de --- /dev/null +++ b/master-primary.yml @@ -0,0 +1,6 @@ +- name: Cluster master-primary + hosts: master-primary + become: true + gather_facts: true + roles: + - master-primary diff --git a/master-secondary.yml b/master-secondary.yml new file mode 100644 index 0000000..355224e --- /dev/null +++ b/master-secondary.yml @@ -0,0 +1,6 @@ +- name: Cluster master-secondry + hosts: master-secondary + become: true + gather_facts: true + roles: + - master-secondary diff --git a/node.yml b/node.yml new file mode 100644 index 0000000..ba9d560 --- /dev/null +++ b/node.yml @@ -0,0 +1,6 @@ +- name: Cluster node setup + hosts: nodes + become: true + gather_facts: true + roles: + - node diff --git a/roles/master-primary/files/k3s-primary-master.sh b/roles/master-primary/files/k3s-primary-master.sh new file mode 100644 index 0000000..1693259 --- /dev/null +++ b/roles/master-primary/files/k3s-primary-master.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +export K3S_TOKEN="$1" + +curl -sfL https://get.k3s.io | sh -s - server --cluster-init \ No newline at end of file diff --git a/roles/master-primary/meta/meta.yml b/roles/master-primary/meta/meta.yml new file mode 100644 index 0000000..28d4ef1 --- /dev/null +++ b/roles/master-primary/meta/meta.yml @@ -0,0 +1,2 @@ +dependencies: + - name: node diff --git a/roles/master-primary/tasks/main.yml b/roles/master-primary/tasks/main.yml new file mode 100644 index 0000000..c2b2356 --- /dev/null +++ b/roles/master-primary/tasks/main.yml @@ -0,0 +1,2 @@ +- name: Install k3s as primary master + ansible.builtin.script: k3s-primary-master.sh {{ K3S_TOKEN }} diff --git a/roles/master-secondary/files/k3s-secondary-master.sh b/roles/master-secondary/files/k3s-secondary-master.sh new file mode 100644 index 0000000..af83e25 --- /dev/null +++ b/roles/master-secondary/files/k3s-secondary-master.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +export K3S_TOKEN="$1" + +curl -sfL https://get.k3s.io | sh -s - server --cluster-init --server "https://${2}:6443" \ No newline at end of file diff --git a/roles/master-secondary/meta/meta.yml b/roles/master-secondary/meta/meta.yml new file mode 100644 index 0000000..28d4ef1 --- /dev/null +++ b/roles/master-secondary/meta/meta.yml @@ -0,0 +1,2 @@ +dependencies: + - name: node diff --git a/roles/master-secondary/tasks/main.yml b/roles/master-secondary/tasks/main.yml new file mode 100644 index 0000000..c16b408 --- /dev/null +++ b/roles/master-secondary/tasks/main.yml @@ -0,0 +1,2 @@ +- name: Install k3s as secondary master + ansible.builtin.script: k3s-secondary-master.sh {{ K3S_TOKEN }} {{ groups['master-primary'][0] }} diff --git a/roles/node/defaults/main.yml b/roles/node/defaults/main.yml new file mode 100644 index 0000000..5847047 --- /dev/null +++ b/roles/node/defaults/main.yml @@ -0,0 +1,18 @@ +packages: + - nfs-common + - curl + - systemd-resolved # needs to be the last one + # breaks dns resolution until + # systemd-networkd is configured + +# hostsnames: +# - ip: x.x.x.x +# name: example +# ... +hostnames: [] + +interface_name: lan0 +gateway: "192.168.50.254" +dns_servers: + - "192.168.11.1" + - "1.1.1.1" diff --git a/roles/node/handlers/main.yml b/roles/node/handlers/main.yml new file mode 100644 index 0000000..c0c6030 --- /dev/null +++ b/roles/node/handlers/main.yml @@ -0,0 +1,12 @@ +- name: Update initramfs + listen: + - update initramfs + - update initrd + ansible.builtin.command: + cmd: > + update-initramfs -k all -u + +- name: Warn user to reboot + ansible.builtin.set_fact: + user_notify: Reboot the machine to use the new name for primary interface! + when: systemd_networkd_ifname is changed diff --git a/roles/node/tasks/hostnames.yml b/roles/node/tasks/hostnames.yml new file mode 100644 index 0000000..7b2f6ff --- /dev/null +++ b/roles/node/tasks/hostnames.yml @@ -0,0 +1,11 @@ +- name: Set hostname + ansible.builtin.template: + src: etc-hostname.j2 + dest: /etc/hostname + mode: "0644" + +- name: Set hosts + ansible.builtin.template: + src: etc-hosts.j2 + dest: /etc/hosts + mode: "0644" diff --git a/roles/node/tasks/main.yml b/roles/node/tasks/main.yml new file mode 100644 index 0000000..8f3bd4f --- /dev/null +++ b/roles/node/tasks/main.yml @@ -0,0 +1,15 @@ +- name: Update system + ansible.builtin.include_tasks: + file: update.yml + +- name: Install packages + ansible.builtin.include_tasks: + file: packages.yml + +- name: Set hostname + ansible.builtin.include_tasks: + file: hostnames.yml + +- name: Configure network + ansible.builtin.include_tasks: + file: network.yml diff --git a/roles/node/tasks/network.yml b/roles/node/tasks/network.yml new file mode 100644 index 0000000..e9c69d1 --- /dev/null +++ b/roles/node/tasks/network.yml @@ -0,0 +1,25 @@ +- name: Configure default interface name + ansible.builtin.template: + src: etc-systemd-network-10-lan0.link.j2 + dest: /etc/systemd/network/10-lan0.link + mode: "0644" + register: systemd_networkd_ifname + +- name: Configure network for default interface + ansible.builtin.template: + src: etc-systemd-network-20-lan0.network.j2 + dest: /etc/systemd/network/20-lan0.network + mode: "0644" + notify: update initramfs + +- name: Enable systemd-networkd + ansible.builtin.systemd_service: + name: systemd-networkd + enabled: true + state: restarted + +- name: Enable systemd-resolved + ansible.builtin.systemd_service: + name: systemd-resolved + enabled: true + state: restarted diff --git a/roles/node/tasks/packages.yml b/roles/node/tasks/packages.yml new file mode 100644 index 0000000..b05f4e5 --- /dev/null +++ b/roles/node/tasks/packages.yml @@ -0,0 +1,10 @@ +- name: Install packages + ansible.builtin.apt: + name: "{{ item }}" + state: present + install_recommends: false + loop: "{{ packages }}" + +- name: Remove dependencies that are no longer required + ansible.builtin.apt: + autoremove: true diff --git a/roles/node/tasks/update.yml b/roles/node/tasks/update.yml new file mode 100644 index 0000000..e64c9e1 --- /dev/null +++ b/roles/node/tasks/update.yml @@ -0,0 +1,5 @@ +- name: Update and upgrade system + ansible.builtin.apt: + upgrade: true + update_cache: true + cache_valid_time: 86400 diff --git a/roles/node/templates/etc-hostname.j2 b/roles/node/templates/etc-hostname.j2 new file mode 100644 index 0000000..2139393 --- /dev/null +++ b/roles/node/templates/etc-hostname.j2 @@ -0,0 +1 @@ +node-{{ groups['nodes'].index(inventory_hostname) + 1 }} \ No newline at end of file diff --git a/roles/node/templates/etc-hosts.j2 b/roles/node/templates/etc-hosts.j2 new file mode 100644 index 0000000..3e59d97 --- /dev/null +++ b/roles/node/templates/etc-hosts.j2 @@ -0,0 +1,10 @@ +127.0.0.1 localhost +127.0.1.1 node-{{ groups['nodes'].index(inventory_hostname) + 1 }} + +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters + +{% for item in hostnames %} +{{ item.ip }} {{ item.name }} +{% endfor %} \ No newline at end of file diff --git a/roles/node/templates/etc-systemd-network-10-lan0.link.j2 b/roles/node/templates/etc-systemd-network-10-lan0.link.j2 new file mode 100644 index 0000000..07cf3e7 --- /dev/null +++ b/roles/node/templates/etc-systemd-network-10-lan0.link.j2 @@ -0,0 +1,5 @@ +[Match] +MACAddress={{ ansible_default_ipv4.macaddress }} + +[Link] +Name={{ interface_name }} diff --git a/roles/node/templates/etc-systemd-network-20-lan0.network.j2 b/roles/node/templates/etc-systemd-network-20-lan0.network.j2 new file mode 100644 index 0000000..2369054 --- /dev/null +++ b/roles/node/templates/etc-systemd-network-20-lan0.network.j2 @@ -0,0 +1,9 @@ +[Match] +Name={{ interface_name }} + +[Network] +Address={{ ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0]) }}/24 +Gateway={{ gateway }} +{% for dns in dns_servers %} +DNS={{ dns }} +{% endfor %} diff --git a/roles/worker/files/k3s-agent.sh b/roles/worker/files/k3s-agent.sh new file mode 100644 index 0000000..6b8197b --- /dev/null +++ b/roles/worker/files/k3s-agent.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +export K3S_TOKEN="$1" + +curl -sfL https://get.k3s.io | sh -s - agent --server "https://${2}:6443" \ No newline at end of file diff --git a/roles/worker/meta/meta.yml b/roles/worker/meta/meta.yml new file mode 100644 index 0000000..28d4ef1 --- /dev/null +++ b/roles/worker/meta/meta.yml @@ -0,0 +1,2 @@ +dependencies: + - name: node diff --git a/roles/worker/tasks/main.yml b/roles/worker/tasks/main.yml new file mode 100644 index 0000000..af0fd9e --- /dev/null +++ b/roles/worker/tasks/main.yml @@ -0,0 +1,2 @@ +- name: Install k3s as agent + ansible.builtin.script: k3s-agent.sh {{ K3S_TOKEN }} {{ groups['master-primary'][0] }} diff --git a/workers.yml b/workers.yml new file mode 100644 index 0000000..54ecaef --- /dev/null +++ b/workers.yml @@ -0,0 +1,6 @@ +- name: Cluster workers + hosts: workers + become: true + gather_facts: true + roles: + - worker