SSD Nodes Learn 🎉 VPS ab $5.50/Monat
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-21

Kubernetes: Fehler an Port 10250 auf Ubuntu beheben

Port 10250 gehört zur kubelet-API. Beheben Sie bei kubeadm init den Fehler „address already in use“ und Firewall-Blockaden für kubectl logs und exec.

Was Port 10250 ist

Port 10250 ist die kubelet-API. Jeder Fehler, in dem dieser Port genannt wird, weist auf eines von zwei gegensätzlichen Problemen hin. Entweder verwendet bereits ein anderer Prozess den Port, sodass kubeadm init nicht gestartet werden kann. Oder niemand kann den Port erreichen, sodass kubectl logs und kubectl exec bei einem ansonsten unauffälligen Node fehlschlagen.

Der kubelet ist der Agent, den Kubernetes auf jedem Node ausführt. Er startet Container und meldet deren Status an die Control Plane zurück. Außerdem lauscht er auf TCP 10250 und stellt eine HTTPS-API bereit, die von der Control Plane aufgerufen wird. Der API-Server öffnet eine Verbindung zu diesem Port, wenn Sie kubectl logs, kubectl exec, kubectl attach oder kubectl port-forward ausführen. metrics-server ruft /metrics/resource über denselben Port ab. Dadurch funktioniert kubectl top node.

Diese API erfordert eine Authentifizierung. kubeadm deaktiviert den anonymen Zugriff und konfiguriert den kubelet für die Verwendung der Cluster-CA (Certificate Authority). Eine Anfrage ohne Anmeldedaten wird daher mit Unauthorized beantwortet und gewährt keinen Shell-Zugriff auf einen Ihrer Container. Beachten Sie dieses Detail. Damit lässt sich am schnellsten prüfen, ob der Port erreichbar ist. Wenn Ports für Sie noch neu sind, erklärt was ein Port unter Linux tatsächlich ist das diesem Leitfaden zugrunde liegende Modell.

Beide Fehlerarten ergeben sich aus derselben Voraussetzung. Port 10250 muss frei sein, bevor der kubelet startet. Sobald er läuft, muss der Port von der Control Plane aus erreichbar sein.

Welches der beiden Probleme liegt bei Ihnen vor

Führen Sie diese Befehle auf dem betroffenen Node aus. Jeden der folgenden Befehle führen Sie selbst auf Ihrem eigenen Server aus.

sudo ss -lntp | grep 10250
sudo systemctl status kubelet --no-pager

ss -lntp listet die lauschenden TCP-Sockets und den jeweils zugehörigen Prozess auf. -l steht für lauschende Sockets, -n sorgt dafür, dass Ports numerisch angezeigt werden, -t begrenzt die Ausgabe auf TCP und -p zeigt den Prozess an, dem der Socket gehört. Für das letzte Flag benötigen Sie root-Rechte. Andernfalls bleibt die Prozessspalte leer und die Ausgabe liefert keine verwertbaren Informationen.

Eine Zeile, die mit users:(("kubelet",pid=1043,fd=23)) endet, bedeutet, dass der kubelet läuft und den Port belegt. Wenn der Port eigentlich frei sein sollte, ist damit die Ursache gefunden. Gibt ss überhaupt nichts aus und kann die Control Plane diesen Node weiterhin nicht erreichen, ist noch keine Firewall beteiligt, weil auf dem Port zunächst kein Dienst lauscht. Ermitteln Sie zuerst, warum der kubelet nicht läuft, bevor Sie Regeln ändern.

systemctl status kubelet liefert die andere Hälfte des Bildes. active (running) mit einer Startzeit vor wenigen Minuten ist normal. Auch ein kubelet, das alle paar Sekunden neu startet, bevor Sie kubeadm init oder kubeadm join ausgeführt haben, ist normal: Die mitgelieferte Unit wird bei der Installation gestartet, findet keine Konfiguration und wird beendet. Die Upstream-Dokumentation beschreibt diese Crash-Schleife als erwartetes Verhalten, während der kubelet darauf wartet, dass kubeadm ihm vorgibt, was er tun soll. Wenn Ihnen das Restart-Verhalten von systemd nicht vertraut ist, erklärt wie systemd-Diensttypen und Restart-Richtlinien funktionieren die Grundlagen für diesen Abschnitt.

Warum ist Port 10250 beim Ausführen von kubeadm init bereits belegt?

