Node Setup und Kubelet
Ziel
In diesem Projekt geht es um das Setup der Kubernetes-Nodes und die Installation von Kubelet. Sie werden:
- Container-Runtime (runc, containerd) auf allen Nodes installieren
- CNI-Plugins für Netzwerk-Funktionalität einrichten
- PKI-Zertifikate für Kubelet-Authentifizierung erstellen
- Kubelet konfigurieren und als systemd-Service starten
- Den Status aller Komponenten überprüfen
Vorbereitung: Multi-Node-Script
-
Erstellen Sie ein Arbeitsverzeichnis und wechseln Sie hinein
cd ~/workspace mkdir node-setup cd node-setup
-
Erstellen Sie ein Helper-Script für die Ausführung auf allen Nodes
cat > run-on-nodes.sh << 'EOF' #!/bin/bash set -e servers=("controlplane-0" "controlplane-1" "controlplane-2" "worker-0" "worker-1") script_path="$1" for server in "${servers[@]}"; do echo "Running script on $server" ssh root@"$server" 'bash -s' < "$script_path" done EOF chmod +x run-on-nodes.sh
Aufgabe 1: Container-Runtime installieren
Runc installieren
-
Erstellen Sie ein Script zur Installation von runc
cat > install-runc.sh << 'EOF' curl -L \ https://github.com/opencontainers/runc/releases/download/v1.3.0/runc.amd64 \ -o /usr/local/bin/runc chmod +x /usr/local/bin/runc echo echo "###" echo "### Installed runc on ${HOSTNAME}. Version:" runc --version echo echo EOF
-
Führen Sie das Script auf allen Nodes aus
./run-on-nodes.sh install-runc.sh
Containerd installieren
-
Erstellen Sie ein Script zur Installation von containerd mit systemd-Integration
cat > install-containerd.sh << 'EOF' # Install containerd curl -L \ https://github.com/containerd/containerd/releases/download/v1.7.28/containerd-1.7.28-linux-amd64.tar.gz \ -o /tmp/containerd.tar.gz tar -xvf /tmp/containerd.tar.gz -C /usr/local echo echo "###" echo "### Installed containerd on ${HOSTNAME}. Version:" containerd --version echo # Containerd Systemd unit file mkdir -p /usr/local/lib/systemd/system/ wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -O /usr/local/lib/systemd/system/containerd.service echo "### Installed containerd systemd unit file." echo # Containerd Config File mkdir -p /etc/containerd containerd config default | sed 's/SystemdCgroup = false/SystemdCgroup = true/' > /etc/containerd/config.toml echo "### Created containerd config file." echo systemctl daemon-reload systemctl enable --now containerd echo echo "###" echo "### Enabled containerd on ${HOSTNAME}." echo echo "### Containerd Status on Node $HOSTNAME" systemctl status containerd | grep -oP "(?<=Active: )(.*)" echo # Install CRICTL for container debugging VERSION="v1.30.0" curl -L https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-${VERSION}-linux-amd64.tar.gz --output crictl-${VERSION}-linux-amd64.tar.gz tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin rm -f crictl-$VERSION-linux-amd64.tar.gz echo echo "###" echo "### Installed crictl on ${HOSTNAME}. Version:" crictl --version echo echo EOF
-
Führen Sie das Script auf allen Nodes aus
./run-on-nodes.sh install-containerd.sh
CNI-Plugins installieren
-
Erstellen Sie ein Script zur Installation der CNI-Plugins
cat > install-cni-plugins.sh << 'EOF' mkdir -p /opt/cni/bin curl -L \ https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz \ -o /tmp/cni-plugins.tgz tar -xvf /tmp/cni-plugins.tgz -C /opt/cni/bin echo echo "###" echo "### Installed Network Plugins on ${HOSTNAME}." echo echo EOF
-
Führen Sie das Script auf allen Nodes aus
./run-on-nodes.sh install-cni-plugins.sh
Aufgabe 2: PKI für Kubelet einrichten
Root-CA erstellen
-
Wechseln Sie in ein PKI-Verzeichnis
cd ../ mkdir pki cd pki
-
Erstellen Sie eine CA-Konfigurationsdatei
cat > ca.cnf << 'EOF' # ca.cnf [ req ] distinguished_name = dn x509_extensions = ca_ext prompt = no [ dn ] C = DE O = Corewire GmbH CN = Corewire Kubernetes Root CA [ ca_ext ] basicConstraints = CA:true # Allows: # keyCertSign = Signieren von Zertifikaten # cRLSign = Signieren von Sperrlisten keyUsage = keyCertSign, cRLSign EOF
-
Erstellen Sie das Root-Zertifikat
# Privaten Schlüssel erzeugen openssl genrsa -out ca.key 4096 # Root-Zertifikat erstellen openssl req -new -x509 -sha512 -days 3650 \ -key ca.key \ -out ca.crt \ -config ca.cnf # Details anzeigen openssl x509 -in ca.crt -text -noout
-
Kopieren Sie das CA-Zertifikat auf alle Nodes
for instance in controlplane-0 controlplane-1 controlplane-2 worker-0 worker-1; do echo "## Copying CA cert to ${instance}" ssh ${instance} "mkdir -p /etc/kubernetes/pki" scp ./ca.crt ${instance}:/etc/kubernetes/pki/ca.crt done
Aufgabe 3: Kubelet-Zertifikate und Kubeconfig erstellen
-
Wechseln Sie zurück ins node-setup Verzeichnis und erstellen Sie ein config-Unterverzeichnis
cd ../node-setup mkdir config cd config
Template-Dateien erstellen
-
Erstellen Sie ein Template für die Kubelet-Client-Zertifikate
cat > kubelet-client.cnf.tmpl << 'EOF' # kubelet-client.cnf [ req ] distinguished_name = dn req_extensions = client_ext prompt = no [ dn ] CN = system:node:${NODE_NAME} O = system:nodes [ client_ext ] basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF
-
Erstellen Sie ein Template für die Kubelet-Kubeconfig
cat > kubelet-kubeconfig.yaml.tmpl << 'EOF' apiVersion: v1 clusters: - cluster: certificate-authority: /etc/kubernetes/pki/ca.crt server: https://${CONTROLPLANE_IP}:6443 name: kubernetes contexts: - context: cluster: kubernetes user: system:node:${NODE_NAME} name: default current-context: default kind: Config preferences: {} users: - name: system:node:${NODE_NAME} user: client-certificate: /etc/kubernetes/pki/kubelet-client.crt client-key: /etc/kubernetes/pki/kubelet-client.key EOF
Script für Zertifikat-Generierung
-
Erstellen Sie ein Script, das für jeden Node Zertifikate und Kubeconfig generiert
cat > generate-kubelet-certs-and-kubeconfig.sh << 'EOF' #!/bin/bash set -euo pipefail mkdir -p ./kubelet export CA_PATH=../../pki for instance in controlplane-0 controlplane-1 controlplane-2 worker-0 worker-1; do echo "## Running for ${instance}" echo "### Generating key" openssl genrsa -out ./kubelet/${instance}.key 4096 echo "### Generating CNF" export NODE_NAME=${instance} cat ./kubelet-client.cnf.tmpl | envsubst > ./kubelet/${instance}.cnf echo "### Generating CSR" openssl req -new -sha512 \ -key "./kubelet/${instance}.key" \ -out "./kubelet/${instance}.csr" \ -config "./kubelet/${instance}.cnf" echo "### Generating Cert" openssl x509 -req -days 365 -sha512 \ -in "./kubelet/${instance}.csr" \ -out "./kubelet/${instance}.crt" \ -CA "${CA_PATH}/ca.crt" -CAkey "${CA_PATH}/ca.key" -CAcreateserial \ -copy_extensions copyall echo "### Generating Kubeconfig" if [[ ${instance} == controlplane-* ]] then echo "#### Setting CONTROLPLANE_IP to 127.0.0.1 for controlplane nodes" export CONTROLPLANE_IP=127.0.0.1 else export CONTROLPLANE_IP=$(ssh -G controlplane-0 | awk '/^hostname /{print $2}') echo "#### Setting CONTROLPLANE_IP to controlplane-0 (${CONTROLPLANE_IP}) for worker nodes" fi cat ./kubelet-kubeconfig.yaml.tmpl | envsubst > ./kubelet/${instance}-kubeconfig.yaml echo "### Copying certs and keys to ${instance}" scp ./kubelet/${instance}.crt ${instance}:/etc/kubernetes/pki/kubelet-client.crt scp ./kubelet/${instance}.key ${instance}:/etc/kubernetes/pki/kubelet-client.key echo "### Copying kubeconfig to ${instance}" scp ./kubelet/${instance}-kubeconfig.yaml ${instance}:/etc/kubernetes/kubelet-kubeconfig.yaml done EOF chmod +x generate-kubelet-certs-and-kubeconfig.sh
-
Führen Sie das Script aus
bash generate-kubelet-certs-and-kubeconfig.sh
Aufgabe 4: Kubelet-Konfiguration
Kubelet-Config erstellen
-
Erstellen Sie eine Kubelet-Konfigurationsdatei
cat > kubelet-config.yaml << 'EOF' apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false webhook: cacheTTL: 0s enabled: true x509: clientCAFile: /etc/kubernetes/pki/ca.crt authorization: mode: Webhook webhook: cacheAuthorizedTTL: 0s cacheUnauthorizedTTL: 0s cgroupDriver: systemd clusterDNS: - 10.96.0.10 clusterDomain: cluster.local containerRuntimeEndpoint: unix:///var/run/containerd/containerd.sock cpuManagerReconcilePeriod: 0s crashLoopBackOff: {} evictionPressureTransitionPeriod: 0s fileCheckFrequency: 0s healthzBindAddress: 127.0.0.1 healthzPort: 10248 httpCheckFrequency: 0s imageMaximumGCAge: 0s imageMinimumGCAge: 0s kind: KubeletConfiguration logging: flushFrequency: 0 options: json: infoBufferSize: "0" text: infoBufferSize: "0" verbosity: 0 memorySwap: {} nodeStatusReportFrequency: 0s nodeStatusUpdateFrequency: 0s resolvConf: /run/systemd/resolve/resolv.conf rotateCertificates: true runtimeRequestTimeout: 0s shutdownGracePeriod: 0s shutdownGracePeriodCriticalPods: 0s staticPodPath: /etc/kubernetes/manifests streamingConnectionIdleTimeout: 0s syncFrequency: 0s volumeStatsAggPeriod: 0s EOF
-
Kopieren Sie die Konfiguration auf alle Nodes
for instance in controlplane-0 controlplane-1 controlplane-2 worker-0 worker-1; do echo "## Copying kubelet config to ${instance}" scp ./kubelet-config.yaml ${instance}:/etc/kubernetes/kubelet-config.yaml done
Systemd Unit File erstellen
-
Erstellen Sie ein systemd Unit File für den Kubelet
cat > kubelet.service << 'EOF' [Unit] Description=kubelet Documentation=https://github.com/kubernetes/kubernetes After=containerd.service Requires=containerd.service [Service] ExecStart=/usr/bin/kubelet \ --config=/etc/kubernetes/kubelet-config.yaml \ --kubeconfig=/etc/kubernetes/kubelet-kubeconfig.yaml \ --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \ --v=2 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF
-
Kopieren Sie das Unit File auf alle Nodes
for instance in controlplane-0 controlplane-1 controlplane-2 worker-0 worker-1; do echo "## Copying kubelet systemd unit file to ${instance}" scp ./kubelet.service ${instance}:/etc/systemd/system/kubelet.service done
Aufgabe 5: Kubelet installieren und starten
-
Wechseln Sie zurück ins node-setup Verzeichnis
cd ..
-
Erstellen Sie ein Script zur Installation des Kubelet
cat > install-kubelet.sh << 'EOF' apt-get update apt-get install -y apt-transport-https ca-certificates curl gpg curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key \ | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /' \ | sudo tee /etc/apt/sources.list.d/kubernetes.list apt-get update apt install -y kubelet systemctl daemon-reload systemctl start kubelet echo echo "###" echo "### Installed kubelet on ${HOSTNAME}." echo echo echo "### Kubelet Status on Node $HOSTNAME" systemctl status kubelet | grep -oP "(?<=Active: )(.*)" echo EOF
-
Führen Sie das Script auf allen Nodes aus
./run-on-nodes.sh install-kubelet.sh
Aufgabe 6: Status überprüfen
-
Erstellen Sie ein Script zur Statusüberprüfung
cat > status.sh << 'EOF' echo echo "### Status on Node $HOSTNAME" STATUS=$( { systemctl status containerd | grep -oP "(?<=Active: )(.*)"; } 2>&1 ) echo "containerd: $STATUS" STATUS=$( { systemctl status kubelet | grep -oP "(?<=Active: )(.*)"; } 2>&1 ) echo "kubelet: $STATUS" echo EOF
-
Führen Sie das Script aus, um den Status aller Services zu überprüfen
./run-on-nodes.sh status.sh
Aufgabe 7: Troubleshooting (Optional)
-
Überprüfen Sie die Kubelet-Logs auf einem Node
ssh controlplane-0 "journalctl -u kubelet -f"
-
Testen Sie die Container-Runtime
ssh worker-0 "crictl version" ssh worker-0 "crictl info"
-
Überprüfen Sie, ob die Static Pod-Manifests-Verzeichnisse existieren
ssh controlplane-0 "ls -la /etc/kubernetes/manifests"
Ausblick
Nach Abschluss dieser Aufgabe haben Sie eine vollständige Node-Infrastruktur mit Container-Runtime und Kubelet aufgebaut. Die Nodes sind bereit, um mit der Control Plane verbunden zu werden. Im nächsten Schritt würden Sie die Control Plane-Komponenten (API-Server, Controller Manager, Scheduler) als Static Pods oder systemd-Services installieren.
Hinweis
Der Kubelet wird momentan noch Fehler zeigen, da keine Control Plane verfügbar ist. Das ist normal und wird sich ändern, sobald der API-Server gestartet wird.