Control-Plane

Die Kubernetes Installation erfordert zu Beginn einige Überlegungen zur Architektur. Aufgrund der einfachen Einrichtung und den geringen Hardwarekosten sollte von Beginn an eine redundante Konfiguration der Control-Planes in Betracht gezogen werden. Im Zweifel tun es für Tests schon zwei Raspberries (Model 4b/8GB RAM). Im Produktionsumfeld sollte jedoch unbedingt eine qualitativ hochwertige Serverhardware verwendet werden. Für die Control-Planes ist auch eine Virtualisierung (z.B. QEMU/KVM) sinnvoll. Die erste Kubernetes Komponente wird erst nach der Installation von Haproxy installiert.

Aufräumen

Falls auf dem Node noch die Reste eines alten Versuchs mit Kubernetes liegt, dann muss die erst einmal rückstandsfrei entfernt werden.

kubeadm reset && rm -rf /etc/cni/net.d && reboot

Der Reboot ist notwendig, damit ggf. noch alte iptables oder Routing Einträge verschwinden.

Quick and Dirty

Wer schnell ein Kubernetes ohne Sonderwünsche haben will, kann direkt mit kubicctl init ein schlüsselfertiges System erzeugen. Werden Anpassungen gewünscht, wie z.B. ein anderes SDN (Calico), dann sollte stattdessen mit dem nächsten Abschnitt weiter gemacht werden.

Erste Control Plane

Jetzt wird unter Einbeziehung des Load-Balancers der Master Node erstellt. Die IP-Adresse 192.168.1.254 ist hier die IP-Adresse des haproxy auf der Firewall.

kubeadm init --control-plane-endpoint=kubeadm.example.com:6443 --upload-certs | tee kubeadm.log

In der Datei kubeadm.log wird das Output für die weitere Verwendung gespeichert. Noch haben wir aber noch keine funktionierende Kubernetes Installation, es fehlt noch ein Netzwerk. Dieses wird mit

kubectl apply -f /usr/share/k8s-yaml/weave/weave.yaml

ergänzt. Statt Weave kann für das Netzwerk auch Calico verwendet werden. Welche Netzwerklösung für Kubernetes am besten geeignet ist, hängt letztlich von der geplanten Architektur ab. Auf jeden Fall sollte darauf geachtet werden, dass die Netzwerklösung auch Kubernetes Policies unterstützt. Das ist bei Weave, Calico und einigen anderen Lösungen der Fall.

Test Master

Kubernetes ist ein sehr komplexes System, daher muss jeder Schritt getestet werden, aber auch da hilft Kubernetes. Wichtig ist hier der Status running, ein anderer Status wiest auf einen Fehler hin. Der Status running kommt bei einigen Services erst nach der Installation von Weave.

kube1:~ # kubectl get pods --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-76679c6978-ndmj4 1/1 Running 0 78m 10.32.0.2 kube1 <none> <none>
kube-system coredns-76679c6978-xk26x 1/1 Running 0 78m 10.32.0.3 kube1 <none> <none>
kube-system etcd-kube1 1/1 Running 0 78m 192.168.1.16 kube1 <none> <none>
kube-system kube-apiserver-kube1 1/1 Running 0 78m 192.168.1.16 kube1 <none> <none>
kube-system kube-controller-manager-kube1 1/1 Running 3 78m 192.168.1.16 kube1 <none> <none>
kube-system kube-proxy-pk5qx 1/1 Running 0 78m 192.168.1.16 kube1 <none> <none>
kube-system kube-scheduler-kube1 1/1 Running 3 78m 192.168.1.16 kube1 <none> <none>
kube-system weave-net-qkkxr 2/2 Running 0 76m 192.168.1.16 kube1 <none> <none>

kube1:~ # kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kube1 Ready master 116m v1.19.4 192.168.1.16 <none> openSUSE MicroOS 5.9.11-1-default cri-o://1.19.0

Nun hat man eine lauffähige Kubernetes Control-Plane und dem Aufbau der Cloud steht nichts mehr im Wege.

Zweite und dritte Control Plane

Für einen redundanten Betrieb werden mindestens 3 Control-Planes benötigt, davon darf dann Eine ausfallen. Im produktiven Betrieb sind mindestens 5 Control Planes zu empfehlen.

Jetzt kann mit einem speziellen Join die Integration der zweiten Control Plane erfolgen. Das genaue Kommando dafür ist in der Datei kubeadm.log zu finden, die im Rahmen der Installation der ersten Control Plane entstanden ist.

    kubeadm join 192.168.1.254:6443 --token re86z7.*** --discovery-token-ca-cert-hash sha256:*** --control-plane --certificate-key ***

Falls die Tokens für den Join nicht mehr verfügbar sind (diese laufen meist nach kurzer Zeit schon ab), dann kann man sich einach mit

    kubeadm token create --print-join-command

einen neuen Tokensatz erzeugen. Den Certificate Key kann man sich im Zweifelsfall mit

    kubeadm init phase upload-certs --upload-certs

beschaffen.

Test

Nach ein paar Minuten sollten sollten anderen Control Planes sichtbar sein:

kube1:~ # kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kube1 Ready master 25h v1.19.4 192.168.1.16 <none> openSUSE MicroOS 5.9.12-1-default cri-o://1.19.0
kubic-pi1 Ready master 24h v1.19.4 192.168.1.15 <none> openSUSE MicroOS 5.9.12-1-default cri-o://1.19.0
kubic3 Ready master 22h v1.19.4 192.168.1.23 <none> openSUSE MicroOS 5.9.12-1-default cri-o://1.19.0


Status

Mit den Komponenten

  • OPNsense Firewall/Haproxy
  • Kubernetes

haben wir jetzt eine redundante Control Plane. Auf den Control Planes können aber noch keine Container ausgeführt werden. Das ist aus Sicherheitsgründen so gewollt und auch eine Default Einstellung. Diese sollte auch nicht geändert werden.

Security

Das Perimeter Konzept sollte hier noch Anwendung finden. Die Control Planes sollten in einem gesonderten Netzsegment laufen, auf das nur via Firewall zugegriffen werden kann. Kubernetes enthält auch eine komplette PKI Lösung. Dessen sollte man sich bewusst sein. Die Zertifikate dieser PKI sollten in das Monitoring aufgenommen werden, denn wenn ein Zertifikat unbemerkt abläuft, dann steht evtl. die ganze Kubernetes Installation.

Aus Sicherheitsgründen kann man auf einer Control Plane keine Pods starten. Zum Experimentieren und Entwickeln kann man dieses Feature abschalten mit

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

so dass man auch auf einem "Full Featured" Kubernetes entwickeln kann.