homeserver/ansible: add playbook to spin up k8s cluster

- add new playbook to spin-up kubernetes cluster using k0sctl and
  k0sctl config file
This commit is contained in:
2025-06-28 13:37:19 +03:00
parent 6a9aefa02d
commit cba783b7ba
7 changed files with 213 additions and 2 deletions

View File

@ -1,4 +1,22 @@
apt_packages: apt_packages:
- curl - curl
- vim - vim
- htop - htop
# Kubernetes k0sctl configuration vars
master1_ip: "192.168.1.151"
master1_hostname: "vm6"
master2_ip: "192.168.1.161"
master2_hostname: "vm8"
worker1_ip: "192.168.1.152"
worker1_hostname: "vm7"
worker2_ip: "192.168.1.162"
worker2_hostname: "vm9"
pod_CIDR: "10.244.0.0/16"
service_CIDR: "10.96.0.0/12"
metallb_ip_range: "192.168.1.201-192.168.1.220"
k0s_version: "v1.33.2+k0s.0"
metallb_version: "0.15.2"
traefik_version: "36.2.0"

View File

@ -17,7 +17,7 @@ vm_list:
ip: "192.168.1.152/24" ip: "192.168.1.152/24"
gateway: "192.168.1.1" gateway: "192.168.1.1"
nameserver1: "192.168.1.145" nameserver1: "192.168.1.145"
nameserver2: "8.8.8.8" nameserver2: "1.1.1.1"
# cloud-init variables # cloud-init variables
node: "homeserver1" node: "homeserver1"

View File

@ -0,0 +1,6 @@
- name: Create Kubernetes Cluster
hosts: vms
vars_files:
- ../secrets/vault.yaml
roles:
- create-kubernetes-cluster

View File

@ -0,0 +1,97 @@
- name: Remove known_hosts file if it exists
delegate_to: localhost
run_once: true
ansible.builtin.file:
path: /home/taqi/.ssh/known_hosts
state: absent
- name: Remove k0ctl lock file if it exists
ansible.builtin.file:
path: /run/lock/k0sctl
state: absent
become: true
- name: Install k0sctl on host
delegate_to: localhost
ansible.builtin.command:
cmd: "go install github.com/k0sproject/k0sctl@latest"
- name: Ensure k0sctl is installed on host
delegate_to: localhost
run_once: true
ansible.builtin.command:
cmd: "k0sctl version"
register: k0sctl_version
changed_when: false
- name: Generate k0sctl configuration file
delegate_to: localhost
run_once: true
ansible.builtin.template:
src: k0sctl.yaml.j2
dest: /tmp/k0sctl.yaml
when: k0sctl_version is defined
tags:
- generate-k0sctl-config
- name: Generate MetalLB IP Address Pool configuration file
delegate_to: localhost
run_once: true
ansible.builtin.template:
src: ipAddressPool.yaml.j2
dest: /tmp/ipAddressPool.yaml
when: k0sctl_version is defined
tags:
- generatemetallb-ippool
- metallb-ippool
- name: Create Cluster using k0sctl from host
delegate_to: localhost
run_once: true
ansible.builtin.command:
cmd: "k0sctl apply --config /tmp/k0sctl.yaml"
when: k0sctl_version is defined
- name: Save kubeconfig file on host
delegate_to: localhost
run_once: true
ansible.builtin.shell:
cmd: "cd /tmp && k0sctl kubeconfig > /home/taqi/.kube/k0s_config.yaml"
register: kubeconfig_result
retries: 3
delay: 5
until: kubeconfig_result.rc == 0
when: k0sctl_version is defined
tags:
- generate-kubeconfig
- name: Apply IP Pool for MetalLB from host
delegate_to: localhost
run_once: true
ansible.builtin.shell:
cmd: "kubectl apply -f /tmp/ipAddressPool.yaml --kubeconfig /home/taqi/.kube/k0s_config.yaml"
register: metallb_ippool_result
retries: 3
delay: 5
until: metallb_ippool_result.rc == 0
when: k0sctl_version is defined
tags:
- metallb-ippool
- name: Cleanup temporary files
delegate_to: localhost
run_once: true
block:
- name: Remove k0sctl.yaml temporary file
ansible.builtin.file:
path: /tmp/k0sctl.yaml
state: absent
- name: Remove ipAddressPool.yaml temporary file
ansible.builtin.shell:
cmd: "rm -f /tmp/ipAddressPool.yaml"
delegate_to: localhost
run_once: true
tags:
- cleanup
when: k0sctl_version is defined

View File

@ -0,0 +1,8 @@
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- "{{ metallb_ip_range }}"

View File

@ -0,0 +1,70 @@
apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
name: k0s-cluster
spec:
hosts:
- ssh:
address: "{{ master1_ip }}"
user: "{{ ansible_vm_user }}"
keyPath: "{{ ansible_ssh_private_key_file }}"
role: controller+worker
hostname: "{{ master1_hostname }}"
noTaints: true
- ssh:
address: "{{ master2_ip }}"
user: "{{ ansible_vm_user }}"
keyPath: "{{ ansible_ssh_private_key_file }}"
role: controller+worker
hostname: "{{ master2_hostname }}"
noTaints: true
- ssh:
address: "{{ worker1_ip }}"
user: "{{ ansible_vm_user }}"
keyPath: "{{ ansible_ssh_private_key_file }}"
role: worker
hostname: "{{ worker1_hostname }}"
- ssh:
address: "{{ worker2_ip }}"
user: "{{ ansible_vm_user }}"
keyPath: "{{ ansible_ssh_private_key_file }}"
role: worker
hostname: "{{ worker2_hostname }}"
k0s:
version: "{{ k0s_version }}"
config:
spec:
api:
address: "{{ master1_ip }}"
port: 6443
k0sApiPort: 9443
sans:
- "{{ master1_ip }}"
- "{{ master2_ip }}"
- k8s.local
- api.k8s.local
network:
kubeProxy:
mode: iptables
kuberouter:
disabled: false
podCIDR: "{{ pod_CIDR }}"
serviceCIDR: "{{ service_CIDR }}"
provider: kuberouter
extensions:
helm:
concurrencyLevel: 5
repositories:
- name: metallb
url: https://metallb.github.io/metallb
- name: traefik
url: https://traefik.github.io/charts
charts:
- name: metallb
chartname: metallb/metallb
version: "{{ metallb_version }}"
namespace: metallb-system
- name: traefik
chartname: traefik/traefik
version: "{{ traefik_version }}"
namespace: traefik-system

View File

@ -0,0 +1,12 @@
# custom-values.yaml
config:
address: $VIP_ADDRESS
env:
# Ensure the interface name is correct for the Nodes
# Can be found using `ip a` command
# For proxmox nodes, the interface name is usually `ens18`
vip_interface: ens18
cp_enable: true
svc_enable: false
nodeSelector:
node-role.kubernetes.io/control-plane: "true"