CRI-O Kubernetes Worker Setup auf Arch Linux ARM
Nachdem im vorherigen Beitrag zu Kubernetes gezeigt wurde, wie mittels CRI-O ein Kubernetes Master Node eingerichtet wird, folgt nun eine Worker Node. Das besondere auch hier: Es wird Arch Linux auf ARM 64bit Architektur verwendet.
Für das Setup wird kubeadm verwendet, daher wird auch die Ausgabe von einem Kubernetes-Master Setup benötigt, da dort das erforderliche Token ausgeben wird.
You can now join any number of machines by running the following on each node
as root:
kubeadm join 10.23.15.110:6443 --token nnnxv2.2p7n2zwuddqedg25 --discovery-token-ca-cert-hash sha256:7563bc0dcf826a37e96f820725147a61d9970a094e1428832283f803aad91cd3
Auf den Worker Nodes werden jeweils die folgenden Pakete installiert:
-
runc
-
runc-1.0.0rc5-1-aarch64.pkg.tar.xz
-
-
CRI-O
-
crictl-bin-1.11.1-1-aarch64.pkg.tar.xz
-
cri-o-1.11-1-aarch64.pkg.tar.xz
-
-
CNI
-
cni-0.6.0-2-aarch64.pkg.tar.xz
-
cni-plugins-0.6.0-1-aarch64.pkg.tar.xz
-
-
Kubernetes
-
kubernetes-1.11.1-1-aarch64.pkg.tar.xz
-
-
socat, ethtool, ebtables
$ sudo pacman -U *xz
loading packages...
resolving dependencies...
looking for conflicting packages...
Packages (6) cni-0.6.0-2 cni-plugins-0.6.0-1 cri-o-1.11-1 crictl-bin-1.11.1-1 kubernetes-1.11.1-1 runc-1.0.0rc5-1
Total Installed Size: 808.83 MiB
Net Upgrade Size: 83.65 MiB
:: Proceed with installation? [Y/n]
...
:: Running post-transaction hooks...
(1/3) Reloading system manager configuration...
(2/3) Creating temporary files...
(3/3) Arming ConditionNeedsUpdate...
Für Kubernetes werden noch weitere Pakete benötigt:
$ sudo pacman -S socat ethtool ebtables
resolving dependencies...
looking for conflicting packages...
Packages (3) ebtables-2.0.10_4-6 ethtool-1:4.17-1 socat-1.7.3.2-2
Total Download Size: 0.30 MiB
Total Installed Size: 1.11 MiB
:: Proceed with installation? [Y/n]
...
Danach wird zunächst die CRI-O Konfiguration vorgenommen, anschließend kann dann kubelet eingerichtet werden.
Als nächstes wird danach kubelet konfiguriert und aktiviert.
CRI-O Konfiguration
Zuerst die CRI-O Konfiguration: CRI-O verhält sich in einigen Punkten anders, als Docker. So muss zwingend konfiguriert werden, von wo CRI-O nicht signierte Images beziehen darf. Um das Standardverhalten von Docker nachzubilden, kann die folgende Image-Policy verwendet werden.
/etc/containers/policy.json
$ mkdir /etc/containers
$ echo '
{
"default": [{"type": "insecureAcceptAnything"}]
}' > /etc/containers/policy.json
Weitere Einstellungen werden in der /etc/crio/crio.conf
vorgenommen:
-
CRI-O kann flexibel mit mehreren Registries konfiguriert werden, die verwendet werden, falls ein unqualifizierter Image-Nanme verwendet wird. Analog zum Verhalten von Docker soll
docker.io
verwendet werden. -
Für die Netzwerkkonfiguration wird CNI verwendet, der richtige Pfad für die Binaries ist
/opt/cni/bin
. -
Durch CRI-O sollen keine Mounts angelegt werden, dies wird fallweise durch kubelet später durchgeführt
Die CRI-O Settings sehen dann wie folgt aus:
/etc/crio/crio.conf
registries = ['docker.io']
plugin_dir = "/opt/cni/bin"
#default_mounts = [
# "/run/secrets",
#]
Nachdem die CRI-O Konfiguration vollständig ist, kann der CRI-O Dienst aktiviert und gestartet werden.
$ sudo systemctl enable crio
Created symlink /etc/systemd/system/multi-user.target.wants/crio.service -> /usr/lib/systemd/system/crio.service.
$ sudo systemctl start crio
kubelet Konfiguration
Die reguläre systemd-Unit für kubelet deklariert eine Abhängigkeit auf Docker.
Diese wird entsprechend auf CRI-O geändert.
Damit während der Bootstrap-Phase der kubelet Dienst nicht von systemd als fehlerhaft markiert wird, soll systemd lediglich im Abstand einer Minute einen Neustart versuchen.
Nach einigen Versuchen wird kubeadm
die erforderliche kubelet Konfiguration erzeugt haben, so dass ein Start gelingt.
Mit systemctl edit --full kubelet
kann die Konfiguration angepasst werden.
[Unit]
After=crio.service
Requires=crio.service
[Service]
RestartSec=60
Für den kube-proxy werden privilegierte Container erzeugt.
Damit kubelet mit --allow-privileged=true
startet, muss dies in der /etc/kubernetes/config
eingestellt werden.
An dieser Stelle wird auf die Konfiguration der API-Server-URL verzichtet, dies wird kubeadm später in einer generierten Konfigurationsdatei mitteilen.
/etc/kubernetes/config
KUBE_ALLOW_PRIV="--allow-privileged=true"
KUBE_MASTER=""
Weitere Einstellungen werden in der /etc/kubernetes/kubelet
Konfigurationsdatei vorgenommen:
-
Der Hostname des Knotens soll automatisch bestimmt werden, darum wird der entsprechende Parameter leer gelassen
-
Als Konfiguration für kubelet wird die Datei
/etc/kubernetes/kubelet.conf
angegeben, außerdem wird der Pfad zur Bootstrap-Konfiguration gesetzt (kubeadm wird diese dann später erzeugen). -
Damit CRI-O verwendet wird, muss noch die Container-Runtime auf
remote
und der entsprechende Socket-Pfad gesetzt werden
/etc/kubernetes/kubelet
KUBELET_HOSTNAME=""
KUBELET_KUBECONFIG="--kubeconfig=/etc/kubernetes/kubelet.conf --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf"
KUBELET_ARGS="--cluster-domain=cluster.local --cluster-dns=10.96.0.10 --cgroup-driver=systemd --fail-swap-on=false --network-plugin=kubenet --container-runtime=remote --container-runtime-endpoint=unix:///var/run/crio/crio.sock"
Die kubelet Konfiguration ist abgeschlossen, sodass der Dienst aktiviert werden kann. Gestartet wird kubelet noch nicht, das übernimmt kubeadm später.
$ sudo systemctl enable kubelet.service
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service -> /usr/lib/systemd/system/kubelet.service.
Bevor es losgehen kann, wird im Kernel noch IP-Forwarding aktiviert. Das ist wichtig, damit die Netzwerkkommunikation der Pods später funktioniert.
$ echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/30-ipforward.conf
Nun muss der Rechner entweder neu gestartet werden, oder durch ein manuelles sudo sysctl net.ipv4.ip_forward=1
das IP-Forwarding aktiviert werden.
Kubernetes Cluster Beitritt
Auf den Cluster-Nodes ist Swapspeicher aktiviert, daher wird kubeadm angewiesen, diesen bei der Verifizierung der Umgebung zu akzeptieren. Damit statt Docker CRI-O als Container Engine verwendet wird, muss der Pfad zum CRI-Socket auch bei kubeadm spezifiziert werden.
$ sudo kubeadm join 10.23.15.110:6443 --ignore-preflight-errors Swap --cri-socket=/var/run/crio/crio.sock --token nnnxv2.2p7n2zwuddqedg25 --discovery-token-ca-cert-hash sha256:7563bc0dcf826a37e96f820725147a61d9970a094e1428832283f803aad91cd3
[WARNING Swap]: running with swap on is not supported. Please disable swap
I0729 18:37:32.057489 595 kernel_validator.go:81] Validating kernel version
I0729 18:37:32.057981 595 kernel_validator.go:96] Validating kernel config
[discovery] Trying to connect to API Server "10.23.15.110:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.23.15.110:6443"
[discovery] Requesting info from "https://10.23.15.110:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "10.23.15.110:6443"
[discovery] Successfully established connection with API Server "10.23.15.110:6443"
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.11" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[preflight] Activating the kubelet service
[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
[patchnode] Uploading the CRI Socket information "/var/run/crio/crio.sock" to the Node API object "c2-worker2" as an annotation
This node has joined the cluster:
* Certificate signing request was sent to master and a response
was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
Kubernetes Overlay Network
Damit ein virtuelles Netzwerk für die Pods zur Verfügung steht, fehlt lediglich noch ein entsprechendes Overlay-Network. Auf dem Master kann dazu folgendes Kommando ausgeführt werden, um Weave als Container-Netzwerk zu installieren:
$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&env.WEAVE_NO_FASTDP=1"
serviceaccount/weave-net configured
clusterrole.rbac.authorization.k8s.io/weave-net created
clusterrolebinding.rbac.authorization.k8s.io/weave-net created
role.rbac.authorization.k8s.io/weave-net created
rolebinding.rbac.authorization.k8s.io/weave-net created
daemonset.extensions/weave-net created
Hier wird der Fast-Data-Path bei Weave deaktiviert, da dies auf einigen ARM Maschinen zu einer Kernel-Panic führt. In neueren Linux-Kernelversionen soll der Fehler behoben werden, dann ist mit weniger CPU-Belastung eine höhere Geschwindigkeit mit Weave zu erzielen.
Zu den Themen Kubernetes, Docker und Cloud Architektur bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:
Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.