feat: Add HA Kubernetes cluster with Terraform + Ansible
- 3x CX23 control plane nodes (HA) - 4x CX33 worker nodes - k3s with embedded etcd - Hetzner CCM for load balancers - Gitea CI/CD workflows - Backblaze B2 for Terraform state
This commit is contained in:
3
ansible/roles/ccm/defaults/main.yml
Normal file
3
ansible/roles/ccm/defaults/main.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
hcloud_token: ""
|
||||
cluster_name: "k8s-cluster"
|
||||
40
ansible/roles/ccm/tasks/main.yml
Normal file
40
ansible/roles/ccm/tasks/main.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
- name: Check if Hetzner CCM is already deployed
|
||||
command: kubectl get namespace hetzner-cloud-system
|
||||
register: ccm_namespace
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Create Hetzner CCM namespace
|
||||
command: kubectl create namespace hetzner-cloud-system
|
||||
when: ccm_namespace.rc != 0
|
||||
changed_when: true
|
||||
|
||||
- name: Create Hetzner cloud secret
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: hcloud
|
||||
namespace: hetzner-cloud-system
|
||||
stringData:
|
||||
token: "{{ hcloud_token }}"
|
||||
network: "{{ cluster_name }}-network"
|
||||
no_log: true
|
||||
when: hcloud_token is defined
|
||||
|
||||
- name: Deploy Hetzner CCM
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
src: "{{ item }}"
|
||||
loop:
|
||||
- https://raw.githubusercontent.com/hetznercloud/hcloud-cloud-controller-manager/main/deploy/ccm-networks.yaml
|
||||
when: ccm_namespace.rc != 0
|
||||
|
||||
- name: Wait for CCM pods to be ready
|
||||
command: kubectl rollout status deployment/hcloud-cloud-controller-manager -n hetzner-cloud-system
|
||||
changed_when: false
|
||||
retries: 30
|
||||
delay: 10
|
||||
2
ansible/roles/common/defaults/main.yml
Normal file
2
ansible/roles/common/defaults/main.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
common_upgrade_packages: false
|
||||
58
ansible/roles/common/tasks/main.yml
Normal file
58
ansible/roles/common/tasks/main.yml
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
- name: Update apt cache
|
||||
apt:
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
|
||||
- name: Upgrade packages
|
||||
apt:
|
||||
upgrade: dist
|
||||
when: common_upgrade_packages | default(false)
|
||||
|
||||
- name: Install required packages
|
||||
apt:
|
||||
name:
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
- curl
|
||||
- gnupg
|
||||
- lsb-release
|
||||
- software-properties-common
|
||||
- jq
|
||||
- htop
|
||||
- vim
|
||||
state: present
|
||||
|
||||
- name: Disable swap
|
||||
command: swapoff -a
|
||||
changed_when: true
|
||||
|
||||
- name: Remove swap from fstab
|
||||
mount:
|
||||
name: swap
|
||||
fstype: swap
|
||||
state: absent
|
||||
|
||||
- name: Load br_netfilter module
|
||||
modprobe:
|
||||
name: br_netfilter
|
||||
state: present
|
||||
|
||||
- name: Persist br_netfilter module
|
||||
copy:
|
||||
dest: /etc/modules-load.d/k8s.conf
|
||||
content: |
|
||||
br_netfilter
|
||||
overlay
|
||||
mode: "0644"
|
||||
|
||||
- name: Configure sysctl for Kubernetes
|
||||
sysctl:
|
||||
name: "{{ item.name }}"
|
||||
value: "{{ item.value }}"
|
||||
state: present
|
||||
reload: true
|
||||
loop:
|
||||
- { name: net.bridge.bridge-nf-call-iptables, value: 1 }
|
||||
- { name: net.bridge.bridge-nf-call-ip6tables, value: 1 }
|
||||
- { name: net.ipv4.ip_forward, value: 1 }
|
||||
4
ansible/roles/k3s-agent/defaults/main.yml
Normal file
4
ansible/roles/k3s-agent/defaults/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
k3s_version: latest
|
||||
k3s_server_url: ""
|
||||
k3s_token: ""
|
||||
30
ansible/roles/k3s-agent/tasks/main.yml
Normal file
30
ansible/roles/k3s-agent/tasks/main.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
- name: Check if k3s agent is already installed
|
||||
stat:
|
||||
path: /usr/local/bin/k3s-agent
|
||||
register: k3s_agent_binary
|
||||
|
||||
- name: Download k3s install script
|
||||
get_url:
|
||||
url: https://get.k3s.io
|
||||
dest: /tmp/install-k3s.sh
|
||||
mode: "0755"
|
||||
when: not k3s_agent_binary.stat.exists
|
||||
|
||||
- name: Install k3s agent
|
||||
environment:
|
||||
INSTALL_K3S_VERSION: "{{ k3s_version if k3s_version != 'latest' else '' }}"
|
||||
K3S_URL: "{{ k3s_server_url }}"
|
||||
K3S_TOKEN: "{{ k3s_token }}"
|
||||
command: /tmp/install-k3s.sh agent
|
||||
args:
|
||||
creates: /usr/local/bin/k3s-agent
|
||||
when: not k3s_agent_binary.stat.exists
|
||||
|
||||
- name: Wait for k3s agent to be ready
|
||||
command: systemctl is-active k3s-agent
|
||||
register: agent_status
|
||||
until: agent_status.stdout == "active"
|
||||
retries: 30
|
||||
delay: 10
|
||||
changed_when: false
|
||||
3
ansible/roles/k3s-server/defaults/main.yml
Normal file
3
ansible/roles/k3s-server/defaults/main.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
k3s_version: latest
|
||||
k3s_token: ""
|
||||
56
ansible/roles/k3s-server/tasks/main.yml
Normal file
56
ansible/roles/k3s-server/tasks/main.yml
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
- name: Check if k3s is already installed
|
||||
stat:
|
||||
path: /usr/local/bin/k3s
|
||||
register: k3s_binary
|
||||
|
||||
- name: Download k3s install script
|
||||
get_url:
|
||||
url: https://get.k3s.io
|
||||
dest: /tmp/install-k3s.sh
|
||||
mode: "0755"
|
||||
when: not k3s_binary.stat.exists
|
||||
|
||||
- name: Install k3s server (primary)
|
||||
environment:
|
||||
INSTALL_K3S_VERSION: "{{ k3s_version if k3s_version != 'latest' else '' }}"
|
||||
K3S_TOKEN: "{{ k3s_token }}"
|
||||
command: /tmp/install-k3s.sh server --cluster-init
|
||||
args:
|
||||
creates: /usr/local/bin/k3s
|
||||
when:
|
||||
- not k3s_binary.stat.exists
|
||||
- k3s_primary | default(false)
|
||||
|
||||
- name: Install k3s server (secondary)
|
||||
environment:
|
||||
INSTALL_K3S_VERSION: "{{ k3s_version if k3s_version != 'latest' else '' }}"
|
||||
K3S_TOKEN: "{{ k3s_token }}"
|
||||
command: /tmp/install-k3s.sh server --server https://{{ k3s_primary_ip }}:6443
|
||||
args:
|
||||
creates: /usr/local/bin/k3s
|
||||
when:
|
||||
- not k3s_binary.stat.exists
|
||||
- not (k3s_primary | default(false))
|
||||
|
||||
- name: Wait for k3s to be ready
|
||||
command: kubectl get nodes
|
||||
register: k3s_ready
|
||||
until: k3s_ready.rc == 0
|
||||
retries: 30
|
||||
delay: 10
|
||||
changed_when: false
|
||||
|
||||
- name: Copy kubeconfig to default location for root
|
||||
file:
|
||||
src: /etc/rancher/k3s/k3s.yaml
|
||||
dest: /root/.kube/config
|
||||
state: link
|
||||
force: true
|
||||
|
||||
- name: Ensure .kube directory exists for ansible user
|
||||
file:
|
||||
path: "/home/{{ ansible_user }}/.kube"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
when: ansible_user != 'root'
|
||||
Reference in New Issue
Block a user