--- # ============================================================ # RKE2 HA-Cluster Installation # kube-ctrl (10.3.1.100) - erster Server # kube-work1 (10.3.1.101) - zweiter Server # kube-work2 (10.3.1.102) - dritter Server # ============================================================ - name: "Phase 1 – Basis-Vorbereitung auf allen Nodes" hosts: kubernetes become: true vars: rke2_token: "pfannkuchen-rke2-2026" rke2_server1: "kube-ctrl" rke2_server1_ip: "10.3.1.100" tasks: - name: /etc/hosts – alle Cluster-Nodes eintragen blockinfile: path: /etc/hosts marker: "# {mark} KUBERNETES CLUSTER" block: | 10.3.1.100 kube-ctrl 10.3.1.101 kube-work1 10.3.1.102 kube-work2 - name: Swap deaktivieren (sofort) command: swapoff -a changed_when: false - name: Swap permanent deaktivieren (fstab) replace: path: /etc/fstab regexp: '^([^#].*\sswap\s.*)$' replace: '# \1' - name: Kernel-Parameter für Kubernetes setzen copy: dest: /etc/sysctl.d/99-kubernetes.conf content: | net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 - name: br_netfilter Modul permanent laden copy: dest: /etc/modules-load.d/k8s.conf content: | br_netfilter - name: br_netfilter Modul jetzt laden modprobe: name: br_netfilter state: present - name: sysctl neu laden command: sysctl --system changed_when: false - name: Longhorn Abhängigkeiten installieren apt: name: - open-iscsi - nfs-common - cryptsetup - dmsetup state: present update_cache: true - name: iscsi_tcp Modul persistent laden copy: dest: /etc/modules-load.d/longhorn.conf content: "iscsi_tcp\n" - name: iscsi_tcp Modul jetzt laden modprobe: name: iscsi_tcp state: present - name: open-iscsi Service starten systemd: name: open-iscsi state: started enabled: true - name: RKE2 installieren shell: curl -sfL https://get.rke2.io | sh - args: creates: /usr/local/bin/rke2 - name: RKE2 config-Verzeichnis anlegen file: path: /etc/rancher/rke2 state: directory mode: '0755' - name: config.yaml - erster Server kube-ctrl OHNE server-Zeile copy: dest: /etc/rancher/rke2/config.yaml content: | tls-san: - kube-ctrl - kube-work1 - kube-work2 - 10.3.1.100 - 10.3.1.101 - 10.3.1.102 kube-apiserver-arg: - "service-node-port-range=1-32767" cni: none disable: rke2-ingress-nginx token: {{ rke2_token }} when: inventory_hostname == 'kube-ctrl' - name: config.yaml - weitere Server MIT server-Zeile copy: dest: /etc/rancher/rke2/config.yaml content: | server: https://kube-ctrl:9345 tls-san: - kube-ctrl - kube-work1 - kube-work2 - 10.3.1.100 - 10.3.1.101 - 10.3.1.102 kube-apiserver-arg: - "service-node-port-range=1-32767" cni: none disable: rke2-ingress-nginx token: {{ rke2_token }} when: inventory_hostname != 'kube-ctrl' - name: kubectl Symlink erstellen file: src: /var/lib/rancher/rke2/bin/kubectl dest: /usr/local/bin/kubectl state: link force: true - name: "Phase 2 – Ersten Server starten" hosts: kube-ctrl become: true tasks: - name: RKE2-Server auf kube-ctrl starten und enablen systemd: name: rke2-server state: started enabled: true - name: Warten bis kubeconfig vorhanden ist (max 5 min) wait_for: path: /etc/rancher/rke2/rke2.yaml timeout: 300 - name: Warten bis API-Server erreichbar ist wait_for: host: 127.0.0.1 port: 6443 timeout: 300 - name: Kubeconfig für root anlegen shell: | mkdir -p /root/.kube cp /etc/rancher/rke2/rke2.yaml /root/.kube/config args: creates: /root/.kube/config - name: Kubeconfig für sascha anlegen shell: | mkdir -p /home/sascha/.kube cp /etc/rancher/rke2/rke2.yaml /home/sascha/.kube/config chown -R sascha:sascha /home/sascha/.kube args: creates: /home/sascha/.kube/config - name: Cilium CLI installieren shell: | CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt) curl -L --fail --remote-name-all \ https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz tar xzvf cilium-linux-amd64.tar.gz -C /usr/local/bin rm -f cilium-linux-amd64.tar.gz args: creates: /usr/local/bin/cilium - name: Cilium installieren shell: | export KUBECONFIG=/etc/rancher/rke2/rke2.yaml cilium install \ --set kubeProxyReplacement=true \ --set k8sServiceHost=kube-ctrl \ --set k8sServicePort=6443 \ --set operator.replicas=1 args: creates: /usr/local/bin/cilium-installed-marker register: cilium_install_result changed_when: "'already installed' not in cilium_install_result.stdout" - name: Warten bis kube-ctrl Ready ist (Cilium braucht ~2 min) shell: | export KUBECONFIG=/etc/rancher/rke2/rke2.yaml kubectl wait node kube-ctrl --for=condition=Ready --timeout=300s register: node_ready retries: 3 delay: 30 - name: Helm installieren shell: curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash args: creates: /usr/local/bin/helm - name: "Phase 3 – Weitere Server joinen" hosts: kube-work1,kube-work2 become: true serial: 1 # nacheinander starten! tasks: - name: RKE2-Server starten und enablen systemd: name: rke2-server state: started enabled: true - name: 45 Sekunden warten damit der Node dem Cluster beitreten kann pause: seconds: 45 - name: "Phase 4 – Cluster-Tools installieren (auf kube-ctrl)" hosts: kube-ctrl become: true tasks: - name: Alle 3 Nodes auf Ready warten shell: | export KUBECONFIG=/etc/rancher/rke2/rke2.yaml kubectl wait nodes --all --for=condition=Ready --timeout=300s retries: 5 delay: 30 register: all_ready until: all_ready.rc == 0 - name: Kubeconfig für sascha aktualisieren (alle Nodes jetzt bekannt) shell: | mkdir -p /home/sascha/.kube cp /etc/rancher/rke2/rke2.yaml /home/sascha/.kube/config chown -R sascha:sascha /home/sascha/.kube - name: Longhorn – Helm Repo hinzufügen shell: | helm repo add longhorn https://charts.longhorn.io helm repo update changed_when: false - name: Longhorn installieren shell: | export KUBECONFIG=/etc/rancher/rke2/rke2.yaml helm install longhorn longhorn/longhorn \ --namespace longhorn-system \ --create-namespace \ --version 1.11.1 register: longhorn_result failed_when: - longhorn_result.rc != 0 - '"already exists" not in longhorn_result.stderr' changed_when: '"already exists" not in longhorn_result.stderr' - name: Cert-Manager installieren shell: | export KUBECONFIG=/etc/rancher/rke2/rke2.yaml helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \ --version v1.20.0 \ --namespace cert-manager \ --create-namespace \ --set crds.enabled=true register: cm_result failed_when: - cm_result.rc != 0 - '"already exists" not in cm_result.stderr' changed_when: '"already exists" not in cm_result.stderr' - name: Reloader – Helm Repo hinzufügen shell: | helm repo add stakater https://stakater.github.io/stakater-charts helm repo update changed_when: false - name: Reloader installieren shell: | export KUBECONFIG=/etc/rancher/rke2/rke2.yaml helm install reloader stakater/reloader \ -n stakater-reloader \ --create-namespace register: rl_result failed_when: - rl_result.rc != 0 - '"already exists" not in rl_result.stderr' changed_when: '"already exists" not in rl_result.stderr' - name: NGINX Ingress – Helm Repo hinzufügen shell: | helm repo add nginx-stable https://helm.nginx.com/stable helm repo update changed_when: false - name: NGINX Ingress Controller installieren shell: | export KUBECONFIG=/etc/rancher/rke2/rke2.yaml helm install nginx-ingress nginx-stable/nginx-ingress \ --namespace nginx-ingress \ --create-namespace register: nginx_result failed_when: - nginx_result.rc != 0 - '"already exists" not in nginx_result.stderr' changed_when: '"already exists" not in nginx_result.stderr' - name: Finaler Cluster-Status shell: | export KUBECONFIG=/etc/rancher/rke2/rke2.yaml echo "=== NODES ===" && kubectl get nodes -o wide echo "=== NAMESPACES ===" && kubectl get ns echo "=== STORAGECLASS ===" && kubectl get sc register: final_status changed_when: false - name: Cluster-Status ausgeben debug: msg: "{{ final_status.stdout_lines }}"