kubeadm init führt Preflight-Prüfungen aus, bevor es Daten auf die Festplatte schreibt. Eine dieser Prüfungen versucht, jeden Port zu binden, den die Control Plane benötigt. Wenn das Binden von Port 10250 fehlschlägt, wird der Vorgang mit einer entsprechenden Fehlermeldung beendet. Das ist kein Fehler in kubeadm. kubeadm verhindert, dass ein zweiter Cluster auf den Resten eines ersten Clusters aufgebaut wird.

In der Praxis gibt es dafür vier Ursachen:

  • Ein vorheriger kubeadm init oder kubeadm join ist teilweise fehlgeschlagen. Der kubelet hat bereits eine Konfiguration erhalten, läuft deshalb und belegt den Port.
  • Ein kubeadm reset wurde gestartet, aber nicht abgeschlossen. Der Reset beendet den kubelet, deaktiviert die Unit jedoch nicht. Beim nächsten Reboot wird der Listener daher erneut gestartet.
  • k3s oder eine andere Kubernetes-Distribution ist auf demselben Server installiert. k3s enthält einen kubelet, der ebenfalls Port 10250 bindet.
  • Das kubelet-Paket wurde von apt installiert und von einer eigenen systemd-Unit gestartet, obwohl auf dem Server noch kein kubeadm ausgeführt wurde.

Ermitteln Sie vor jeder Änderung, welche Ursache vorliegt:

sudo ss -lntp 'sport = :10250'
systemctl list-units --type=service --state=running | grep -Ei 'kubelet|k3s|k0s'

Wenn der Listener zu k3s gehört, beenden Sie k3s und entscheiden Sie, welchen Cluster Sie tatsächlich verwenden möchten. k3s und kubeadm können sich einen Server nicht teilen, weil sie dieselben Ports und dasselbe CNI-Verzeichnis (Container Network Interface) verwenden. Das k3s-Installationsprogramm legt auf einem Serverknoten ein Deinstallationsskript unter /usr/local/bin/k3s-uninstall.sh und auf einem Agentknoten unter k3s-agent-uninstall.sh ab.

Warum das Beenden von kubelet den Port nicht freigibt

sudo pkill kubelet gibt Port 10250 etwa zehn Sekunden lang frei. Die mitgelieferte Unit legt eine Neustartrichtlinie fest. Deshalb startet systemd einen neuen kubelet-Prozess, der wieder denselben Port bindet. Sie können die Richtlinie selbst anzeigen:

systemctl show kubelet -p Restart -p RestartSec
sudo systemctl stop kubelet
sudo ss -lntp | grep 10250

Restart=always mit RestartSec=10 entspricht der Konfiguration, mit der die Unit ausgeliefert wird. Genau deshalb sieht es bei kill so aus, als hätte der Befehl funktioniert, bevor die Belegung wiederhergestellt wird. systemctl stop ist die richtige Methode, um den Port freizugeben, weil systemd eine Unit, deren Beenden Sie angefordert haben, nicht erneut startet.

Ein freier Port reicht auf einem Node, der einen Teil eines Clusters enthält, noch nicht aus. /var/lib/kubelet/config.yaml, die Zertifikate unter /etc/kubernetes/pki und alle statischen Pod-Manifeste in /etc/kubernetes/manifests sind weiterhin vorhanden. Spätere Preflight-Prüfungen stoßen auf diese Dateien. Wenn Sie die Prüfungen erzwingen, erhalten Sie einen Cluster, dessen Zertifikate nicht mit der Konfiguration übereinstimmen. Setzen Sie den Node stattdessen ordnungsgemäß zurück.

Knoten sauber zurücksetzen

sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d
rm -rf $HOME/.kube
sudo systemctl stop kubelet
sudo ss -lntp | grep -E '10250|6443|2379'

-f überspringt die Bestätigungsabfrage. Der Reset versucht bestmöglich, die Änderungen von init oder join rückgängig zu machen. Er entfernt die lokalen Dateien und die Konfiguration, entfernt das lokale etcd-Mitglied auf einem Control-Plane-Knoten, bereinigt die Zertifikate in /etc/kubernetes/pki und entfernt die kubelet-Konfiguration sowie die Manifeste.

