Worker Nodes finalisieren
Ziel
In diesem Projekt geht es um die Finalisierung der Kubernetes Worker Nodes. Sie werden:
- Kube-Proxy als DaemonSet installieren und konfigurieren
- CNI-Plugin (Cilium) für Cluster-Networking installieren
- CoreDNS für Service Discovery und DNS-Auflösung einrichten
- Die Funktionalität aller Cluster-Komponenten testen
Vorbereitung
-
Erstellen Sie ein neues Arbeitsverzeichnis und wechseln Sie hinein
cd ~/workspace mkdir kubeproxy cd kubeproxy
Aufgabe 1: Kube-Proxy installieren
Kube-Proxy Manifest erstellen
-
Erstellen Sie ein Manifest für kube-proxy als DaemonSet
cat > kube-proxy.yaml << 'EOF' --- apiVersion: v1 kind: ServiceAccount metadata: name: kube-proxy namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubeadm:node-proxier roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:node-proxier subjects: - kind: ServiceAccount name: kube-proxy namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: kube-proxy namespace: kube-system rules: - apiGroups: - "" resourceNames: - kube-proxy resources: - configmaps verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: kube-proxy namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kube-proxy subjects: - kind: Group name: system:bootstrappers:kubeadm:default-node-token --- kind: ConfigMap apiVersion: v1 metadata: name: kube-proxy namespace: kube-system labels: app: kube-proxy data: kubeconfig.conf: |- apiVersion: v1 kind: Config clusters: - cluster: certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt server: https://<API_SERVER_IP>:6443 name: default contexts: - context: cluster: default namespace: default user: default name: default current-context: default users: - name: default user: tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token config.conf: |- apiVersion: kubeproxy.config.k8s.io/v1alpha1 bindAddress: 0.0.0.0 bindAddressHardFail: false clientConnection: acceptContentTypes: "" burst: 0 contentType: "" kubeconfig: /var/lib/kube-proxy/kubeconfig.conf qps: 0 clusterCIDR: "" configSyncPeriod: 0s conntrack: maxPerCore: null min: null tcpBeLiberal: false tcpCloseWaitTimeout: null tcpEstablishedTimeout: null udpStreamTimeout: 0s udpTimeout: 0s detectLocal: bridgeInterface: "" interfaceNamePrefix: "" detectLocalMode: "" enableProfiling: false healthzBindAddress: "" hostnameOverride: "" iptables: localhostNodePorts: null masqueradeAll: false masqueradeBit: null minSyncPeriod: 0s syncPeriod: 0s ipvs: excludeCIDRs: null minSyncPeriod: 0s scheduler: "" strictARP: false syncPeriod: 0s tcpFinTimeout: 0s tcpTimeout: 0s udpTimeout: 0s kind: KubeProxyConfiguration logging: flushFrequency: 0 options: json: infoBufferSize: "0" text: infoBufferSize: "0" verbosity: 0 metricsBindAddress: "" mode: "" nftables: masqueradeAll: false masqueradeBit: null minSyncPeriod: 0s syncPeriod: 0s nodePortAddresses: null oomScoreAdj: null portRange: "" showHiddenMetricsForVersion: "" winkernel: enableDSR: false forwardHealthCheckVip: false networkName: "" rootHnsEndpointName: "" sourceVip: "" --- apiVersion: apps/v1 kind: DaemonSet metadata: labels: k8s-app: kube-proxy name: kube-proxy namespace: kube-system spec: selector: matchLabels: k8s-app: kube-proxy updateStrategy: type: RollingUpdate template: metadata: labels: k8s-app: kube-proxy spec: priorityClassName: system-node-critical containers: - name: kube-proxy image: registry.k8s.io/kube-proxy:v1.34.0 imagePullPolicy: IfNotPresent command: - /usr/local/bin/kube-proxy - --config=/var/lib/kube-proxy/config.conf - --hostname-override=$(NODE_NAME) securityContext: privileged: true volumeMounts: - mountPath: /var/lib/kube-proxy name: kube-proxy - mountPath: /run/xtables.lock name: xtables-lock readOnly: false - mountPath: /lib/modules name: lib-modules readOnly: true env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName hostNetwork: true serviceAccountName: kube-proxy volumes: - name: kube-proxy configMap: name: kube-proxy - name: xtables-lock hostPath: path: /run/xtables.lock type: FileOrCreate - name: lib-modules hostPath: path: /lib/modules tolerations: - operator: Exists nodeSelector: kubernetes.io/os: linux EOF
API-Server IP konfigurieren
-
Ermitteln Sie die IP-Adresse Ihres API-Servers
# IP-Adresse des controlplane-0 ermitteln API_SERVER_IP=$(ssh -G controlplane-0 | awk '/^hostname /{print $2}') echo "API Server IP: $API_SERVER_IP"
-
Ersetzen Sie
<API_SERVER_IP>
im Manifest mit der tatsächlichen IP# IP-Adresse im Manifest ersetzen sed -i "s/<API_SERVER_IP>/$API_SERVER_IP/g" kube-proxy.yaml # Überprüfen, ob die Ersetzung erfolgreich war grep "server: https://" kube-proxy.yaml
Kube-Proxy deployen
-
Deployen Sie das kube-proxy Manifest
kubectl apply -f kube-proxy.yaml
-
Überprüfen Sie, ob alle kube-proxy Pods laufen
kubectl get pods -n kube-system -o wide -l k8s-app=kube-proxy # Warten Sie, bis alle Pods im Status "Running" sind kubectl wait --for=condition=Ready pod -l k8s-app=kube-proxy -n kube-system --timeout=300s
Aufgabe 2: CNI Plugin (Cilium) installieren
Cilium CLI installieren
-
Laden Sie die Cilium CLI herunter und installieren Sie sie
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/v0.18.6/cilium-linux-amd64.tar.gz{,.sha256sum} sha256sum --check cilium-linux-amd64.tar.gz.sha256sum tar xzvfC cilium-linux-amd64.tar.gz . rm cilium-linux-amd64.tar.gz{,.sha256sum} # Cilium CLI ausführbar machen chmod +x cilium
Cilium installieren
-
Installieren Sie Cilium als CNI-Plugin
./cilium install --version 1.18.1
-
Überprüfen Sie die Installation
# Status der Cilium-Installation prüfen ./cilium status # Alle Cilium Pods anzeigen kubectl get pods -n kube-system -o wide -l app.kubernetes.io/part-of=cilium # Warten Sie, bis alle Pods bereit sind kubectl wait --for=condition=Ready pod -l app.kubernetes.io/part-of=cilium -n kube-system --timeout=300s
Aufgabe 3: CoreDNS installieren
CoreDNS Manifest erstellen
-
Erstellen Sie ein Manifest für CoreDNS
cat > coredns.yaml << 'EOF' --- apiVersion: apps/v1 kind: Deployment metadata: name: coredns namespace: kube-system labels: k8s-app: kube-dns spec: replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 selector: matchLabels: k8s-app: kube-dns template: metadata: labels: k8s-app: kube-dns spec: priorityClassName: system-cluster-critical serviceAccountName: coredns affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: k8s-app operator: In values: ["kube-dns"] topologyKey: kubernetes.io/hostname tolerations: - key: CriticalAddonsOnly operator: Exists - key: node-role.kubernetes.io/control-plane effect: NoSchedule nodeSelector: kubernetes.io/os: linux containers: - name: coredns image: registry.k8s.io/coredns/coredns:v1.12.1 imagePullPolicy: IfNotPresent resources: limits: memory: 170Mi requests: cpu: 100m memory: 70Mi args: [ "-conf", "/etc/coredns/Corefile" ] volumeMounts: - name: config-volume mountPath: /etc/coredns readOnly: true ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP - containerPort: 9153 name: metrics protocol: TCP - containerPort: 8080 name: liveness-probe protocol: TCP - containerPort: 8181 name: readiness-probe protocol: TCP livenessProbe: httpGet: path: /health port: liveness-probe scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /ready port: readiness-probe scheme: HTTP securityContext: allowPrivilegeEscalation: false capabilities: add: - NET_BIND_SERVICE drop: - ALL readOnlyRootFilesystem: true dnsPolicy: Default volumes: - name: config-volume configMap: name: coredns items: - key: Corefile path: Corefile --- apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 { disable success cluster.local disable denial cluster.local } loop reload loadbalance } --- apiVersion: v1 kind: Service metadata: labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" kubernetes.io/name: "CoreDNS" name: kube-dns namespace: kube-system annotations: prometheus.io/port: "9153" prometheus.io/scrape: "true" # Without this resourceVersion value, an update of the Service between versions will yield: # Service "kube-dns" is invalid: metadata.resourceVersion: Invalid value: "": must be specified for an update resourceVersion: "0" spec: clusterIP: 10.96.0.10 ports: - name: dns port: 53 protocol: UDP targetPort: 53 - name: dns-tcp port: 53 protocol: TCP targetPort: 53 - name: metrics port: 9153 protocol: TCP targetPort: 9153 selector: k8s-app: kube-dns --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: system:coredns rules: - apiGroups: - "" resources: - endpoints - services - pods - namespaces verbs: - list - watch - apiGroups: - discovery.k8s.io resources: - endpointslices verbs: - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: system:coredns roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:coredns subjects: - kind: ServiceAccount name: coredns namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: coredns namespace: kube-system EOF
CoreDNS deployen
-
Deployen Sie CoreDNS
kubectl apply -f coredns.yaml
-
Überprüfen Sie, ob alle CoreDNS Pods laufen
kubectl get pods -n kube-system -o wide -l k8s-app=kube-dns # Warten Sie, bis alle Pods bereit sind kubectl wait --for=condition=Ready pod -l k8s-app=kube-dns -n kube-system --timeout=300s
Aufgabe 4: Cluster-Funktionalität testen
Node-Status überprüfen
-
Überprüfen Sie den Status aller Nodes
kubectl get nodes -o wide # Alle Nodes sollten jetzt "Ready" sein kubectl wait --for=condition=Ready nodes --all --timeout=300s
Test-Pod deployen
-
Erstellen Sie einen Test-Pod zur Überprüfung der Cluster-Funktionalität
# Test-Pod erstellen kubectl run test-pod --image=busybox --restart=Never -- sleep 3600 # Warten bis Pod läuft kubectl wait --for=condition=Ready pod/test-pod --timeout=300s # Pod-Status prüfen kubectl get pod test-pod -o wide
DNS-Funktionalität testen
-
Testen Sie die DNS-Auflösung im Cluster
# DNS-Test im Pod ausführen kubectl exec test-pod -- nslookup kubernetes.default.svc.cluster.local # CoreDNS Service testen kubectl exec test-pod -- nslookup kube-dns.kube-system.svc.cluster.local # Externe DNS-Auflösung testen kubectl exec test-pod -- nslookup google.com
Service-Konnektivität testen
-
Testen Sie die Service-Discovery
# Kubernetes API Service testen kubectl exec test-pod -- wget -qO- https://kubernetes.default.svc.cluster.local:443 --no-check-certificate || echo "Connection established (certificate error expected)" # CoreDNS Metrics testen kubectl exec test-pod -- wget -qO- http://kube-dns.kube-system.svc.cluster.local:9153/metrics
Aufgabe 5: Gesamtübersicht
-
Zeigen Sie eine Übersicht aller wichtigen Cluster-Komponenten
echo "=== NODES ===" kubectl get nodes echo "=== SYSTEM PODS ===" kubectl get pods -n kube-system echo "=== SYSTEM SERVICES ===" kubectl get services -n kube-system echo "=== DAEMONSETS ===" kubectl get daemonsets -n kube-system echo "=== DEPLOYMENTS ===" kubectl get deployments -n kube-system
Cleanup (Optional)
-
Löschen Sie den Test-Pod
kubectl delete pod test-pod
Gratulation!
Sie haben erfolgreich einen vollständigen Kubernetes-Cluster aufgebaut! Alle wichtigen Komponenten sind installiert und funktionsfähig:
- Kube-Proxy: Ermöglicht Service-Discovery und Load Balancing
- Cilium: Stellt Cluster-Networking und Sicherheitsrichtlinien bereit
- CoreDNS: Bietet DNS-Auflösung für Services und Pods
Der Cluster ist jetzt bereit für den produktiven Einsatz von Workloads.
Nächste Schritte
In einem produktiven Umgebung würden Sie zusätzlich folgende Komponenten installieren:
- Ingress Controller für HTTP/HTTPS-Traffic
- Monitoring Stack (Prometheus, Grafana)
- Logging Stack (Fluentd, Elasticsearch)
- Backup-Lösungen für etcd und persistente Daten
- Security Tools für Policy Enforcement