Kubernetes Cluster mit Proxmox VMs
K3s erlaubt mit geringem Aufwand einen hochverfügbaren Kubernetes-Cluster auf Proxmox Virtual Environment (oder vergleichbar) einzurichten. K3s ist eine schlanke Kubernetes-Distribution von Rancher, die sich besonders für Edge-Computing, IoT und Homelab-Umgebungen eignet. Durch den Einsatz von drei Master Nodes in einem HA-Setup mit embedded etcd, einem HAProxy als Load Balancer und mehreren Worker Nodes entsteht eine produktionsnahe Cluster-Architektur, die Ausfallsicherheit bietet.
Es ist ratsam direkt zu Beginn HA für die Master Nodes einzurichten --cluster-init, nachträglich kann dieses Feature nur über ein Backup/Restore hinzugefügt werden.
VM-Anforderungen (Minimum):
- HAProxy: 1 vCPU, 1 GB RAM, 10 GB Disk
- Master Nodes: 2 vCPUs, 4 GB RAM, 20 GB Disk
- Worker Nodes: 2 vCPUs, 2 GB RAM, 20 GB Disk
- OS: Debian 10 (oder vergleichbar)
Netzwerk:
- Statische IPs für alle Nodes
- Offene Ports zwischen den Nodes
Schritt 1: VMs in Proxmox erstellen
- VMs erstellen (HAProxy, 3 Master, 3 Worker)
- Cloud Init erleichtert das Zuweisen von statischen IPs
- Debian installieren
- Updates:
sudo apt update && sudo apt upgrade -y
Schritt 2: HAProxy installieren Mittels HAProxy verteilen wir die Zugriffe auf die Master Nodes. Diese werden dank der Einrichtung als Cluster Node gleichwertig, da die ==Embedded etcd== automatisch synchronisiert wird. Das ist die einfachste unterstützte HA-Architektur, alternativ könnte eine externe Datenbank (PostgreSQL/MySQL) Verwendung finden.
sudo apt install -y haproxy
MASTER1_IP="192.168.201.1"
MASTER2_IP="192.168.201.2"
MASTER3_IP="192.168.201.3"
cat <<EOF >> /etc/haproxy/haproxy.cfg
frontend k3s-api
bind *:6443
mode tcp
default_backend k3s-masters
backend k3s-masters
mode tcp
balance roundrobin
server master1 ${MASTER1_IP}:6443 check
server master2 ${MASTER2_IP}:6443 check
server master3 ${MASTER3_IP}:6443 check
EOF
Konfiguration auf Syntax-Fehler prüfen, ==WARNING option httplog== kann ignoriert werden:
haproxy -c -f /etc/haproxy/haproxy.cfg
Konfiguration anwenden:
sudo systemctl reload haproxy
Schritt 3: Master Node installieren Auf dem ersten Master Node K3s als Master installieren:
HAPROXY_IP="192.168.201.0"
curl -sfL https://get.k3s.io | sh -s - server \
--cluster-init \
--tls-san=${HAPROXY_IP}
Node-Token für weitere Nodes abrufen:
sudo cat /var/lib/rancher/k3s/server/node-token
Ebenfalls Master2 und Master3 als Master Node installieren:
MASTER1_IP="192.168.201.1"
NODE_TOKEN="K10cf9d2625abcde0a83a53bc4f02192f3fcb4cc8d730ef4e248e023251bbd08139::server:7ba73ceb7480ee96763c43554819976b"
curl -sfL https://get.k3s.io | sh -s - server \
--server https://${MASTER1_IP}:6443 \
--token ${NODE_TOKEN}
Schritt 4: Worker Nodes hinzufügen Auf jedem Worker Node wie folgt installieren:
HAPROXY_IP="192.168.201.0"
NODE_TOKEN="K10cf9d2625abcde0a83a53bc4f02192f3fcb4cc8d730ef4e248e023251bbd08139::server:7ba73ceb7480ee96763c43554819976b"
curl -sfL https://get.k3s.io | K3S_URL=https://${HAPROXY_IP}:6443 K3S_TOKEN=${NODE_TOKEN} sh -
Schritt 5: Cluster verifizieren Auf dem Master:
sudo kubectl get nodes
Der Cluster ist nun einsatzbereit.
Zur Verwaltung wird kubectl benötigt, nachfolgend die Einrichtung auf MacOS:
MASTER1_IP="192.168.201.1"
brew install kubectl
mkdir ~/.kube
scp root@${MASTER1_IP}:/etc/rancher/k3s/k3s.yaml ~/.kube/config
# Berechtigungen setzen
sudo chown $USER:$USER ~/.kube/config
chmod 600 ~/.kube/config
# IP anpassen, HAProxy IP eintragen
code ~/.kube/config
kubectl get pods --all-namespaces
Load Balancer
- MetalLB ausrollen
METALLB_VERSION=$(curl -s https://api.github.com/repos/metallb/metallb/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/"${METALLB_VERSION}"/config/manifests/metallb-native.yaml
- Warten bis Pods laufen
kubectl wait --namespace metallb-system --for=condition=ready pod -l app=metallb
- IP-Pool konfigurieren
IP_POOL="192.168.202.1-192.168.202.254"
cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: metallb-system
spec:
addresses:
- ${IP_POOL}
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
namespace: metallb-system
spec:
ipAddressPools:
- default-pool
EOF
Test Anwendung ausrollen:
# 1. Nginx Deployment erstellen
kubectl create deployment nginx-test --image=nginx --replicas=2
# 2. Als Service verfügbar machen
kubectl expose deployment nginx-test --port=80 --type=LoadBalancer
# 3. Status prüfen
kubectl get deployments
kubectl get pods -o wide
kubectl get svc nginx-test
Testen via Browser oder curl
EXTERNAL_IP="192.168.202.2"
curl http://"${EXTERNAL_IP}"
Außerdem (by Design) ist die Anwendung auf allen IPs der Master und Agents erreichbar, dort aber nur via NODEPORT.
Test Anwendung entfernen:
kubectl delete service nginx-test
kubectl delete deployment nginx-test