Die Dokumentation beschreibt ausdrücklich, was der Reset zurücklässt. Jeder dieser Punkte führt häufig zu Problemen. /etc/cni/net.d wird nicht bereinigt. Die alte CNI-Plugin-Konfiguration bleibt daher erhalten und wird vom neuen Cluster eingelesen. iptables-, nftables- oder IPVS-Regeln, die kube-proxy auf dem Host eingerichtet hat, werden nicht entfernt. $HOME/.kube wird nicht verändert. kubectl kommuniziert daher weiterhin mit einem Cluster, der nicht mehr existiert, und gibt Zertifikatsfehler zurück, die wie ein neues Problem aussehen.

Die verbliebenen Paketregeln sind der problematische Teil. Wenn Sie die Tabellen manuell leeren, werden auch die von ufw eingerichteten Regeln entfernt, weil ufw unter Ubuntu dasselbe Backend verwendet. Der Server bleibt dadurch ungefiltert, bis Sie sudo ufw reload ausführen. Wenn Sie den Knoten ohnehin neu aufbauen, starten Sie ihn nach dem Reset neu. Ein Neustart entfernt die von kube-proxy hinzugefügten Laufzeitregeln und kostet weniger Zeit, als ein teilweise geleertes Regelwerk zu bereinigen. Warum iptables-Regeln und nftables-Regeln in der Ausgabe des jeweils anderen erscheinen erklärt die zugrunde liegenden Vorgänge.

Der letzte ss-Befehl sollte keine Ausgabe erzeugen. Wenn auf 10250, 6443 oder 2379 kein Prozess lauscht, ist der Knoten für einen neuen kubeadm init bereit.

Warum kubectl logs und kubectl exec bei Port 10250 eine Zeitüberschreitung erreichen

Dies ist die gegenteilige Fehlermeldung, und sie weist nicht direkt auf ein Portproblem hin. Der Cluster wird gestartet. Die Nodes werden als Ready angezeigt. Pods laufen. Dann schlägt ein Befehl fehl:

Error from server: Get "https://10.0.0.12:10250/containerLogs/default/web-0/web": dial tcp 10.0.0.12:10250: i/o timeout

Lesen Sie diese Meldung vom Ende her. Der API-Server hat versucht, eine TCP-Verbindung zum Node auf Port 10250 zu öffnen, aber keine Antwort erhalten. i/o timeout bedeutet, dass die Pakete stillschweigend verworfen wurden. Daher filtert etwas den Datenverkehr: die Host-Firewall auf dem Node oder die separate Netzwerk-Firewall Ihres Providers im Control Panel. connect: connection refused an derselben Stelle bedeutet das Gegenteil. Das Paket ist angekommen, aber kein Prozess hat auf dem Port gelauscht. Der kubelet ist also nicht aktiv. Dies ist dasselbe Ursachenpaar wie unter Verbindung abgelehnt im Vergleich zu Zeitüberschreitung, hier jedoch für einen anderen Port.

Die Nodes bleiben währenddessen Ready, weil der Node-Status in die andere Richtung übertragen wird. Der kubelet stellt ausgehend eine Verbindung zum API-Server auf Port 6443 her und sendet seinen eigenen Heartbeat. Dafür ist keine eingehende Verbindung auf Port 10250 erforderlich. Ein blockierter Port 10250 führt daher zu einem Cluster, der Pods normal plant, aber nur bei logs, exec, port-forward und Metriken fehlschlägt.

kubectl top node als Antwort auf error: Metrics API not available ist derselbe Fehler aus Sicht von metrics-server. Dessen Log nennt den Node und den Port:

unable to fully scrape metrics from node worker-1: unable to fetch metrics from node worker-1: Get "https://10.0.0.12:10250/metrics/resource": dial tcp 10.0.0.12:10250: i/o timeout

Testen Sie den Pfad, bevor Sie eine Firewall-Regel ändern

Führen Sie diesen Befehl von einem Control-Plane-Knoten zur Adresse des Workers aus:

nc -zv 10.0.0.12 10250
curl -sk -o /dev/null -w '%{http_code}\n' https://10.0.0.12:10250/healthz

nc -z öffnet eine Verbindung, schließt sie wieder und gibt succeeded! aus, wenn der Port die Verbindung akzeptiert. Die curl-Zeile ist der bessere Test, weil sie nachweist, dass der kubelet Anfragen verarbeitet, statt nur zu zeigen, dass ein Port geöffnet ist. Sie gibt 401 aus. Das ist das erwartete Ergebnis: Der TLS-Handshake (Transport Layer Security) wurde abgeschlossen, anschließend hat der kubelet eine nicht authentifizierte Anfrage abgewiesen. Genau so soll es sein. -k überspringt die Zertifikatsprüfung. Das ist hier in Ordnung, weil Sie den Pfad und nicht die Vertrauenskette testen.

