k3s (D6): Dienst-VM k3s per tofu, Rollen k3s-server/k3s-agent/k3s-apps, Manifeste, NEX-Sprachdienste als k3s-Umzugstest
ci / test (push) Failing after 22s

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Robert Rapp
2026-10-15 11:55:18 +02:00
co-authored by Claude Fable 5.1
parent 6cccc01d14
commit 2c1d43e9c7
23 changed files with 701 additions and 15 deletions
@@ -0,0 +1,8 @@
# k3s-Steuerung (D6) auf der Dienst-VM "k3s". Version gepinnt (Kanal stable, 15.10.2026).
k3s_version: v1.36.5+k3s1
k3s_server_name: k3s.knaster # Name, unter dem die Agents den Server finden (/etc/hosts, Rolle k3s-agent)
k3s_install_script: /usr/local/src/k3s-install.sh
# Geheimnisse und Zugang landen auf ops, nicht im Repo
k3s_env_file: /root/.config/knaster/k3s.env # K3S_URL und K3S_TOKEN für die Agents
k3s_kubeconfig: /root/.kube/config # kubectl auf ops
k3s_kubectl_version: "{{ k3s_version | regex_replace('\+k3s\d+$', '') }}"
@@ -0,0 +1,98 @@
# k3s-Server (Steuerung, Datenbank, API) auf der Dienst-VM. Ohne traefik (kein Ingress nötig),
# servicelb bleibt für Dienste vom Typ LoadBalancer. Die Agents (GPU-VMs) kommen über die Rolle k3s-agent.
- name: curl vorhanden
ansible.builtin.apt:
name: curl
state: present
update_cache: true
- name: Installationsskript laden
ansible.builtin.get_url:
url: https://get.k3s.io
dest: "{{ k3s_install_script }}"
mode: "0755"
- name: Konfiguration /etc/rancher/k3s/config.yaml
ansible.builtin.copy:
dest: /etc/rancher/k3s/config.yaml
mode: "0600"
content: |
# Verwaltet von Ansible (Rolle k3s-server)
disable: [traefik]
write-kubeconfig-mode: "0600"
tls-san: [{{ k3s_server_name }}, {{ ansible_host }}]
node-label: [knaster.role=control]
register: k3s_server_config
vars:
ansible_become: true
- name: Installierte Version lesen
ansible.builtin.command: /usr/local/bin/k3s --version
register: k3s_installed
failed_when: false
changed_when: false
- name: k3s-Server installieren oder auf die gepinnte Version bringen
ansible.builtin.command: "{{ k3s_install_script }} server"
environment:
INSTALL_K3S_VERSION: "{{ k3s_version }}"
when: k3s_version not in (k3s_installed.stdout | default(''))
- name: k3s neu starten, wenn sich die Konfiguration geändert hat
ansible.builtin.service:
name: k3s
state: restarted
when: k3s_server_config.changed and k3s_version in (k3s_installed.stdout | default(''))
- name: Warten, bis der Knoten bereit ist
ansible.builtin.command: /usr/local/bin/k3s kubectl get node {{ inventory_hostname }} -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'
register: k3s_ready
until: k3s_ready.stdout == "True"
retries: 30
delay: 5
changed_when: false
- name: Token und kubeconfig lesen
ansible.builtin.slurp:
src: "{{ item }}"
loop: [/var/lib/rancher/k3s/server/node-token, /etc/rancher/k3s/k3s.yaml]
register: k3s_secrets
no_log: true
- name: Zugang nach ops schreiben
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0700"
loop: ["{{ k3s_env_file | dirname }}", "{{ k3s_kubeconfig | dirname }}"]
delegate_to: localhost
become: false
- name: K3S_URL und K3S_TOKEN auf ops ({{ k3s_env_file }})
ansible.builtin.copy:
dest: "{{ k3s_env_file }}"
mode: "0600"
content: |
K3S_URL=https://{{ k3s_server_name }}:6443
K3S_TOKEN={{ k3s_secrets.results[0].content | b64decode | trim }}
delegate_to: localhost
become: false
no_log: true
- name: kubeconfig auf ops ({{ k3s_kubeconfig }}, Server = VM-Adresse)
ansible.builtin.copy:
dest: "{{ k3s_kubeconfig }}"
mode: "0600"
content: "{{ k3s_secrets.results[1].content | b64decode | replace('https://127.0.0.1:6443', 'https://' ~ ansible_host ~ ':6443') }}"
delegate_to: localhost
become: false
no_log: true
- name: kubectl auf ops (Version passend zum Server)
ansible.builtin.get_url:
url: "https://dl.k8s.io/release/{{ k3s_kubectl_version }}/bin/linux/amd64/kubectl"
checksum: "sha256:https://dl.k8s.io/release/{{ k3s_kubectl_version }}/bin/linux/amd64/kubectl.sha256"
dest: /usr/local/bin/kubectl
mode: "0755"
delegate_to: localhost
become: false