Control Plane Setup
Ziel
In diesem Projekt geht es um das Setup der Kubernetes Control Plane-Komponenten. Sie werden:
- PKI-Zertifikate für API-Server, etcd-Client und Kubelet-Client erstellen
- Kube-API-Server als Static Pod konfigurieren und starten
- Admin-Kubeconfig für Cluster-Zugriff erstellen
- Kube-Scheduler als Static Pod einrichten
- Kube-Controller-Manager als Static Pod konfigurieren
- Control Plane finalisieren und Nodes verwalten
Vorbereitung
-
Wechseln Sie ins workspace-Verzeichnis und erstellen Sie ein API-Server-Verzeichnis
cd ~/workspace mkdir apiserver cd apiserver
Aufgabe 1: API-Server-Zertifikate erstellen
Zertifikat-Konfigurationsdateien
-
Erstellen Sie eine Template-Datei für das API-Server-Zertifikat
cat > apiserver.cnf.tmpl << 'EOF' # apiserver.cnf [ req ] distinguished_name = dn req_extensions = server_ext prompt = no [ dn ] C = DE O = Corewire GmbH CN = kube-apiserver [ server_ext ] basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP:${IP_CONTROLPLANE_0}, IP:${IP_CONTROLPLANE_1}, IP:${IP_CONTROLPLANE_2}, IP:127.0.0.1, IP:10.96.0.1 EOF
-
Erstellen Sie eine Konfigurationsdatei für das API-Server-etcd-Client-Zertifikat
cat > apiserver-etcd-client.cnf << 'EOF' [ req ] distinguished_name = dn req_extensions = client_ext prompt = no [ dn ] C = DE O = Corewire GmbH CN = kube-apiserver-etcd-client [ client_ext ] basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF
-
Erstellen Sie eine Konfigurationsdatei für das API-Server-Kubelet-Client-Zertifikat
cat > apiserver-kubelet-client.cnf << 'EOF' [ req ] distinguished_name = dn req_extensions = client_ext prompt = no [ dn ] C = DE O = kubeadm:cluster-admins CN = kube-apiserver-kubelet-client [ client_ext ] basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF
Script für Zertifikat-Generierung
-
Erstellen Sie ein Script zur automatischen Generierung aller API-Server-Zertifikate
cat > generate-apiserver-certificates.sh << 'EOF' #!/bin/bash set -euo pipefail export IP_CONTROLPLANE_0=$(ssh -G controlplane-0 | awk '/^hostname /{print $2}') export IP_CONTROLPLANE_1=$(ssh -G controlplane-1 | awk '/^hostname /{print $2}') export IP_CONTROLPLANE_2=$(ssh -G controlplane-2 | awk '/^hostname /{print $2}') mkdir -p pki echo "### Generating apiserver.cnf from apiserver.cnf.tmpl" envsubst < apiserver.cnf.tmpl > apiserver.cnf echo "### Generating apiserver certificate and key" # Privaten Schlüssel erzeugen openssl genrsa -out pki/apiserver.key 4096 # Certificate Signing Request erstellen openssl req -new -sha512 \ -key "pki/apiserver.key" \ -out "pki/apiserver.csr" \ -config "apiserver.cnf" # Zertifikat erstellen openssl x509 -req -days 365 -sha512 \ -in "pki/apiserver.csr" \ -out "pki/apiserver.crt" \ -CA "../pki/ca.crt" -CAkey "../pki/ca.key" -CAcreateserial \ -copy_extensions copyall echo "### Generating apiserver-etcd-client certificate and key" # Privaten Schlüssel erzeugen openssl genrsa -out pki/apiserver-etcd-client.key 4096 # Certificate Signing Request erstellen openssl req -new -sha512 \ -key "pki/apiserver-etcd-client.key" \ -out "pki/apiserver-etcd-client.csr" \ -config "apiserver-etcd-client.cnf" # Zertifikat erstellen openssl x509 -req -days 365 -sha512 \ -in "pki/apiserver-etcd-client.csr" \ -out "pki/apiserver-etcd-client.crt" \ -CA "../pki/etcd/ca.crt" -CAkey "../pki/etcd/ca.key" -CAcreateserial \ -copy_extensions copyall echo "### Generating apiserver-kubelet-client certificate and key" # Privaten Schlüssel erzeugen openssl genrsa -out pki/apiserver-kubelet-client.key 4096 # Certificate Signing Request erstellen openssl req -new -sha512 \ -key "pki/apiserver-kubelet-client.key" \ -out "pki/apiserver-kubelet-client.csr" \ -config "apiserver-kubelet-client.cnf" # Zertifikat erstellen openssl x509 -req -days 365 -sha512 \ -in "pki/apiserver-kubelet-client.csr" \ -out "pki/apiserver-kubelet-client.crt" \ -CA "../pki/ca.crt" -CAkey "../pki/ca.key" -CAcreateserial \ -copy_extensions copyall echo "### Generating SA key and public key" # Service Account Schlüssel erzeugen (4096 Bit) openssl genrsa -out pki/sa.key 4096 # Öffentlichen Schlüssel aus dem privaten extrahieren openssl rsa -in pki/sa.key -pubout -out pki/sa.pub EOF chmod +x generate-apiserver-certificates.sh
-
Führen Sie das Script aus
bash generate-apiserver-certificates.sh
-
Kopieren Sie die Zertifikate auf alle Control Plane Nodes
for instance in controlplane-0 controlplane-1 controlplane-2; do echo "## Copying certificates to ${instance}" scp pki/* ${instance}:/etc/kubernetes/pki/ done
Aufgabe 2: API-Server Static Pod Manifest
-
Erstellen Sie das API-Server Static Pod Manifest
cat > kube-apiserver.yaml << 'EOF' apiVersion: v1 kind: Pod metadata: name: kube-apiserver namespace: kube-system labels: component: kube-apiserver spec: hostNetwork: true containers: - name: kube-apiserver image: registry.k8s.io/kube-apiserver:v1.32.7 command: - kube-apiserver - --allow-privileged=true - --service-cluster-ip-range=10.96.0.0/12 - --enable-bootstrap-token-auth=true - --authorization-mode=Node,RBAC - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname # Etcd-Config - --etcd-servers=https://127.0.0.1:2379 - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key # Server-Zertifikat für SSL/TLS - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key # Root-Zertifikat für Authentifizierung - --client-ca-file=/etc/kubernetes/pki/ca.crt # Client-Zertifikat für Interaktion mit Kubelet - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key # SA Zertifikate für das erstellen von Service Accounts - --service-account-issuer=https://kubernetes.default.svc.cluster.local - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key - --service-account-key-file=/etc/kubernetes/pki/sa.pub volumeMounts: - name: apiserver-certs mountPath: /etc/kubernetes/pki volumes: - name: apiserver-certs hostPath: path: /etc/kubernetes/pki EOF
-
Kopieren Sie das Manifest auf alle Control Plane Nodes
for instance in controlplane-0 controlplane-1 controlplane-2; do echo "## Copying kube-apiserver manifest to ${instance}" scp kube-apiserver.yaml ${instance}:/etc/kubernetes/manifests/ done
Aufgabe 3: Admin-Kubeconfig erstellen
-
Wechseln Sie ins parent-Verzeichnis und erstellen Sie ein admin-config-Verzeichnis
cd .. mkdir admin-config cd admin-config
Admin-Zertifikat erstellen
-
Erstellen Sie eine Konfigurationsdatei für das Admin-Zertifikat
cat > admin.cnf << 'EOF' [ req ] distinguished_name = dn req_extensions = req_ext prompt = no [ dn ] CN = kubernetes-admin O = system:masters [ req_ext ] keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF
-
Generieren Sie Schlüssel und Zertifikat für den Admin
# Privaten Schlüssel erzeugen openssl genrsa -out admin.key 4096 # Certificate Signing Request erstellen openssl req -new -sha512 \ -key "admin.key" \ -out "admin.csr" \ -config "admin.cnf" # Zertifikat erstellen openssl x509 -req -days 365 -sha512 \ -in "admin.csr" \ -out "admin.crt" \ -CA "../pki/ca.crt" -CAkey "../pki/ca.key" -CAcreateserial \ -copy_extensions copyall
Admin-Kubeconfig konfigurieren
-
Ermitteln Sie die IP-Adresse des ersten Control Plane Nodes
export API_SERVER_IP=$(ssh -G controlplane-0 | awk '/^hostname /{print $2}') echo "API Server IP: $API_SERVER_IP"
-
Erstellen Sie die admin.conf Kubeconfig-Datei
# Cluster konfigurieren kubectl config set-cluster kubernetes \ --server="https://${API_SERVER_IP}:6443" \ --certificate-authority=../pki/ca.crt \ --embed-certs=true \ --kubeconfig=admin.conf # Credentials konfigurieren kubectl config set-credentials kubernetes-admin \ --client-certificate=./admin.crt \ --client-key=./admin.key \ --embed-certs=true \ --kubeconfig=admin.conf # Context konfigurieren kubectl config set-context kubernetes-admin@kubernetes \ --cluster=kubernetes \ --user=kubernetes-admin \ --kubeconfig=admin.conf # Context aktivieren kubectl config use-context kubernetes-admin@kubernetes \ --kubeconfig=admin.conf
-
Kopieren Sie die admin.conf in Ihr kubectl-Konfigurationsverzeichnis
mkdir -p ~/.kube cp admin.conf ~/.kube/config
API-Server-Verbindung testen
-
Testen Sie die Verbindung zum API-Server
# Nodes anzeigen kubectl get nodes # Pods in allen Namespaces anzeigen kubectl get pods -A
Aufgabe 4: Kube-Scheduler einrichten
-
Wechseln Sie ins parent-Verzeichnis und erstellen Sie ein Scheduler-Verzeichnis
cd .. mkdir kube-scheduler-setup cd kube-scheduler-setup
Scheduler-Zertifikat erstellen
-
Erstellen Sie eine Konfigurationsdatei für das Scheduler-Zertifikat
cat > scheduler.cnf << 'EOF' [ req ] distinguished_name = dn req_extensions = req_ext prompt = no [ dn ] CN = system:kube-scheduler [ req_ext ] keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF
-
Generieren Sie Schlüssel und Zertifikat für den Scheduler
# Privaten Schlüssel erzeugen openssl genrsa -out scheduler.key 4096 # Certificate Signing Request erstellen openssl req -new -sha512 \ -key "scheduler.key" \ -out "scheduler.csr" \ -config "scheduler.cnf" # Zertifikat erstellen openssl x509 -req -days 365 -sha512 \ -in "scheduler.csr" \ -out "scheduler.crt" \ -CA "../pki/ca.crt" -CAkey "../pki/ca.key" -CAcreateserial \ -copy_extensions copyall
Scheduler-Kubeconfig erstellen
-
Erstellen Sie die Kubeconfig-Datei für den Scheduler
# Cluster konfigurieren kubectl config set-cluster kubernetes \ --certificate-authority=../pki/ca.crt \ --server=https://127.0.0.1:6443 \ --kubeconfig=scheduler.conf \ --embed-certs=true # Credentials konfigurieren kubectl config set-credentials system:kube-scheduler \ --client-certificate=scheduler.crt \ --client-key=scheduler.key \ --kubeconfig=scheduler.conf \ --embed-certs=true # Context konfigurieren kubectl config set-context default \ --cluster=kubernetes \ --user=system:kube-scheduler \ --kubeconfig=scheduler.conf # Context aktivieren kubectl config use-context default \ --kubeconfig=scheduler.conf
-
Kopieren Sie die Kubeconfig auf alle Control Plane Nodes
for instance in controlplane-0 controlplane-1 controlplane-2; do echo "## Copying kube-scheduler kubeconfig to ${instance}" scp scheduler.conf ${instance}:/etc/kubernetes/scheduler.conf done
Scheduler Static Pod Manifest
-
Erstellen Sie das Scheduler Static Pod Manifest
cat > kube-scheduler.yaml << 'EOF' apiVersion: v1 kind: Pod metadata: name: kube-scheduler namespace: kube-system labels: component: kube-scheduler spec: hostNetwork: true containers: - name: kube-scheduler image: registry.k8s.io/kube-scheduler:v1.32.7 command: - kube-scheduler - --authentication-kubeconfig=/etc/kubernetes/scheduler.conf - --authorization-kubeconfig=/etc/kubernetes/scheduler.conf - --bind-address=127.0.0.1 - --kubeconfig=/etc/kubernetes/scheduler.conf - --leader-elect=true volumeMounts: - mountPath: /etc/kubernetes/scheduler.conf name: kubeconfig readOnly: true volumes: - hostPath: path: /etc/kubernetes/scheduler.conf type: FileOrCreate name: kubeconfig EOF
-
Kopieren Sie das Manifest auf alle Control Plane Nodes
for instance in controlplane-0 controlplane-1 controlplane-2; do echo "## Copying kube-scheduler manifest to ${instance}" scp kube-scheduler.yaml ${instance}:/etc/kubernetes/manifests/ done
Aufgabe 5: Kube-Controller-Manager einrichten
-
Wechseln Sie ins parent-Verzeichnis und erstellen Sie ein Controller-Manager-Verzeichnis
cd .. mkdir kube-controller-manager-setup cd kube-controller-manager-setup
Controller-Manager-Zertifikat erstellen
-
Erstellen Sie eine Konfigurationsdatei für das Controller-Manager-Zertifikat
cat > controller.cnf << 'EOF' [ req ] distinguished_name = dn req_extensions = req_ext prompt = no [ dn ] CN = system:kube-controller-manager [ req_ext ] keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF
-
Generieren Sie Schlüssel und Zertifikat für den Controller Manager
# Privaten Schlüssel erzeugen openssl genrsa -out controller.key 4096 # Certificate Signing Request erstellen openssl req -new -sha512 \ -key "controller.key" \ -out "controller.csr" \ -config "controller.cnf" # Zertifikat erstellen openssl x509 -req -days 365 -sha512 \ -in "controller.csr" \ -out "controller.crt" \ -CA "../pki/ca.crt" -CAkey "../pki/ca.key" -CAcreateserial \ -copy_extensions copyall
Controller-Manager-Kubeconfig erstellen
-
Erstellen Sie die Kubeconfig-Datei für den Controller Manager
# Cluster konfigurieren kubectl config set-cluster kubernetes \ --certificate-authority=../pki/ca.crt \ --server=https://127.0.0.1:6443 \ --kubeconfig=controller-manager.conf \ --embed-certs=true # Credentials konfigurieren kubectl config set-credentials system:kube-controller-manager \ --client-certificate=controller.crt \ --client-key=controller.key \ --kubeconfig=controller-manager.conf \ --embed-certs=true # Context konfigurieren kubectl config set-context default \ --cluster=kubernetes \ --user=system:kube-controller-manager \ --kubeconfig=controller-manager.conf # Context aktivieren kubectl config use-context default \ --kubeconfig=controller-manager.conf
-
Kopieren Sie die Kubeconfig auf alle Control Plane Nodes
for instance in controlplane-0 controlplane-1 controlplane-2; do echo "## Copying kube-controller-manager kubeconfig to ${instance}" scp controller-manager.conf ${instance}:/etc/kubernetes/controller-manager.conf done
Controller-Manager Static Pod Manifest
-
Erstellen Sie das Controller-Manager Static Pod Manifest
cat > kube-controller-manager.yaml << 'EOF' apiVersion: v1 kind: Pod metadata: name: kube-controller-manager namespace: kube-system labels: component: kube-controller-manager spec: hostNetwork: true containers: - name: kube-controller-manager image: registry.k8s.io/kube-controller-manager:v1.32.7 command: - kube-controller-manager - --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf - --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf - --bind-address=127.0.0.1 - --kubeconfig=/etc/kubernetes/controller-manager.conf - --leader-elect=true - --use-service-account-credentials=true - --service-account-private-key-file=/etc/kubernetes/pki/sa.key - --root-ca-file=/etc/kubernetes/pki/ca.crt volumeMounts: - mountPath: /etc/kubernetes/pki name: k8s-certs readOnly: true - mountPath: /etc/kubernetes/controller-manager.conf name: kubeconfig readOnly: true volumes: - hostPath: path: /etc/kubernetes/pki type: DirectoryOrCreate name: k8s-certs - hostPath: path: /etc/kubernetes/controller-manager.conf type: FileOrCreate name: kubeconfig EOF
-
Kopieren Sie das Manifest auf alle Control Plane Nodes
for instance in controlplane-0 controlplane-1 controlplane-2; do echo "## Copying kube-controller-manager manifest to ${instance}" scp kube-controller-manager.yaml ${instance}:/etc/kubernetes/manifests/ done
Aufgabe 6: Control Plane finalisieren
ClusterRoleBinding erstellen
-
Erstellen Sie eine ClusterRoleBinding für die API-Server-Kubelet-Kommunikation
kubectl create clusterrolebinding kube-apiserver-to-kubelet \ --clusterrole=system:kubelet-api-admin \ --user=kube-apiserver-kubelet-client
Control Plane Nodes mit Taint versehen
-
Tainten Sie die Control Plane Nodes, damit keine regulären Workloads darauf gescheduled werden
for instance in controlplane-0 controlplane-1 controlplane-2; do echo "## Tainting node ${instance}" kubectl taint node ${instance} node-role.kubernetes.io/control-plane:NoSchedule done
Aufgabe 7: Cluster-Status überprüfen
-
Überprüfen Sie den Status aller Nodes
kubectl get nodes -o wide
-
Überprüfen Sie alle Control Plane Pods
kubectl get pods -n kube-system
-
Überprüfen Sie die Cluster-Informationen
kubectl cluster-info
-
Testen Sie die Funktionalität mit einem Test-Pod
# Test-Pod erstellen kubectl run test-pod --image=nginx --restart=Never # Pod-Status überprüfen kubectl get pods # Pod-Details anzeigen kubectl describe pod test-pod # Test-Pod löschen kubectl delete pod test-pod
Aufgabe 8: Troubleshooting (Optional)
-
Überprüfen Sie die Static Pod-Logs auf einem Control Plane Node
ssh controlplane-0 "journalctl -u kubelet -f"
-
Überprüfen Sie die API-Server-Logs
kubectl logs -n kube-system kube-apiserver-controlplane-0
-
Überprüfen Sie die Scheduler-Logs
kubectl logs -n kube-system kube-scheduler-controlplane-0
-
Überprüfen Sie die Controller-Manager-Logs
kubectl logs -n kube-system kube-controller-manager-controlplane-0
Ausblick
Nach Abschluss dieser Aufgabe haben Sie eine vollständige Control Plane mit allen wichtigen Komponenten aufgebaut. Der Cluster ist bereit für die Installation von CNI-Plugins und weiteren Add-ons. Sie können nun beginnen, Workloads auf dem Cluster zu deployen.
Glückwunsch!
Sie haben erfolgreich einen Kubernetes-Cluster manuell aufgebaut und verstehen nun die grundlegenden Komponenten und deren Interaktionen. Diese Kenntnisse helfen Ihnen beim Troubleshooting und bei der Administration von Kubernetes