Eine lange Pause mit anschließendem Timeout bedeutet, dass Pakete verworfen werden. Wenn curl: (7) Failed to connect sofort zurückkehrt, ist der Port auf einem erreichbaren Host geschlossen. Testen Sie vom Control-Plane-Knoten und nicht von Ihrem Laptop aus, weil hier nur der Zugriff des Control Plane relevant ist.

Welche Ports eine Control-Plane- und eine Worker-Node jeweils benötigen

Dies sind die eingehenden Ports, die upstream aufgeführt sind. Auf einer Control-Plane-Node wird TCP 6443 für den API-Server benötigt. Der Port muss für alle Komponenten geöffnet sein, die kubectl ausführen. TCP 2379 bis 2380 werden für die Client- und Peer-API von etcd verwendet. Darauf greifen der API-Server und etcd selbst zu. TCP 10250 wird für die kubelet-API benötigt. Darauf greifen die Node selbst und die Control Plane zu. TCP 10259 für kube-scheduler und TCP 10257 für kube-controller-manager werden jeweils nur von der Node selbst verwendet.

Auf einer Worker-Node wird TCP 10250 für die kubelet-API benötigt. Darauf greifen die Node selbst und die Control Plane zu. TCP 10256 wird für kube-proxy verwendet. Darauf greifen die Node selbst und Load Balancer für Health Checks zu. TCP und UDP 30000 bis 32767 werden für NodePort-Services verwendet. Das ist der Standardbereich. Er muss für alle erreichbar sein, die diese Services benötigen.

Ihr CNI-Plugin benötigt zusätzlich eigene Ports. Diese sind in der Liste nicht enthalten. Flannel und Calico im VXLAN-Modus benötigen UDP 4789 zwischen den Nodes. Calico mit BGP benötigt TCP 179. Prüfen Sie die Dokumentation Ihres Plugins und öffnen Sie diese Ports zwischen den Nodes. Andernfalls können Pods auf unterschiedlichen Nodes nicht miteinander kommunizieren, obwohl alle Ports in diesem Abschnitt geöffnet sind.

10250 öffnen, ohne es dem Internet auszusetzen

Die kubelet-API kann innerhalb jedes Containers auf diesem Node einen Prozess starten. Behandeln Sie einen offenen Port 10250 wie Root-Zugriff auf den Node und beschränken Sie den Zugriff anhand der Quelladresse. Erlauben Sie den Zugriff niemals von beliebigen Adressen.

sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp comment 'kubelet API'
sudo ufw allow from 10.0.0.0/24 to any port 10256 proto tcp comment 'kube-proxy'
sudo ufw status numbered

Ersetzen Sie 10.0.0.0/24 durch das Netzwerk, das Ihre Nodes gemeinsam verwenden. ufw status numbered listet die aktiven Regeln mit einem Index auf. Dadurch können Sie eine falsche Regel mit sudo ufw delete <number> löschen. Die ufw-Grundlagen für einen VPS beschreibt die Reihenfolge der Regeln, die festlegt, welcher Ihrer Einträge tatsächlich angewendet wird.

Eine ufw-Einstellung kann Kubernetes allein bereits beeinträchtigen. Pod-Verkehr, der den Node passiert, wird weitergeleitet und nicht lokal zugestellt. ufw verwirft weitergeleitete Pakete standardmäßig. Setzen Sie DEFAULT_FORWARD_POLICY="ACCEPT" in /etc/default/ufw und führen Sie sudo ufw reload aus. Ohne diese Einstellung kann Port 10250 vollständig offen sein, während der Pod-zu-Pod-Verkehr zwischen Nodes weiterhin fehlschlägt.

Prüfen Sie auch die Firewall Ihres Providers. Die meisten VPS-Panels verfügen über eine Firewall auf Netzwerkebene, die dem Server vorgeschaltet und für ufw status unsichtbar ist. Eine Regel, die Sie auf dem Node hinzufügen, ändert nichts, wenn das Paket den Server nie erreicht.

Wenn der Port erreichbar ist und die Anfrage trotzdem fehlschlägt

