k3s: RustDesk-Server (hbbs/hbbr) als Manifest und Playbook, parallel zu appsrv08
ci / test (push) Successful in 26s

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Robert Rapp
2026-10-15 14:41:00 +02:00
co-authored by Claude Fable 5.1
parent eafebaab94
commit d11e2d90fc
2 changed files with 183 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
# RustDesk-Server (ID-Server hbbs + Relay hbbr) in k3s, Umzug vom Portainer-Stack „rustdesk“ auf appsrv08
# (Phase 6.0, 15.10.2026). Schlüsselpaar id_ed25519 kommt aus dem Secret rustdesk-keys (legt
# playbooks/rustdesk-k3s.yml aus /root/.config/knaster/rustdesk/ auf ops an; nicht im Repo). Mit demselben
# Schlüssel bleiben die in den Clients hinterlegten Public Keys gültig.
#
# Erreichbar über Service-Typ LoadBalancer (k3s ServiceLB): Ports 21115–21119/tcp und 21116/udp auf jeder
# Knoten-Adresse. Die Clients tragen als ID-Server die Adresse ein, die das Playbook als Relay-Adresse setzt
# (rustdesk_public_host, Standard: die k3s-VM). Erst mit fester Adresse/DNS-Namen für die Clients umstellen.
apiVersion: v1
kind: Namespace
metadata:
name: rustdesk
labels:
knaster.app: rustdesk
---
# Datenbank (ID-Registrierungen) auf local-path: bindet den Pod an den Knoten, auf dem er zuerst lief.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rustdesk-data
namespace: rustdesk
spec:
accessModes: [ReadWriteOnce]
storageClassName: local-path
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rustdesk
namespace: rustdesk
labels: {app: rustdesk}
spec:
replicas: 1
strategy: {type: Recreate} # ein Datenverzeichnis, ein Pod
selector:
matchLabels: {app: rustdesk}
template:
metadata:
labels: {app: rustdesk}
spec:
nodeSelector:
knaster.gpu: "true" # nicht auf die kleine k3s-VM (2 Kerne, 3 GB)
containers:
- name: hbbs
image: rustdesk/rustdesk-server:1.1.14
# Relay-Adresse, die hbbs den Clients nennt; setzt das Playbook (RELAY_HOST) – muss von den Clients erreichbar sein
command: ["sh", "-c", "exec hbbs -r ${RELAY_HOST}:21117 -k _"]
env:
- {name: RELAY_HOST, value: "__RELAY_HOST__"}
workingDir: /root
ports:
- {name: nat-test, containerPort: 21115, protocol: TCP}
- {name: id-tcp, containerPort: 21116, protocol: TCP}
- {name: id-udp, containerPort: 21116, protocol: UDP}
- {name: web, containerPort: 21118, protocol: TCP}
resources:
requests: {cpu: 50m, memory: 64Mi}
limits: {memory: 256Mi}
volumeMounts:
- {name: data, mountPath: /root}
- {name: keys, mountPath: /root/id_ed25519, subPath: id_ed25519, readOnly: true}
- {name: keys, mountPath: /root/id_ed25519.pub, subPath: id_ed25519.pub, readOnly: true}
readinessProbe:
tcpSocket: {port: id-tcp}
periodSeconds: 10
livenessProbe:
tcpSocket: {port: id-tcp}
periodSeconds: 30
failureThreshold: 3
- name: hbbr
image: rustdesk/rustdesk-server:1.1.14
command: ["hbbr", "-k", "_"]
workingDir: /root
ports:
- {name: relay, containerPort: 21117, protocol: TCP}
- {name: relay-web, containerPort: 21119, protocol: TCP}
resources:
requests: {cpu: 50m, memory: 64Mi}
limits: {memory: 256Mi}
volumeMounts:
- {name: keys, mountPath: /root/id_ed25519, subPath: id_ed25519, readOnly: true}
- {name: keys, mountPath: /root/id_ed25519.pub, subPath: id_ed25519.pub, readOnly: true}
readinessProbe:
tcpSocket: {port: relay}
periodSeconds: 10
volumes:
- name: data
persistentVolumeClaim: {claimName: rustdesk-data}
- name: keys
secret:
secretName: rustdesk-keys
defaultMode: 0400
---
apiVersion: v1
kind: Service
metadata:
name: rustdesk
namespace: rustdesk
labels: {app: rustdesk}
spec:
type: LoadBalancer
selector: {app: rustdesk}
ports:
- {name: nat-test, port: 21115, targetPort: 21115, protocol: TCP}
- {name: id-tcp, port: 21116, targetPort: 21116, protocol: TCP}
- {name: id-udp, port: 21116, targetPort: 21116, protocol: UDP}
- {name: relay, port: 21117, targetPort: 21117, protocol: TCP}
- {name: web, port: 21118, targetPort: 21118, protocol: TCP}
- {name: relay-web, port: 21119, targetPort: 21119, protocol: TCP}
@@ -0,0 +1,71 @@
# RustDesk-Server (hbbs/hbbr) in k3s, Umzug vom Portainer-Stack „rustdesk“ auf appsrv08 (15.10.2026).
# Läuft auf ops: ansible-playbook playbooks/rustdesk-k3s.yml [-e rustdesk_public_host=<Adresse für Clients>]
#
# Voraussetzung: Schlüsselpaar des bisherigen Servers unter /root/.config/knaster/rustdesk/{id_ed25519,id_ed25519.pub}
# auf ops (aus dem Docker-Volume rustdesk_rustdesk-data von appsrv08, Pfad /root). Damit bleiben die in den
# Clients hinterlegten Public Keys gültig. Die Clients selbst zeigen weiter auf appsrv08, bis ihre
# Server-Adresse umgestellt wird (Installer-Name im Stack rustdesk-updater und bestehende Installationen).
- name: RustDesk nach k3s
hosts: localhost
connection: local
gather_facts: false
vars:
manifest: "{{ playbook_dir }}/../../../../deploy/k8s/rustdesk/rustdesk.yaml"
key_dir: /root/.config/knaster/rustdesk
# Adresse, die hbbs den Clients als Relay nennt (Port 21117). Standard: die k3s-VM; ServiceLB stellt die Ports
# auf jeder Knoten-Adresse bereit. Nach DHCP-Reservierung/DNS-Name hier bzw. per -e anpassen.
rustdesk_public_host: "{{ hostvars['k3s'].ansible_host }}"
tasks:
- name: Schlüsseldateien vorhanden?
ansible.builtin.stat:
path: "{{ key_dir }}/{{ item }}"
loop: [id_ed25519, id_ed25519.pub]
register: keys
failed_when: not keys.stat.exists
- name: Namespace
ansible.builtin.shell: >
kubectl create namespace rustdesk --dry-run=client -o yaml | kubectl apply -f -
register: ns
changed_when: "'created' in ns.stdout"
- name: Secret rustdesk-keys aus den Schlüsseldateien
ansible.builtin.shell: >
kubectl -n rustdesk create secret generic rustdesk-keys
--from-file=id_ed25519={{ key_dir }}/id_ed25519 --from-file=id_ed25519.pub={{ key_dir }}/id_ed25519.pub
--dry-run=client -o yaml | kubectl apply -f -
register: secret
changed_when: "'configured' in secret.stdout or 'created' in secret.stdout"
no_log: true
- name: Manifest mit Relay-Adresse anwenden
ansible.builtin.shell: >
sed 's/__RELAY_HOST__/{{ rustdesk_public_host }}/' {{ manifest }} | kubectl apply -f -
register: dep
changed_when: "'configured' in dep.stdout or 'created' in dep.stdout"
- name: Neustart, wenn sich nur das Secret geändert hat
ansible.builtin.command: kubectl -n rustdesk rollout restart deployment/rustdesk
when: secret.changed and not dep.changed
- name: Warten, bis bereit
ansible.builtin.command: kubectl -n rustdesk rollout status deployment/rustdesk --timeout=300s
changed_when: false
- name: Public Key im Cluster entspricht der Datei
ansible.builtin.shell: >
set -o pipefail;
kubectl -n rustdesk exec deploy/rustdesk -c hbbs -- cat /root/id_ed25519.pub | tr -d '\n' | cmp - <(tr -d '\n' < {{ key_dir }}/id_ed25519.pub)
args: {executable: /bin/bash}
changed_when: false
- name: Ports von außen erreichbar (ID-Server 21116/tcp, Relay 21117/tcp auf {{ rustdesk_public_host }})
ansible.builtin.wait_for:
host: "{{ rustdesk_public_host }}"
port: "{{ item }}"
timeout: 30
loop: [21115, 21116, 21117, 21118, 21119]
- name: Ergebnis
ansible.builtin.debug:
msg: "RustDesk in k3s bereit: ID-Server/Relay {{ rustdesk_public_host }}, Public Key {{ lookup('file', key_dir + '/id_ed25519.pub') }}"