Host einrichten

Mit Arch Linux lässt sich schnell ein Kubernetes Server einrichten. An dieser Stelle geht es nur um die Einrichtung des Betriebssystemes, so dass dort eine Kubernetes Control-Plane oder ein Worker eingerichtet werden kann. Zunächst wird Arch mit btrfs eingerichtet, gegenüber der Installationsanleitung sind folgende Abweichungen sinnvoll:

btrfs subvolume create /mnt/root
for i in var usr home tmp; do btrfs subvolume create /mnt/root/$i; done
btrfs subvolume list /mnt
ID 271 gen 57 top level 5 path root
ID 276 gen 54 top level 271 path root/var
ID 277 gen 55 top level 271 path root/usr
ID 278 gen 56 top level 271 path root/home
ID 279 gen 57 top level 271 path root/tmp
mount /dev/nvme0n1p3 /mnt/root -o subvol=root,subvolid=271
mount /dev/nvme0n1p3 /mnt/root/var -o subvol=root/var,subvolid=276
mount /dev/nvme0n1p3 /mnt/root/usr -o subvol=root/usr,subvolid=277
mount /dev/nvme0n1p3 /mnt/root/home -o subvol=root/home,subvolid=278
mount /dev/nvme0n1p3 /mnt/root/tmp -o subvol=root/tmp,subvolid=279
mount /dev/nvme0n1p2 /mnt/root/boot
mount /dev/nvme0n1p1 /mnt/root/boot/efi
pacstrap -K /mnt/root base linux linux-firmware
genfstab -U /mnt/root >> /mnt/root/etc/fstab
arch-chroot /mnt/root
pacman -S btrfs-progs

Ansonsten die übliche Prozedur zu Installation. Man bekommt so eine Installation, bei der Kubernetes von btrfs profitieren kann und das Root Filesystem in einem btrfs Subvolume liegt.

Hardware

Sowohl Control Planes, als auch Worker stellen an die Hardware keine all zu hohen Anforderungen. Bei den Workern sollte Wert auf eine solide Server-Hardware, CPU und (ECC)RAM gelegt werden. Ansonsten reicht eine 20GB SSD als lokaler Storage. So ist immer sichergestellt, dass möglichst viele Nodes starten können. Ein zentraler Storage für das System bildet immer einen Single-Point-Of-Failure. Es sollte weiterhin auf alles Nodes die gleiche CPU Architektur verwendet werden. Ein Mix von z.B. x86 und ARM ist nicht zu empfehlen. Bei den Workern gilt die Regel "mehr CPU Cores und mehr RAM" ohne Einschränkung. Bei den Control Planes sollten mindestens 4 CPU Cores und 16 GByte RAM vorhanden sein.

Netzwerk

Sowohl Worker, als auch Control Planes sollten jeweils redundant angebunden werden. Grundsätzlich sollten immer zwei Ethernet Ports mit 802.1ad verwendet werden. Weniger als 1GBit/s pro Port sollten es nicht sein, bei größeren Installationen können auch 100GBit/s pro Port sinnvoll sein.

Damit Kubernetes funktioniert muss noch die Datei /etc/modules-load.d/br_netfilter.conf mit dem Inhalt br_netfilter erstellt werden.

IP-Forwarding brauchen wir auch noch:

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

Mit sysctl --system wird das aktiviert.

iptables

Kubernetes kümmert sich sehr gut um das Firewalling seiner eigenen Prozesse. Die Network Policies gelten allerdings nur für die Kubernetes Infrastruktur und Pods. Services, die auf dem Host laufen, bleiben erreichbar, was unter Umständen einen Ausbruch auf den Host erlaubt. Bei einem Preset von iptables muss man sehr vorsichtig vorgehen, damit Kubernetes auch weiterhin funktioniert. Auf dem Host sollte neben Kubernetes maximal noch ein sshd laufen. Mit dem folgenden iptables Ruleset in /etc/sysconfig/iptables kann man den Zugriff von Pods auf sshd unterbinden:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i enp0s3 -s 192.168.56.0/24 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j REJECT

COMMIT

Damit das Ruleset beim Boot auch geladen wird, muss noch ein Systemd Service eingerichtet werden, dazu wird die Datei /etc/systemd/system/iptables.service erstellt:

[Unit]
Description=Restore iptables rules on boot
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/sbin/iptables-restore /etc/sysconfig/iptables

[Install]
WantedBy=multi-user.target

Mit systemctl daemon-reload && systemctl enable iptables wird das aktiviert. Nach einem Reboot wird das Ruleset aktiviert und Kubernetes kann ungestört seine eigenen Rulesets ergänzen.

containerd

Mit containerd config default | tee /etc/containerd/config.toml wird ein Config File für den containerd erzeugt.

In der Datei config.toml ist im Abschnitt [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] noch SystemdCgroup = true zu setzen.

Nun noch den containerd mit systemctl restart containerd neu starten.

DNS

Ganz wichtig: Die /etc/hosts muss für die erste Control Plane alles sauber auflösen, sind sind jede Menge Probleme garantiert:

# Static table lookup for hostnames.
# See hosts(5) for details.

127.0.0.1 localhost
192.168.3.16 k8s.example.com k8s

Mit hostnamectl set-hostname "k8s" wird der Hostname gesetzt.

 

Kubernetes

Für Arch gibt es fertige Pakete für Kubernetes, mit pacman -S kubelet kubeadm kubectl wird alles nötige installiert.

Mit kubeadm init erfolgt jetzt die Installation von Kubernetes.

 

Virtualisierung

Sollte man Kubernetes Nodes virtualisieren?

Bei dieser Frage gehen die Meiungen z.T. sehr auseinander - wie so oft ist die Antwort "Es kommt darauf an" zutreffend. Befürworter von Virtualisierung führen gerne die Snapshotmöglichkeit an, die meist dann hilfreich ist, wenn ein Update nicht geklappt hat.

Die Mischung macht es

In einer Beispielinstallation hat sich folgende Architektur als sinnvoll erwiesen:

  • 2 Control-Planes virtualisiert, z.B. libvirt/kvm
  • 3 Control Planes als Hardware
  • 4 Worker virtualisiert wegen Zugriff auf Storage der VM Lösung
  • 10 Worker als Hardware

Alle Komponenten werden mit mindestens 2 Ethernet Ports mit dem Netzwerk verbunden. An der Stelle soll noch der Hinweis erlaubt sein, dass Arch auch Infiniband unterstützt.