Einige 10250-Fehler treten sofort auf, statt dass die Verbindung hängen bleibt. Das zeigt, dass die Verbindung erfolgreich hergestellt wurde und die Anfrage abgelehnt wurde. x509: certificate signed by unknown authority im metrics-server-Log bedeutet, dass der kubelet ein selbst signiertes Zertifikat bereitstellt, dem der Scraper nicht vertraut. Üblicherweise aktivieren Sie die Rotation der kubelet-Serverzertifikate, damit die Cluster-CA das Zertifikat signiert, und genehmigen anschließend die CertificateSigningRequest. In einem Testcluster können Sie das Risiko akzeptieren und metrics-server mit --kubelet-insecure-tls ausführen.

Eine Meldung mit Forbidden zusammen mit nodes/proxy oder nodes/metrics weist auf einen RBAC-Fehler (rollenbasierte Zugriffskontrolle) hin. Der Aufrufer hat den kubelet erreicht. Der kubelet hat den API-Server gefragt, ob diese Identität das Subresource verwenden darf. Die Antwort war nein. Korrigieren Sie die ClusterRole des Aufrufers. Eine Änderung an der Firewall hilft nicht, weil nichts blockiert wurde.

Wenn Sie nur einen kleinen Cluster benötigen

Wenn diese Fehler beim erstmaligen Einrichten von kubeadm auf einem einzelnen VPS auftreten, sollten Sie prüfen, ob Sie kubeadm überhaupt benötigen. Ein k3s-Cluster mit einem einzelnen Node auf einem VPS stellt Ihnen mit einem einzigen Befehl eine funktionsfähige Kubernetes-API bereit. Kubelet, kube-proxy und ein CNI sind bereits integriert. Port 10250 ist auch dort vorhanden, und dafür gelten dieselben Regeln. Die Control Plane müssen Sie jedoch nicht mehr selbst zusammenstellen.

FAQ

Wofür wird Port 10250 in Kubernetes verwendet?

Dabei handelt es sich um die authentifizierte HTTPS-API des kubelet auf jedem Node, sowohl auf Control-Plane- als auch auf Worker-Nodes. Der API-Server verbindet sich für kubectl logs, kubectl exec, kubectl attach und kubectl port-forward damit. Außerdem ruft metrics-server dort /metrics/resource ab, um kubectl top bereitzustellen. Der Node-Status verwendet diesen Port nicht, weil das kubelet seinen Heartbeat über Port 6443 ausgehend an den API-Server sendet. Deshalb werden Nodes bei einem blockierten Port 10250 als Ready angezeigt, während Logs und exec fehlschlagen.

Wie finde ich heraus, welcher Prozess auf Port 10250 lauscht?

Führen Sie sudo ss -lntp | grep 10250 auf dem Node aus. Das Feld users:((...)) am Ende der Zeile nennt den Prozess und seine PID. sudo ist wichtig, weil die Prozessspalte ohne root leer bleibt. Wenn der Besitzer das kubelet ist, zeigt sudo systemctl status kubelet --no-pager, ob es sich um ein funktionierendes kubelet handelt oder um eines, das in einer Neustartschleife läuft. Wenn der Besitzer k3s ist, sind zwei Kubernetes-Distributionen auf einem Server installiert. Sie müssen eine davon entfernen.

Muss ich Port 10250 in meiner Firewall öffnen?

Ja, zwischen Ihren Nodes. Die Control Plane muss Port 10250 auf jedem Node erreichen können, auch auf sich selbst. Andernfalls schlagen Logs, exec, port-forward und Metriken fehl. Beschränken Sie den Zugriff anhand der Quelle auf das Netzwerk, das Ihre Nodes gemeinsam verwenden, zum Beispiel sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp. Öffnen Sie den Port nicht für das Internet. Jeder, der sich an diesem Port authentifizieren kann, kann in jedem Container auf dem Node einen Prozess ausführen.

Warum schlägt kubectl logs nur für Pods auf einem Node fehl?

Weil die Sperre pro Node gilt und der API-Server eine Verbindung zu dem Node herstellt, auf dem der Pod läuft. Lesen Sie den Fehlertext. Er enthält die IP-Adresse des Nodes, zu dem die Verbindung hergestellt werden sollte. Führen Sie anschließend nc -zv <node-ip> 10250 von einem Control-Plane-Node aus. Ein Timeout weist auf die Firewall dieses Nodes oder auf die Netzwerk-Firewall Ihres Providers hin. connection refused weist auf ein kubelet hin, das dort nicht läuft. Prüfen Sie daher stattdessen systemctl status kubelet auf diesem Node.