Kubeadm: apiserver startet nicht, weil livenessprobe zu aggressiv ist

Erstellt am 25. Aug. 2017  ·  73Kommentare  ·  Quelle: kubernetes/kubeadm

[Lubomir] HINWEIS : Ein möglicher Fix wurde hier eingereicht:
https://github.com/kubernetes/kubernetes/pull/66264

Ist dies ein BUG REPORT oder eine FEATURE REQUEST?

FEHLERBERICHT

Versionen

kubeadm version (benutze kubeadm version ):
kubeadm version: & version.Info {Major: "1", Minor: "7", GitVersion: "v1.7.3 + 2c2fe6e8278a5", GitCommit: "2c2fe6e8278a5db2d15a013987b53968c743f2a1", GitTreeState: "0 a -01T00: 00: 00Z ", GoVersion:" go1.8 ", Compiler:" gc ", Plattform:" linux / arm "}

Umwelt :

  • Kubernetes-Version (verwenden Sie kubectl version ):
    Serverversion: version.Info {Major: "1", Minor: "7", GitVersion: "v1.7.4", GitCommit: "793658f2d7ca7f064d2bdf606519f9fe1229c381", GitTreeState: "clean", BuildDate: "2017-08-17T08: 30: 51Z ", GoVersion:" go1.8.3 ", Compiler:" gc ", Plattform:" linux / arm "}
  • Cloud-Anbieter oder Hardwarekonfiguration :
    arm32 (Bananapi - im Grunde ein Himbeerpi2)

  • Betriebssystem (zB aus / etc / os-release):
    (mein eigenes Betriebssystem-Image)
    ID = "Containos"
    NAME = "Containos"
    VERSION = "v2017.07"
    VERSION_ID = "v2017.07"
    PRETTY_NAME = "enthältos v2017.07"

  • Kernel (zB uname -a ):
    Linux master2 4.9.20 # 2 SMP Mi Aug 16 15:36:20 AEST 2017 armv7l GNU / Linux

  • Andere :

Was ist passiert?

kubeadm init sitzt ~ für immer in der Phase "Warten auf Kontrollebene". Die Untersuchung von Docker ps / logs zeigt, dass ein Apiserver getötet (SIGTERM) und kontinuierlich neu gestartet wird.

Was hast du erwartet?

Alles, um zu funktionieren :) Insbesondere muss ein Apiserver auftauchen und der Rest des Prozesses fortgesetzt werden.

Wie kann man es reproduzieren (so minimal und präzise wie möglich)?

Führen Sie kubeadm init auf einem langsamen Computer aus.

Was müssen wir noch wissen?

Während die Abwanderung all dieser Container auf einmal beginnt, dauert es für mich ungefähr 90 Sekunden (!) Von der ersten Protokollzeile bis zur Beantwortung von HTTP-Anfragen. Ich habe mir nicht genau angesehen, was es zu diesem Zeitpunkt tut, aber in den Protokollen wird erwähnt, wie usw. Bootstrapping-Dinge aussehen.

Mein empfohlener Fix besteht darin, den Apiserver initialDelaySeconds auf 180s zu setzen. Und wahrscheinlich anderswo im Allgemeinen ähnlich - ich denke, es gibt kaum einen Grund für aggressive anfängliche Verzögerungen.

(Wenn Sie kein Unittest sind, der häufig mit Fehlern rechnet, deutet meine Erfahrung mit Produktionssoftware darauf hin, dass die richtige Lösung für Zeitüberschreitungen fast immer darin besteht, länger gewartet zu haben.)

areUX help wanted kinbug prioritbacklog sicluster-lifecycle

Hilfreichster Kommentar

@pipejakob Ich kann bestätigen, dass (auf meinem Bananapi) das Ausführen in einem anderen Terminal am richtigen Punkt im Kubeadm-Lauf dazu führt, dass alles erfolgreich ausgeführt wird:

sed -i 's/initialDelaySeconds: [0-9]\+/initialDelaySeconds: 180/' /etc/kubernetes/manifests/kube-apiserver.yaml

(Ich habe normalerweise auch manuell docker kill den alten / Neustart-Looping-Apiserver-Container, ich bin mir nicht sicher, ob das automatisch mit statischen Pods bereinigt wird)

Alle 73 Kommentare

Es scheint, dass wir sowohl InitialDelaySeconds als auch TimeoutSeconds für die Pods der Kontrollebene auf 15 setzen, was auch dem entspricht, was kube-up.sh tut. Ich verstehe, dass der erste Start langsam ist und alle Bilder auf einmal gezogen werden. Aber wie lange dauert es, bis Ihr Apiserver nach dem Start auf /healthz Schecks reagiert, nachdem alle Bilder gezogen wurden?

Zweifellos sollten wir diese beiden Werte wahrscheinlich anpassen, um Maschinen mit geringerer Leistung aufzunehmen.

Einmal gestartet, kann es in << 15s auf Gesundheitsprüfungen reagieren - es ist wirklich nur all das zusätzliche Zeug, das der Apiserver zwischen exec () und der tatsächlichen Bereitschaft, Afaics zu bedienen, erledigt.

Oh, und die Docker-Pull-Zeit zählt nicht für InitialDelaySeconds-Afaics (gut). In anderen Beispielen mit größeren (generischen Ubuntu) Bildern über meine langsame Netzwerkverbindung kann der Pull viele Minuten dauern, aber der initialDelaySeconds-Timer scheint erst zu ticken, wenn der Pull abgeschlossen und der Docker-Lauf gestartet wurde. (Ich habe mir den relevanten Code nicht angesehen - nur häufige anekdotische Erfahrungen)

Ich habe das gleiche Problem. Bei langsamen Maschinen sitzt kubeadm für immer. Verwenden von v1.7.4

@anguslees und @koalalorenzo , können Sie bestätigen, dass dies Ihr Problem behebt, wenn Sie die Einstellungen für den Lebendigkeitstest manuell ändern (indem Sie die Manifestdateien in /etc/kubernetes/manifests/ bearbeiten)? Ich habe kürzlich auch einen Fall bei Slack gesehen, bei dem der Benutzer dieselben Symptome hatte, aber wahrscheinlich auf Speicherbeschränkungen stieß, da das Problem behoben wurde, als er zu einem Hosttyp mit mehr Speicher wechselte.

Ich möchte nur sicherstellen, dass dieser Ansatz das Problem tatsächlich behebt, bevor wir Zeit in die Codierung investieren. Vielen Dank!

Dieses Problem tritt auch auf, wenn ich versuche, kubeadm in QEMU ohne hardwareunterstützte Virtualisierung zu verwenden (was eine schlechte Idee ist, da es furchtbar langsam ist). Das Erhöhen der InitialDelaySeconds und TimeoutSeconds hilft; Der Cluster wird dann irgendwann hochgefahren.

@pipejakob Ich kann bestätigen, dass (auf meinem Bananapi) das Ausführen in einem anderen Terminal am richtigen Punkt im Kubeadm-Lauf dazu führt, dass alles erfolgreich ausgeführt wird:

sed -i 's/initialDelaySeconds: [0-9]\+/initialDelaySeconds: 180/' /etc/kubernetes/manifests/kube-apiserver.yaml

(Ich habe normalerweise auch manuell docker kill den alten / Neustart-Looping-Apiserver-Container, ich bin mir nicht sicher, ob das automatisch mit statischen Pods bereinigt wird)

@anguslees Großartig! Danke für die Bestätigung.

Ich kann bestätigen, dass ich dieses Problem auch gerade hatte, in meinem Fall auf einem Himbeer-Pi 3. Durch Ändern auf 180s wurde es behoben, aber ich glaube, ich bin auch auf Problem Nr. 106 gestoßen, da es in meinem Fall einfach gestorben ist mit:

1. September 10:47:30 raspberrypi kubelet [6053]: W0901 10: 47: 30.020409 6053 kubelet.go: 1596] Löschen des Spiegel-Pods "kube-apiserver-raspberrypi_kube-system" (7c03df63-8efa-1)
1e7-ae86-b827ebdd4b52) "weil es veraltet ist

Ich musste den Kubelet-Prozess manuell HUP, damit er wieder zum Leben erweckt wurde.

Ich kann auch bestätigen, dass ich dies hatte und wollte mich für die Rettung meiner geistigen Gesundheit bedanken. Ich habe Raspberry Pi 2B und war den letzten Monat in der Init-Phase festgefahren. Nachdem ich diesen Einzeiler gefahren hatte, als er auf das Kontrollflugzeug wartete, ging es weiter.

Dieses Problem besteht immer noch in kubeadm v1.8.0 und ist noch schlimmer, da kubeadm selbst bei den meisten Aktionen eine Zeitüberschreitung wenn initialDelaySeconds verlängert wurde, und c) kann nicht erhöht werden, ohne kubeadm afaics zu hacken / neu aufzubauen.

Timeouts brechen die ansonsten korrekte Logik, insbesondere in komplexen, letztendlich konsistenten Systemen. Wir sollten sie niemals "nur weil" hinzufügen :( Mein Verständnis ist, dass kubeadm ein Baustein sein soll, von dem größere Bereitstellungssysteme abhängen können. Infolgedessen schlage ich mutig vor, alle Zeitüberschreitungen aus kubeadm selbst zu entfernen (die verschiedenen Phasen sollten für immer wiederholt werden) und mich auf den übergeordneten Prozess zu verlassen, um gegebenenfalls eine Gesamtzeitüberschreitung in diesem übergeordneten Kontext hinzuzufügen. Im einfachen / direkten Anwendungsfall ist dies der Fall würde bedeuten "erneut versuchen, bis der Benutzer aufgibt und ^ c drückt". Wäre eine solche PR akzeptabel?

@anguslees Wir hatten früher das Verhalten "ewig warten"; Aber das war von einem UX PoV sehr suboptimal, also haben wir jetzt Timeouts. Wenn Sie möchten, möchten wir möglicherweise einige dieser Zeitüberschreitungen erhöhen.

Das Problem ist, dass die Verwendung von kubeadm zweifach ist. Wir haben beide Benutzer, die kubeadm interaktiv eingeben und wissen möchten, ob etwas passiert oder nicht, und übergeordnete Verbraucher.

.. Also, in welche Richtung werden wir hier gehen? Derzeit verwende ich eine Abzweigung von kubeadm , bei der zahlreiche Zeitüberschreitungen um das 10-fache erhöht wurden, und ich würde gerne glauben, dass ich irgendwann wieder Standard-Binärdateien von kubeadm verwenden kann.

@anguslees Wir hatten früher das Verhalten "ewig warten"; Aber das war von einem UX PoV sehr suboptimal, also haben wir jetzt Timeouts. Wenn Sie möchten, möchten wir möglicherweise einige dieser Zeitüberschreitungen erhöhen.

Wie wäre es, sie konfigurierbar zu machen? Ist es sinnvoll, eine einzige Option zu haben, die alle besitzt?

/ Priorität wichtig - bald

Ist es sinnvoll, eine einzige Option zu haben, die alle besitzt?

Wahrscheinlich oder eine Art "Gewicht" für alle Timeouts, mit denen multipliziert werden soll ... Andernfalls kommen wir mit 20 verschiedenen Arten von Timeout-Flags in die Konfigurationshölle :)

Das gleiche Problem tritt mit dem kubeadm-Upgrade auf dem Himbeer-Pi-2-Cluster auf. Das Upgrade schlägt aufgrund aggressiver Zeitüberschreitungen fehl. Das Ändern der Einstellungen der Lebendigkeitssonde in den Manifesten hilft nicht. Irgendwelche Ideen?

Ich schlage immer noch ein Muster vor, bei dem jedes Kubeadm-Timeout vom aufrufenden Kontext (oder Teil einer ausgefeilteren Fehlerbehebungsstrategie) geerbt wird, anstatt willkürliche Timeouts auf die unteren Ebenen der Kubeadm-Codebasis zu verteilen.

In seiner einfachsten Form würde sich dies fast genau so verhalten, als würden alle Zeitüberschreitungen aus kubeadm entfernt und durch einen globalen Zeitgeber "Lauf für xx Minuten, dann Abbruch, wenn nicht beendet" ersetzt (da kubeadm nicht viel an Fehlern tun kann Erholung anders als nur länger warten).

Für die ursprünglichen Manifest LivenessProbe-Timeouts ist es buchstäblich ein Einzeiler-Patch. Leider reicht es nicht mehr aus, die livenessProbe allein zu reparieren, da sich der Irrtum "Abweichung vom normalen == Fehler" in der gesamten kubeadm-Codebasis weiter ausgebreitet hat. Kulturelle Bewusstsein zu ändern ist hart, so in der Zwischenzeit habe ich eine gegabelt Version von kubeadm haben hier , wenn jemand will nur auf eine Himbeere pi installieren. (Bauen mit make cross WHAT=cmd/kubeadm KUBE_BUILD_PLATFORMS=linux/arm )

@anguslees Hast du eine kompilierte 1.9.4-Version deines gepatchten kubeadm? Ich habe Probleme beim Kompilieren Ihrer gepatchten Version.

Ich bin überrascht, dass kubeadm dieses Verhalten nicht hinter einer Flagge hat. Vielleicht ist eine PR angebracht?

/ @liztio zuweisen

Daher haben wir in 1.11 zwei Probleme behoben, die sich darauf auswirken könnten.

  1. Bereiten Sie das etcd-Image vor dem Start vor.
  2. Korrigieren Sie die Überprüfung der Rennbedingungen beim Start.
    ...

Wenn dies nur bei Himbeer-Pi-Gear geschieht, brauchen wir eine Möglichkeit, einen kleinsten gemeinsamen Nenner zu qualifizieren.

Was ist die niedrigste Zielplattform, die wir unterstützen möchten?

Ich denke, Raspberry Pi 2 ist die niedrigste Plattform, auf der Sie Kubernetes ausführen möchten. Meine Tests mit nicht hardwareunterstützter QEMU sind zu exotisch, um berücksichtigt zu werden.

In Anbetracht der Tatsache, dass der Pi häufig unter langsamen E / A-Vorgängen leidet, hilft das Vorabziehen aller Bilder bereits sehr, aber wir benötigen einige Tests in der Praxis, um die tatsächlichen Zeitüberschreitungen zu ermitteln.

imo rasberry pi2 ist zu alt, um es zu unterstützen - http://socialcompare.com/de/comparison/raspberrypi-models-comparison , erschien 2015.

>= 3 scheint imo vernünftiger zu sein.

Das Vorbereiten von Bildern hilft nicht. Der livenessProbe-Timer startet erst, nachdem das Bild gezogen wurde (wie oben erwähnt ).

Das Update dient

Bearbeiten: Und um klar zu sein, es ist nur der Start, der ewig dauert - mein Kontrollcluster arbeitet einwandfrei mit 3xRPi2, sobald ich das Apiserver-Zeitlimit für intialDelaySeconds (und andere Zeitlimits nur für die Installation, die in kubeadm selbst verwendet werden) erhöhe. Ich verstehe nicht, warum wir immer noch darüber reden: /

Ich habe einen ARM64-Cluster unter 1.9.3 und erfolgreich auf 1.9.7 aktualisiert, habe jedoch das Timeout-Problem beim Upgrade von 1.9.7 auf 1.10.2.

Ich habe sogar versucht, kubeadm zu bearbeiten und neu zu kompilieren, um die Zeitüberschreitungen zu erhöhen (wie diese letzten Commits https://github.com/anguslees/kubernetes/commits/kubeadm-gusfork), mit denselben Ergebnissen.

$ sudo kubeadm upgrade apply  v1.10.2 --force
[preflight] Running pre-flight checks.
[upgrade] Making sure the cluster is healthy:
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[upgrade/version] You have chosen to change the cluster version to "v1.10.2"
[upgrade/versions] Cluster version: v1.9.7
[upgrade/versions] kubeadm version: v1.10.2-dirty
[upgrade/version] Found 1 potential version compatibility errors but skipping since the --force flag is set:

   - Specified version to upgrade to "v1.10.2" is higher than the kubeadm version "v1.10.2-dirty". Upgrade kubeadm first using the tool you used to install kubeadm
[upgrade/prepull] Will prepull images for components [kube-apiserver kube-controller-manager kube-scheduler]
[upgrade/apply] Upgrading your Static Pod-hosted control plane to version "v1.10.2"...
Static pod: kube-apiserver-kubemaster1 hash: ed7578d5bf9314188dca798386bcfb0e
Static pod: kube-controller-manager-kubemaster1 hash: e0c3f578f1c547dcf9996e1d3390c10c
Static pod: kube-scheduler-kubemaster1 hash: 52e767858f52ac4aba448b1a113884ee
[upgrade/etcd] Upgrading to TLS for etcd
Static pod: etcd-kubemaster1 hash: 413224efa82e36533ce93e30bd18e3a8
[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests346927148/etcd.yaml"
[certificates] Using the existing etcd/ca certificate and key.
[certificates] Using the existing etcd/server certificate and key.
[certificates] Using the existing etcd/peer certificate and key.
[certificates] Using the existing etcd/healthcheck-client certificate and key.
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/etcd.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests190581659/etcd.yaml"
[upgrade/staticpods] Not waiting for pod-hash change for component "etcd"
[upgrade/etcd] Waiting for etcd to become available
[util/etcd] Waiting 30s for initial delay
[util/etcd] Attempting to get etcd status 1/10
[util/etcd] Attempt failed with error: dial tcp 127.0.0.1:2379: getsockopt: connection refused
[util/etcd] Waiting 15s until next retry
[util/etcd] Attempting to get etcd status 2/10
[util/etcd] Attempt failed with error: dial tcp 127.0.0.1:2379: getsockopt: connection refused
[util/etcd] Waiting 15s until next retry
[util/etcd] Attempting to get etcd status 3/10
[util/etcd] Attempt failed with error: dial tcp 127.0.0.1:2379: getsockopt: connection refused
[util/etcd] Waiting 15s until next retry
[util/etcd] Attempting to get etcd status 4/10
[upgrade/staticpods] Writing new Static Pod manifests to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests346927148"
[controlplane] Wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests346927148/kube-apiserver.yaml"
[controlplane] Wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests346927148/kube-controller-manager.yaml"
[controlplane] Wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests346927148/kube-scheduler.yaml"
[upgrade/staticpods] The etcd manifest will be restored if component "kube-apiserver" fails to upgrade
[certificates] Using the existing etcd/ca certificate and key.
[certificates] Using the existing apiserver-etcd-client certificate and key.
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-apiserver.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests190581659/kube-apiserver.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/apply] FATAL: couldn't upgrade control plane. kubeadm has tried to recover everything into the earlier state. Errors faced: [timed out waiting for the condition]

Wenn kubeadm verwendet wird und der Apiserver gestartet wird, können wir versuchen, Punkte beim ersten Start zu messen. Vielleicht ändern wir die Konfiguration in einem späteren Stadium für die Zeitüberschreitungen, die bei der ersten Initialisierung an die Messungen angepasst wurden. Es ist auch schwer herauszufinden, dass der Apiserver durch den Healtz-Check, der sich die Protokolle ansieht, getreten wird. Möglicherweise erhalten wir zumindest eine bessere Protokollierung, um uns des Problems bewusst zu werden. Es dauerte einige Zeit, bis ich herausfand, dass die Lebendigkeitsprobe das Problem war. Ich muss erwähnen, dass ich ein Anfänger bin, und das wäre zumindest hilfreich, um irgendwo auf der Fehlerausgabe für kubeadm erwähnt zu werden.

RaspberryPi 3 zeigt dieses Problem auch bei vorab gezogenen Bildern. Der API-Server benötigt 2-3 Minuten, um an einen Ort zu gelangen, an dem eine Seite bereitgestellt werden kann ...

Es wäre großartig, wenn dies konfigurierbar wäre, da ich gerade die YAML-Datei im Hintergrund patche, während kubeadm ausgeführt wird.

@carlosedp Was ich während eines Upgrades mache, ist das Kubelet herunterzufahren, während der Apiserver bootet. Es ist ein bisschen hackig, aber es verhindert, dass der Gesundheitscheck ausgelöst wird, bis der Apiserver hoch ist.

Aber ehrlich gesagt arbeiten kubeadm upgrade und ARM meiner Erfahrung nach einfach nicht so gut zusammen ...

@brendandburns Es hat perfekt funktioniert bis 1.9. Ich habe meinen 1.8-Cluster ohne Probleme bereitgestellt und dann zweimal auf 1.9 aktualisiert. Keine Ahnung, was sich in 1.10 geändert haben könnte, um diese Probleme zu verursachen.

Ich habe gesehen, dass sich das Zeitlimit in 1,11 auf 5 Minuten geändert hat (https://github.com/kubernetes/kubernetes/pull/64988/files#diff-2056df5f0c3a4828b3f9a2510a7533c7L45). Haben Sie es mit 1.11 versucht?

Ich werde diesen Hack versuchen, nachdem ich aus den Ferien zurückgekehrt bin. Danke für den Tipp!

@brendandburns @carlosedp
Ja, bitte versuchen Sie 1.11, um zu bestätigen, dass die Erhöhung des Zeitlimits eine Lösung für Sie ist.

/ cc @ kubernetes / sig-cluster-lifecycle-bugs

Hallo! Ich stoße auch auf dieses Problem.
Interessanterweise kann ich auf meinem Raspberry 3 einen Cluster-Master von Grund auf neu erstellen, auf meinem 3+ jedoch nicht.
Wie auch immer, die Version, die ich derzeit verwende (gemäß der schrittweisen Dokumentation unter https://blog.hypriot.com/post/setup-kubernetes-raspberry-pi-cluster/)
kubeadm version: &version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.0", GitCommit:"91e7b4fd31fcd3d5f436da26c980becec37ceefe", GitTreeState:"clean", BuildDate:"2018-06-27T20:14:41Z", GoVersion:"go1.10.2", Compiler:"gc", Platform:"linux/arm"}

Wie bei den anderen steht der Apiserver-Container zwar irgendwann auf, aber nicht bevor Kubeadm aussteigt, und lässt mich in der Schwebe, da ich zu unerfahren bin, um von dort manuell abzuholen.

Schnelles Update: läuft
watch -n 1.0 "sed -i 's/initialDelaySeconds: [0-9]\+/initialDelaySeconds: 180/' /etc/kubernetes/manifests/kube-apiserver.yaml"
In einem separaten Terminal konnte mein Cluster aufstehen.

@ DJGummikuh
danke fürs testen 1.11.

Wie bei den anderen steht der Apiserver-Container zwar irgendwann auf, aber nicht bevor Kubeadm aussteigt, und lässt mich in der Schwebe, da ich zu unerfahren bin, um von dort manuell abzuholen.

Wie lange dauert es in Ihrem Fall, bis der Apiserver startet?
Es scheint, dass wir dies möglicherweise konfigurierbar machen müssen.

Es ist schwer zu sagen, ich würde ungefähr 1 Minute schätzen, aber ich weiß nicht, wie ich das richtig messen soll.

Da mein Master jetzt betriebsbereit ist, kann ich ihm keinen Knoten hinzufügen, was ein weiteres Timeout-Problem zu sein scheint.
`[Preflight] Vor-Flug-Checks durchführen
[WARNUNG Erforderlich IPVSKernelModulesAvailable]: Der IPVS-Proxier wird nicht verwendet, da die folgenden erforderlichen Kernelmodule nicht geladen werden: [ip_vs_rr ip_vs_wrr ip_vs_sh ip_vs] oder kein integrierter Kernel nf_conntrack_ipv4: {} ip_vs: {}]
Sie können dieses Problem mit folgenden Methoden lösen:

  1. Führen Sie 'modprobe -' aus, um fehlende Kernelmodule zu laden.

    1. Stellen Sie die fehlende integrierte Kernel-IPvs-Unterstützung bereit

I0708 19: 02: 20.256325 8667 kernel_validator.go: 81] Überprüfen der Kernelversion
I0708 19: 02: 20.256846 8667 kernel_validator.go: 96] Überprüfen der Kernelkonfiguration
[WARNUNG SystemVerification]: Die Docker-Version ist größer als die zuletzt validierte Version. Docker-Version: 18.03.1-ce. Max validierte Version: 17.03
[Erkennung] Versuch, eine Verbindung zum API-Server herzustellen "192.168.2.2:6443"
[Erkennung] Erstellt einen Cluster-Info-Erkennungsclient, der Informationen von " https://192.168.2.2 : 6443" anfordert.
[Discovery] Fordern Sie erneut Informationen von " https://192.168.2.2 : 6443" an, um TLS anhand des angehefteten öffentlichen Schlüssels zu überprüfen
[Erkennung] Die Signatur und der Inhalt der Clusterinformationen sind gültig und das TLS-Zertifikat wird anhand von angehefteten Wurzeln überprüft. Der API-Server "192.168.2.2:6443" wird verwendet.
[Erkennung] Verbindung mit API-Server "192.168.2.2:6443" erfolgreich hergestellt
[kubelet] Herunterladen der Konfiguration für das Kubelet aus der ConfigMap "kubelet-config-1.11" im Namespace des Kubesystems
[kubelet] Schreiben der Kubelet-Konfiguration in die Datei "/var/lib/kubelet/config.yaml"
[kubelet] Schreiben einer Kubelet-Umgebungsdatei mit Flags in die Datei "/var/lib/kubelet/kubeadm-flags.env"
[Preflight] Aktivieren des Kubelet-Dienstes
[tlsbootstrap] Warten auf das Kubelet, um den TLS-Bootstrap auszuführen ...
[Kubelet-Check] Es scheint, als ob das Kubelet nicht läuft oder gesund ist.
[Kubelet-Check] Es scheint, als ob das Kubelet nicht läuft oder gesund ist.
[Kubelet-Check] Es scheint, als ob das Kubelet nicht läuft oder gesund ist.
[Kubelet-Check] Es scheint, als ob das Kubelet nicht läuft oder gesund ist.
[Kubelet-Check] Es scheint, als ob das Kubelet nicht läuft oder gesund ist.
Leider ist ein Fehler aufgetreten:
Zeitüberschreitung beim Warten auf den Zustand

Dieser Fehler wird wahrscheinlich verursacht durch:
- Das Kubelet läuft nicht
- Das Kubelet ist aufgrund einer Fehlkonfiguration des Knotens in irgendeiner Weise ungesund (erforderliche cgroups deaktiviert)

Wenn Sie sich auf einem systemd-basierten System befinden, können Sie versuchen, den Fehler mit den folgenden Befehlen zu beheben:
- 'systemctl status kubelet'
- 'journalctl -xeu kubelet'
Wartezeit auf die Bedingung "

Während dieser Zeit wird auf meinem Knoten kein einziger Docker-Container angezeigt.

[WARNUNG ErforderlichIPVSKernelModulesAvailable]:

offtopic, wir sprechen hier darüber:
https://github.com/kubernetes/kubeadm/issues/975

Da mein Master jetzt betriebsbereit ist, kann ich ihm keinen Knoten hinzufügen, was ein weiteres Timeout-Problem zu sein scheint.
[kubelet-check] Der HTTP-Aufruf gleich 'curl -sSL http: // localhost : 10248 / healthz' ist mit folgendem Fehler fehlgeschlagen: Get http: // localhost : 10248 / healthz: Wählen Sie tcp [:: 1]: 10248: connect : Verbindung abgelehnt.

Das Kubelet konnte nicht starten. Schauen Sie sich besser die Kubelet-Protokolle an.

- 'systemctl status kubelet'
- 'journalctl -xeu kubelet'

Die Liveness-Sonde sollte konfigurierbar gemacht werden, aber wir sollten wahrscheinlich in der kubeadm-Konfiguration darüber sprechen, wie dies am besten funktioniert.

Ich denke, dies sind die verwendeten Werte. Wenn Sie also selbst Kubeadm bauen, versuchen Sie, mit folgenden Elementen zu spielen:
https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/util/staticpod/utils.go#L95 -L96
Beachten Sie jedoch, dass dies die Zeitüberschreitungen für alle Komponenten der Steuerebene erhöhen würde.

Edit: Ich bin anscheinend zu dumm, um Kommentare in Github richtig zu formatieren :-(

Here are the log outputs of both systemctl status kubelet and journalctl -xeu kubelet. "No cloud provider specified is the only thing that springs to eye.

`root@djg-clusterpi3:/home/djgummikuh# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: active (running) since Sun 2018-07-08 19:55:15 CEST; 2min 12s ago
     Docs: http://kubernetes.io/docs/
 Main PID: 9233 (kubelet)
   Memory: 14.4M
      CPU: 17.064s
   CGroup: /system.slice/kubelet.service
           └─9233 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --cgroup-driver=cgroupfs --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --network-pl

Jul 08 19:55:15 djg-clusterpi3 systemd[1]: Started kubelet: The Kubernetes Node Agent.
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more inform
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: I0708 19:55:15.665304    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more inform
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: I0708 19:55:15.675950    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: I0708 19:55:15.676273    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:31 djg-clusterpi3 kubelet[9233]: I0708 19:55:31.963686    9233 server.go:408] Version: v1.11.0
Jul 08 19:55:31 djg-clusterpi3 kubelet[9233]: I0708 19:55:31.964029    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:31 djg-clusterpi3 kubelet[9233]: I0708 19:55:31.964378    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:31 djg-clusterpi3 kubelet[9233]: I0708 19:55:31.965040    9233 plugins.go:97] No cloud provider specified.






Jul 08 19:55:15 djg-clusterpi3 systemd[1]: Started kubelet: The Kubernetes Node Agent.
-- Subject: Unit kubelet.service has finished start-up
-- Defined-By: systemd
-- Support: https://www.debian.org/support
-- 
-- Unit kubelet.service has finished starting up.
-- 
-- The start-up result is done.
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more inform
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: I0708 19:55:15.665304    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more inform
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: I0708 19:55:15.675950    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:15 djg-clusterpi3 kubelet[9233]: I0708 19:55:15.676273    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:31 djg-clusterpi3 kubelet[9233]: I0708 19:55:31.963686    9233 server.go:408] Version: v1.11.0
Jul 08 19:55:31 djg-clusterpi3 kubelet[9233]: I0708 19:55:31.964029    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:31 djg-clusterpi3 kubelet[9233]: I0708 19:55:31.964378    9233 feature_gate.go:230] feature gates: &{map[]}
Jul 08 19:55:31 djg-clusterpi3 kubelet[9233]: I0708 19:55:31.965040    9233 plugins.go:97] No cloud provider specified.`

Bitte beachten Sie, dass diese Protokolle keine Fehler enthalten.

Ja, aber das ist ein Teil des Problems, glaube ich. Ich kann anfangs nirgendwo eine einzige schlüssige Zeile von [ERROR] finden. Das frustriert mich so sehr :-)

Wie auch immer, danke, dass du mein Durcheinander formatiert hast :-D

Was wäre also ein guter nächster Schritt?

Was wäre also ein guter nächster Schritt?

Wie zuvor genannt:

Die Liveness-Sonde sollte konfigurierbar gemacht werden, aber wir sollten wahrscheinlich in der kubeadm-Konfiguration darüber sprechen, wie dies am besten funktioniert.

Ich denke, dies sind die verwendeten Werte. Wenn Sie also selbst Kubeadm bauen, versuchen Sie, mit folgenden Elementen zu spielen:
https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/util/staticpod/utils.go#L95 -L96
Beachten Sie jedoch, dass dies die Zeitüberschreitungen für alle Komponenten der Steuerebene erhöhen würde.

Wenn ich kubeadm nicht selbst baue, ziehe ich es über apt von apt.kubernetes.io. Ich habe nichts, was einer Build-Pipeline für einen meiner Computer im entferntesten ähnelt (noch nie daran herumgebastelt). Ich hoffte, dass es eine ähnliche Datei geben würde, die geändert werden könnte, wenn ich einem Cluster beitrete, wie es zum Erstellen vorhanden war, aber wie es scheint, sind diese Werte in utils.go fest codiert: - |

Sie können diese Lösung ausprobieren, aber es ist schwierig:
https://github.com/kubernetes/kubeadm/issues/413#issuecomment -402916173

Das Problem ist, dass dies eine Konfigurationsänderung erfordert und ich glaube nicht, dass es in einer 1.11.X-Version enthalten sein kann (aber wir können es versuchen). es muss auch zuerst besprochen werden.

Das habe ich bereits in dem Kommentar getan, in dem ich Ihnen gesagt habe, dass der Master aktiv ist (genau das hat mein Befehl watch -n 1.0 getan). Was jetzt passiert ist, dass kubeadm join nicht funktioniert, und soweit ich sehen kann, platziert kubeadm join keine yaml-Dateien, die ich irgendwo patchen kann: - /

Möglicherweise tritt ein anderes Problem auf. schwer zu sagen.

Dies sind die verwendeten Werte. Wenn Sie also selbst kubeadm erstellen, versuchen Sie, mit folgenden Elementen zu spielen:
https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/util/staticpod/utils.go#L95 -L96

Ich stelle also fest, dass das Zeitlimit für InitialDelaySeconds hier ein Jahr später noch 15 Sekunden beträgt, und ich verstehe nicht, warum es nicht auf etwas erhöht wurde, das tatsächlich die Realität darstellt. Hat dieser Fehlerbericht überhaupt einen Zweck? Ich habe anfangs keine PR vorgeschlagen, um diese Nummer selbst zu ändern, weil ich der Meinung war, dass jemand, der sich bereits im inneren Kreis von kubeadm befindet, dies in wenigen Minuten erledigen und zusammenführen könnte, aber ich bin froh, dies zu tun, wenn "PR fehlt" Der einzige Grund, warum wir uns nicht weiterentwickelt haben.

Ich habe das Gefühl, dass jeder versucht, Gründe zu finden, um den ursprünglichen Fehlerbericht für ungültig zu erklären (vielleicht sollten wir rPi2 nicht unterstützen, vielleicht sollten wir die anfängliche Verzögerung konfigurierbar machen, vielleicht sollten wir Bilder oder eine andere nicht verwandte Änderung vorab abrufen, vielleicht a Ein schneller undurchsichtiger Timeout-Fehler ist eine bessere UX als ein langsamerer Erfolg. Statt nur das InitialDelay-Timeout zu erhöhen, um das tatsächliche InitialDelay widerzuspiegeln, das unsere Binärdateien deutlich aufweisen, und dann zu etwas anderem überzugehen, das tatsächlich eine Diskussion verdient.

Daher stelle ich fest, dass das Zeitlimit für InitialDelaySeconds hier noch 15 Sekunden pro Jahr beträgt, und ich verstehe nicht, warum es nicht auf etwas erhöht wurde, das tatsächlich die Realität darstellt. Hat dieser Fehlerbericht überhaupt einen Zweck? Ich habe anfangs keine PR vorgeschlagen, um diese Nummer selbst zu ändern, weil ich der Meinung war, dass jemand, der sich bereits im inneren Kreis von kubeadm befindet, dies in wenigen Minuten erledigen und zusammenführen könnte, aber ich bin froh, dies zu tun, wenn "PR fehlt" Der einzige Grund, warum wir uns nicht weiterentwickelt haben.

Ich kann Ihre Fragen nicht beantworten, da das ganze Thema für mich neu ist, aber wir können versuchen, diese Woche darüber zu sprechen. Bitte beachten Sie, dass das Team hinter kubeadm ein kleines Team mit großen Zielen ist und oft niemand an einer bestimmten Aufgabe wie dieser arbeiten kann.

Ich habe das Gefühl, dass jeder versucht, Gründe zu finden, um den ursprünglichen Fehlerbericht für ungültig zu erklären (vielleicht sollten wir rPi2 nicht unterstützen, vielleicht sollten wir die anfängliche Verzögerung konfigurierbar machen, vielleicht sollten wir Bilder oder eine andere nicht verwandte Änderung vorab abrufen, vielleicht a Ein schneller undurchsichtiger Timeout-Fehler ist eine bessere UX als ein langsamerer Erfolg. Statt nur das InitialDelay-Timeout zu erhöhen, um das tatsächliche InitialDelay widerzuspiegeln, das unsere Binärdateien deutlich aufweisen, und dann zu etwas anderem überzugehen, das tatsächlich eine Diskussion verdient.

Ja, Optionen wurden bereits in diesem Thread besprochen. Es geht darum, die richtige Option auszuwählen und die Implementierung durchzuführen.

Ich glaube tatsächlich, dass es sinnvoll wäre, standardmäßig "kein Zeitlimit" zu verwenden, mit der Option, ein Zeitlimit für den gesamten Prozess festzulegen (wie irgendwo früher in dieser Ausgabe vorgeschlagen).

Der Grund dafür ist, dass es den meisten Anwendungsfällen, an die ich denken kann, eigentlich egal ist, ob ein bestimmter Schritt in X Sekunden ausgeführt wird oder nicht, da in einem verteilten System nur die Konsistenz berücksichtigt wird (das Aufspulen eines anderen Knotens für den Fall, dass dies billiger ist als mit den Einstellungen herumzuspielen).

Als Zwischenlösung würde es jedoch ausreichen, die Timeout-Einstellungen für kubeadm join tatsächlich aus einer Konfigurationsdatei zu lesen, genau wie das kubeadm init-Zeug, damit unser Hack mit dem Austausch des Inflight-Timeouts funktioniert. Es ist ein Hack, denken Sie nicht anders - aber ein schrecklicher Hack ist immer noch besser als gar keine Problemumgehung.

Ich persönlich bin gegen den Versuch, vernünftige Zeitüberschreitungen zu "erraten", da Vermutungen immer falsch sein können, in diesem Fall keinen wirklichen Zweck erfüllen würden (da die Bewältigungsstrategie für verstrichene Zeitüberschreitungen einfach aus dem Ruder läuft) und die Reproduktion von Fehlern zu einem Problem machen würde Es sei denn, zwei identische Systeme könnten sich aus einer Vielzahl von Gründen unterschiedlich verhalten.

@anguslees @DJGummikuh darüber haben wir auf dem letzten SIG-Treffen gesprochen.

Dies ist ein heikles Problem, aber hier sind einige zufällige Notizen unten.

Anmerkungen:

  • Einige unserer Leute haben viel Erfahrung und sie sagen, dass dies nach einer Rennbedingung riecht, die den Start des Apiservers blockiert. es sollte nicht so lange dauern. Dies könnte eine Sache zwischen ARM und GOLANG sein.
  • Ich habe die SIG API Machinery gefragt, aber keine Antwort auf die vorgeschlagenen Werte für die Lebendigkeitssonde erhalten und ob sie hier eine andere Art von Problem vermuten.
  • Wir sind uns einig, dass das Anzeigen einer Konfigurationsoption, einer Umgebungsvariablen oder eines Befehlszeilenparameters für kubeadm eine schlechte Idee ist . Der Grund dafür ist, dass wir keine Parameter offenlegen wollen, die für Benutzer eine völlig willkürliche Bedeutung haben können.
  • Niemand im Team hat jemals ein solches Problem auf langsamen Maschinen (z. B. langsamen VMs) gesehen, was bedeutet, dass dies mit RPi zusammenhängen könnte und das gesamte Argument, dass dies auf "langsame" Hardware zurückzuführen ist, ungültig ist.
  • Schauen Sie sich das an: https://github.com/kubernetes/kubernetes/issues/64357 Der Benutzer meldet überhaupt kein Problem mit der Lebendigkeitsprobe. Irgendeine Idee, warum das so ist?
  • Hat jemand ein Problem auf so etwas wie https://www.scaleway.com/ gesehen , laut der Theorie in diesem Thread sollte es auch dort passieren?
  • Unter dem Strich haben wir besprochen, dass das Hardcodieren größerer Timeout- / Delay-Werte für kubeadm nicht allzu wichtig ist. Wenn also jemand eine PR dafür einreichen möchte, fahren Sie fort. ( @anguslees )

Schauen Sie sich das an: kubernetes / kubernetes # 64357 Der Benutzer meldet überhaupt kein Problem mit der Lebendigkeitsprüfung. Irgendeine Idee, warum das so ist?

Nein, es scheint jetzt auf meiner Hardware nicht einmal wirklich reproduzierbar zu sein. Da das Token für das Verbinden von Knoten abgelaufen ist, dachte ich, "was zum Teufel" und kubeadm setzten meinen Cluster-Master zurück und versuchten, ihn neu zu initiieren (mit dieser Watch-Problemumgehung) - jetzt kann ich selbst mit dieser Problemumgehung nicht mehr aufrufen ein Meister auf meinem Raspberry Pi 3+. Ich habe sogar das konfigurierte Timeout ohne Unterschied von 180 auf 300 Sekunden erhöht. Ich mag die Idee, dass dies eine Rennbedingung ist.
Trotzdem begrüße ich Ihren Vorschlag, höhere Zeitüberschreitungen anzufordern. Wird nicht viel weh tun und gibt dem Pi (was eine langsame Hardware ist, da können wir uns alle einig sein :-)) etwas mehr Raum zum Atmen.

verwandtes Problem auf ARM64 im Apiserver:
https://github.com/kubernetes/kubernetes/issues/64649

Habe über das Wochenende mehr Nachforschungen mit meinem (immer noch fehlgeschlagenen :-() Pi-Cluster angestellt.

Ich habe einen meiner Knoten neu installiert, da ich den Verdacht hatte, dass ein Update von einem Pi 2 auf einen Pi 3+ ohne Neuinstallation des Betriebssystems einige Probleme verursachen könnte. Dies ist nicht der Fall, das Problem ist das gleiche mit dem brandneuen Betriebssystem.
Außerdem habe ich mir die Mühe gemacht, Kubernetes mit den erhöhten Timeouts zu kompilieren und damit zu testen. Auch dies ergab kein wirkliches Ergebnis.
Ich konnte den Master einrichten (mit meiner Watch-Problemumgehung zum Patchen der Konfigurationsdateien), aber der Beitritt zum Cluster mit dem zweiten Knoten ist einfach nie erfolgreich.

Es wäre wirklich ordentlich, eine zusätzliche nützliche Protokollausgabe zu haben, um dieses Problem zu beheben. Ich verstehe jedoch nicht genug darüber, wie die Kubernetes-Komponenten interagieren, um zu wissen, wo Zeilen hinzugefügt werden müssen.

Ist jemand bereit für die Herausforderung? ^^

das ist wirklich ein problem außerhalb von kubeadm ...

Die Leute von der API-Maschinerie haben meine Anfrage nach Kommentaren zu diesem Problem nicht geprüft. Wenn also noch kein Ticket dafür angemeldet ist, sollte jemand eines im kubernetes/kubernetes Repo anmelden und /sig api-machinery markieren.

Es wäre wirklich ordentlich, eine zusätzliche nützliche Protokollausgabe zu haben, um dieses Problem zu beheben. Ich verstehe jedoch nicht genug darüber, wie die Kubernetes-Komponenten interagieren, um zu wissen, wo Zeilen hinzugefügt werden müssen.

Zu Beginn kann --v 4 für das Kubelet in der Dropdown-Datei systemd aktiviert werden, wodurch der GLOG-Logger angewiesen wird, eine hohe Ausführlichkeit zu aktivieren.
Das Gleiche kann man auch für Steuerebenenkomponenten aus der kubeadm-Konfiguration tun:
https://kubernetes.io/docs/setup/independent/control-plane-flags/

Dies löste das Problem auf meinem Raspberry Pi 3-Cluster: https://github.com/kubernetes/kubernetes/pull/66264

@joejulian nett Ich habe es geschafft, das zu patchen und jetzt wird auch mein Cluster

@ Joejulian danke für die Untersuchung!
Eine mögliche Lösung finden Sie unter https://github.com/kubernetes/kubernetes/pull/66264

bis auf weiteres schließen.

/schließen

Gibt es eine Möglichkeit, solche Einstellungen in der kubeadm init-Datei zu übergeben? vielleicht in apiServerExtraArgs ? Es ist ein Schmerz, Dateien zu beobachten, um sie zu patchen, was schwer zu automatisieren ist.

Da ist nicht. Vielleicht wäre das eine gute Funktion, um hinzuzufügen.

Spätere Updates haben noch mehr Dinge hinzugefügt, die überprüft werden müssen, und das verlängerte Timeout, das meine PR bereitgestellt hat, war nicht mehr ausreichend. Ich habe es aufgegeben, das Timeout zu verwalten. Die Lösung für mich war die Verwendung von ecdsa-Zertifikaten.

Außerdem belegen die Controller-Dienste einschließlich etcd jetzt mehr RAM als ein Raspberry Pi. Statt die doppelte Anzahl von Knoten zum Hosten der Steuerebene zu haben, habe ich auf Rock64s aktualisiert.

Entschuldigen Sie das Wortspiel, aber mein Kontrollflugzeug ist seitdem absolut stabil.

Ich habe gerade versucht, eine Installation auf einem Raspberry Pi 3+ durchzuführen, und kann bestätigen, dass die Installation tatsächlich fehlschlägt. Die Verwendung des Tricks 'watch' auf der oben aufgeführten Datei kube-apiserver.yaml scheint konsistent zu funktionieren ... aber nur, wenn ich die initialDelaySeconds auf 360 ändere. Der vorgeschlagene Wert von 180 scheint auf meinen Computern marginal zu sein.

Gerade wenn es zu einfach wird, beschwert sich kubeadm jetzt darüber, dass die Version von Docker (18.09) nicht unterstützt wird. Ein schneller Rückblick auf 18.06 behebt das Problem.

In kubeadm 1.13 fügen wir unter ClusterConfig-> ApiServer ein Konfigurationsflag hinzu, das das Zeitlimit des API-Servers steuern kann.
https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1
timeoutForControlPlane

Konfigurationsflag unter ClusterConfig-> ApiServer, der das Timeout des API-Servers steuern kann.

Wenn ich die Codebasis nach TimeoutForControlPlane durchsuche, ist dies standardmäßig 4 Minuten und wird nur für die Verzögerung verwendet, die kubeadm selbst verwendet, um darauf zu warten, dass der Apiserver gesund wird. Insbesondere ändert es nicht die von Kubelet selbst verwendete Apiserver-Lebendigkeitssonde. Ist das korrekt?

Ich glaube nicht, dass ich irgendwo in der Diskussion um dieses Thema ein Gegenargument gesehen habe. Gibt es einen Grund, warum wir nicht nur die LivenessProbe initialDelaySeconds erhöhen und zu einem anderen Problem übergehen?

Nebenbei: Soweit ich aus einer kurzen Lektüre ersehen kann, berücksichtigt TimeoutForControlPlane auch keine anderen Fehlerursachen für eine erhöhte Startverzögerung des Apiservers, wie z. B. Überlastung beim Abrufen mehrerer Bilder oder zusätzliche Zeitüberschreitung + Wiederholungsschleife Iterationen, während bei der Erstinstallation alles konvergiert (Timeout + Wiederholungsversuch wiederholt ist das Entwurfsmuster des k8s ... und dies geschieht manchmal auf einem geladenen System, was erwartet wird und in Ordnung ist). Ich persönlich bin der Meinung, dass 4 Minuten sowohl zu lang für ungeduldige interaktive Benutzer sind, die einen schnellen Fehler erwarten, als auch zu kurz für einen Installationsprozess auf einem geladenen / langsamen / automatisierten System, das bereit ist, länger auf den erwarteten Erfolg zu warten. Wie kam es dazu, können wir standardmäßig 5 Minuten verwenden? Können wir es bis SIGINT wiederholen? Warum setzen wir intern eine künstliche Wanduhr-Frist fest, anstatt sie von der Anrufumgebung zu erben?

Afaics TimeoutForControlPlane legt lediglich eine willkürliche schwerwiegende interne Frist als Parameter offen,

Das ist ein ausgezeichneter Punkt und ich stimme voll und ganz zu.

Insbesondere ändert es nicht die Apiserver-Lebendigkeitssonde, die von Kubelet selbst verwendet wird. Ist das korrekt?

Ja, es gibt noch keine Pläne, die Lebendigkeitssonden von kubeadm zu modifizieren.

Dieses RPI-Problem wurde bei einem Sig-Cluster-Lifecyle-Meeting als "etwas, das nicht passieren sollte", "scheint fast wie eine Rennbedingung im Kubelet", "warum passiert es nur auf RPI und nicht auf anderen langsameren Geräten" qualifiziert. Ich muss zugeben, dass ich langsame Geräte nicht selbst getestet habe.

dh es gab eine Vereinbarung, diesen Wert zu erhöhen:
https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/util/staticpod/utils.go#L97
ist keine gute Lösung und es scheint eine Problemumgehung für einen anderen Fehler zu sein.

Wie kam es dazu, können wir standardmäßig 5 Minuten verwenden?

Das Zeitlimit betrug 30 Minuten vor 4 Minuten, da das Ziehen von Bildern vor 1.11 berücksichtigt wurde.
Wenn Sie eine Meinung zu 4 gegen 5 Minuten haben, könnte eine gut umrissene PR mit Stärken zu diesem Thema es in 1.14 schaffen.

Dieses RPI-Problem wurde bei einem Sig-Cluster-Lifecyle-Meeting als "etwas, das nicht passieren sollte", "scheint fast wie eine Rennbedingung im Kubelet", "warum passiert es nur auf RPI und nicht auf anderen langsameren Geräten" qualifiziert.

Dies sind alles Gründe, um auch anderswo nach einem anderen Fehler zu suchen, aber keiner dieser Gründe ist _nicht_, initialDelaySeconds zu erhöhen. Gibt es tatsächlich einen Nachteil bei der Erhöhung von initialDelaySeconds?

Um es aus einer anderen Richtung zu betrachten: Wenn wir wissen, dass wir an anderer Stelle in Kubernetes ein Problem mit einer Problemumgehung haben, die in Kubeadm verwendet werden kann, ist es die Aufgabe von Kubeadm, die Reinheit in den Griff zu bekommen und ein bekanntermaßen fehlerhaftes Ergebnis zu erzielen? Dies scheint im Widerspruch zu dem Ziel zu stehen, ein Tool zu sein, das von den Mitarbeitern voraussichtlich tatsächlich für die Bereitstellung bereitgestellt wird. Bisher konnte ich kubeadm nicht in meinem Cluster verwenden, ohne es zu patchen, um die Zeitüberschreitung zu erhöhen (obwohl ich es vor über einem Jahr mit Patches gemeldet habe), was mich traurig macht.

(Entschuldigung, dass ich etwas von meiner Frustration über dieses Problem in meinen Ton geraten ließ)

wenn Sie eine Meinung zu 4 vs 5 Minuten haben

Seufzer. Ich habe versucht, für _no_ timeout in kubeadm einzutreten, aber ich habe noch keinen Weg gefunden, diesen Vorschlag überzeugend zu formulieren (siehe diesen und andere fehlgeschlagene Versuche in dieser Ausgabe zum Beispiel) :(

Dies sind alles Gründe, um auch anderswo nach einem anderen Fehler zu suchen, aber keiner dieser Gründe ist ein Grund, initialDelaySeconds nicht zu erhöhen. Gibt es tatsächlich einen Nachteil bei der Erhöhung von initialDelaySeconds?

Es ist eine kleine Änderung, aber es wurde vereinbart, diese Erhöhung nicht hinzuzufügen, da sie auch für Systeme gilt, die das Problem nicht ausüben.

Um es aus einer anderen Richtung zu betrachten: Wenn wir wissen, dass wir an anderer Stelle in Kubernetes ein Problem mit einer Problemumgehung haben, die in Kubeadm verwendet werden kann, ist es die Aufgabe von Kubeadm, die Reinheit in den Griff zu bekommen und ein bekanntermaßen fehlerhaftes Ergebnis zu erzielen? Dies scheint im Widerspruch zu dem Ziel zu stehen, ein Tool zu sein, das von den Mitarbeitern voraussichtlich tatsächlich für die Bereitstellung bereitgestellt wird.

Dem Endbenutzer gegenüberzutreten ist ein Ziel für kubeadm, das stimmt.
aber auch hier ist es nur ein bericht für rpis und der eigentliche fehler sollte zu sig-api-machine (api server) und sig-node (kubelet) eskaliert und möglicherweise außerhalb von kubeadm reproduziert werden.

Bisher konnte ich kubeadm nicht in meinem Cluster verwenden, ohne es zu patchen, um die Zeitüberschreitung zu erhöhen (obwohl ich es vor über einem Jahr mit Patches gemeldet habe), was mich traurig macht.

Sie müssen kubeadm nicht patchen, sondern können stattdessen Manifestdateien patchen.
kubeadm 1.13 führt die Init-Phasen zu Befehlen der obersten Ebene aus - z. B. kubeadm init phase [phase-name]
Phasen gibt es hauptsächlich, weil Benutzer eine benutzerdefinierte Steuerung der Erstellung des Steuerebenenknotens wünschen.

Wenn Sie kubeadm init --help ausführen, wird angezeigt, in welcher Reihenfolge die Phasen ausgeführt werden.

Damit Sie Ihren Befehl kubeadm init in die entsprechenden Phasen aufteilen können, verwenden Sie benutzerdefinierte Manifeste für die Komponenten der Steuerebene und überspringen die Phase control-plane . Es gibt jetzt auch --skip-phases .

Sie können das bereits in 1.11 und 1.12 tun, aber es ist weniger einfach.

weil es auch für Systeme gilt, die das Problem nicht ausüben.

Also ... was ist daran falsch? Wir beheben ständig Fehler, die nur auf einigen Systemen ausgelöst werden. Überall dort, wo wir Zeitüberschreitungen haben, müssen wir sie auf unser langsamstes System aller Zeiten abstimmen, nicht nur auf einen Teil unserer Umgebungen, oder?

Ein weiterer Aspekt ist, dass ich als Ops-Typ Angst vor Kaskadenfehlern in Überlastungssituationen habe, insbesondere mit dem Apiserver selbst. Afaics, das Livenessprobe-Timeout sollte immer nur ausgelöst werden, wenn die Dinge eindeutig gescheitert sind , nicht nur, wenn es von der Vorstellung von "normal" abweicht. Afaics wir sollten eine sehr entspannte Livenesssonde konfiguriert haben, selbst auf unserer schnellsten Hardware. Mein kleines RPI demonstriert diesen Überlastungsfehler nur einfacher - aber es gilt auch für größere Server unter größeren Überlastungs- / DoS-Szenarien. Es gibt keinen Vorteil, eine kleine initialDelaySeconds zu haben . Die Standard-Livenessprobe von kubeadm ist auf allen Plattformen unnötig aggressiv.

Es tut mir leid, dass ich immer wieder dieselben Punkte wiederhole, aber es gibt starke praktische und theoretische Gründe, initialDelaySeconds zu verlängern, und ich verstehe das gegnerische Argument, es klein zu halten, einfach nicht :(

Das Hinzufügen einer kubeadm-Konfigurationsoption hierfür ist derzeit unwahrscheinlich.

Ich versuche zu erklären, dass dies bereits mit 3 Befehlen in 1.13 möglich ist:

sudo kubeadm reset -f
sudo kubeadm init phase control-plane all --config=testkubeadm.yaml
sudo sed -i 's/initialDelaySeconds: 15/initialDelaySeconds: 20/g' /etc/kubernetes/manifests/kube-apiserver.yaml
sudo kubeadm init --skip-phases=control-plane --ignore-preflight-errors=all --config=testkubeadm.yaml

Ich möchte keine Option, ich versuche zu sagen, dass der aktuelle feste Wert (15) in einen anderen festen Wert geändert werden sollte (360 wurde oben vorgeschlagen).

.. Aber ich möchte das nicht weiter herausziehen. Es ist klar, dass die Entscheidung darin besteht, beim aktuellen Wert zu bleiben, also werde ich mich besiegt zurückziehen. Danke für Ihre Geduld :)

@ neolit123 Diese Kombination sieht großartig aus - viel einfacher als das, was ich dokumentiert hatte - ich muss warten, bis das Kontrollflugzeug eingestellt ist, und dann schnell in einem anderen Terminal laufen. https://github.com/alexellis/k8s-on-raspbian/blob/master/GUIDE.md

Ich werde die Anweisungen testen und versuchen, die Anleitung zu aktualisieren.

@ neolit123 das habe ich mit der obigen Konfiguration auf einem RPi3 B + bekommen

[certs] apiserver serving cert is signed for DNS names [rnode-1 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.0.110 192.168.0.26 192.168.0.26]
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0xaa7204]

goroutine 1 [running]:
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.validateKubeConfig(0xfa93f2, 0xf, 0xfb3d32, 0x17, 0x4032210, 0x68f, 0x7bc)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:236 +0x120
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.createKubeConfigFileIfNotExists(0xfa93f2, 0xf, 0xfb3d32, 0x17, 0x4032210, 0x0, 0xf7978)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:257 +0x90
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.createKubeConfigFiles(0xfa93f2, 0xf, 0x3ec65a0, 0x3f71c60, 0x1, 0x1, 0x0, 0x0)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:120 +0xf4
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.CreateKubeConfigFile(0xfb3d32, 0x17, 0xfa93f2, 0xf, 0x3ec65a0, 0x1f7a701, 0xb9772c)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:93 +0xe8
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases.runKubeConfigFile.func1(0xf66a80, 0x4208280, 0x0, 0x0)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/kubeconfig.go:155 +0x168
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).Run.func1(0x3cc2d80, 0x0, 0x0)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:235 +0x160
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).visitAll(0x3ec9270, 0x3f71d68, 0x4208280, 0x0)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:416 +0x5c
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).Run(0x3ec9270, 0x24, 0x416bdb4)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:208 +0xc8
k8s.io/kubernetes/cmd/kubeadm/app/cmd.NewCmdInit.func1(0x3e97b80, 0x3e900e0, 0x0, 0x3)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/init.go:141 +0xfc
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).execute(0x3e97b80, 0x3e3ff80, 0x3, 0x4, 0x3e97b80, 0x3e3ff80)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:760 +0x20c
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0x3e96140, 0x3e97b80, 0x3e96780, 0x3d82100)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:846 +0x210
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).Execute(0x3e96140, 0x3c8c0c8, 0x116d958)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:794 +0x1c
k8s.io/kubernetes/cmd/kubeadm/app.Run(0x3c9c030, 0x0)
    /workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/kubeadm.go:48 +0x1b0
main.main()
    _output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/kubeadm.go:29 +0x20
kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.1", GitCommit:"eec55b9ba98609a46fee712359c7b5b365bdd920", GitTreeState:"clean", BuildDate:"2018-12-13T10:36:44Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"linux/arm"}

In kubeadm-config.yaml - 192.168.0.26 ist eine LB, die auf 192.168.0.110 zeigt

apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: stable
apiServer:
  certSANs:
  - "192.168.0.26"
controlPlaneEndpoint: "192.168.0.26:6443"

Ich bekomme das gleiche auch ohne die externe config / lb IP.

Alex

Ich habe Leute für eine Weile dazu gedrängt, Kubeadm zu verwenden, sogar Schulen, die es auf ihren Pi-Clustern ausführen wollen. Ich verstehe zwar, dass ich die Codebasis nicht komplizieren möchte, aber ich denke, es ist wahrscheinlich eine gute Sache für Ihre Benutzerbasis, die Ausführung auf diesen kleinen Geräten zu unterstützen. Es ermöglicht jungen Leuten, die Kubernetes-Reifen auf billige Hardware zu treten, die es sonst möglicherweise nicht gibt. Die obige Problemumgehung ist zwar gültig, für diesen Anwendungsfall jedoch viel schwieriger.

Was ist mit einem Kompromiss? Anstatt es konfigurierbar zu machen, fügen Sie eine einfache Heuristik hinzu, die besagt, wenn nicht x86_64, das Standardzeitlimit höher einstellen?

[kubeconfig] Schreiben der kubeconfig-Datei "admin.conf"
[kubeconfig] Schreiben der kubeconfig-Datei "kubelet.conf"
Panik: Laufzeitfehler: Ungültige Speicheradresse oder Nullzeiger-Dereferenzierung
[Signal SIGSEGV: Segmentierungsverletzungscode = 0x1 addr = 0x8 pc = 0xaa7204]

Seltsamerweise ist admin.conf maschinengeneriert und sollte einen gültigen Config -Typ enthalten, wobei ein current-context -Feld auf einen Kontext verweist.

Die Panik kommt von dieser Linie:
https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go#L236

Ich sehe genau den gleichen Fehler wie: point_up: oben mit folgendem:

modify_kube_apiserver_config(){
  sed -i 's/failureThreshold: [0-9]/failureThreshold: 15/g' /etc/kubernetes/manifests/kube-apiserver.yaml && \
  sed -i 's/timeoutSeconds: [0-9][0-9]/timeoutSeconds: 20/g' /etc/kubernetes/manifests/kube-apiserver.yaml && \
  sed -i 's/initialDelaySeconds: [0-9][0-9]/initialDelaySeconds: 120/g' /etc/kubernetes/manifests/kube-apiserver.yaml
}
kubeadm init phase control-plane all --config=$${KUBEADM_CONFIG_FILE} && \
modify_kube_apiserver_config && \
kubeadm init \
--skip-phases=control-plane \
--ignore-preflight-errors=all \
--config=$${KUBEADM_CONFIG_FILE} \
--v 4

Das folgende Skript löst das Problem für mich mit den kubeadm-Versionen 1.12, 1.13 ( meistens ).

modify_kube_apiserver_config(){
  while [[ ! -e /etc/kubernetes/manifests/kube-apiserver.yaml ]]; do
    sleep 0.5s;
  done && \
  sed -i 's/failureThreshold: [0-9]/failureThreshold: 18/g' /etc/kubernetes/manifests/kube-apiserver.yaml && \
  sed -i 's/timeoutSeconds: [0-9][0-9]/timeoutSeconds: 20/g' /etc/kubernetes/manifests/kube-apiserver.yaml && \
  sed -i 's/initialDelaySeconds: [0-9][0-9]/initialDelaySeconds: 240/g' /etc/kubernetes/manifests/kube-apiserver.yaml
}

# ref https://github.com/kubernetes/kubeadm/issues/413 (initialDelaySeconds is too eager)
if [[ ${var.arch} == "arm" ]]; then modify_kube_apiserver_config & fi

kubeadm init \
  --config=$${KUBEADM_CONFIG_FILE} \
  --v ${var.kubeadm_verbosity}

Ich war in der gleichen Situation und bekam den gleichen Fehler mit dem von @ neolit123 vorgeschlagenen
Ich konnte das Skript von @stephenmoloney nicht Skripten vertraut, wahrscheinlich meine Schuld.

Also habe ich das Skript auf Python portiert (das standardmäßig auf Raspbian installiert ist, sodass keine zusätzlichen Abhängigkeiten erforderlich sind), falls jemand interessiert ist:

import os
import time
import threading

filepath = '/etc/kubernetes/manifests/kube-apiserver.yaml'

def replace_defaults():
    print('Thread start looking for the file')
    while not os.path.isfile(filepath):
        time.sleep(1) #wait one second
    print('\033[94m -----------> FILE FOUND: replacing defaults \033[0m')
    os.system("""sed -i 's/failureThreshold: [0-9]/failureThreshold: 18/g' /etc/kubernetes/manifests/kube-apiserver.yaml""")
    os.system("""sed -i 's/timeoutSeconds: [0-9][0-9]/timeoutSeconds: 20/g' /etc/kubernetes/manifests/kube-apiserver.yaml""")
    os.system("""sed -i 's/initialDelaySeconds: [0-9][0-9]/initialDelaySeconds: 240/g' /etc/kubernetes/manifests/kube-apiserver.yaml""")

t = threading.Thread(target=replace_defaults)
t.start()
os.system("kubeadm init")

Um es auszuführen: sudo python however_you_name_the_file.py
Vielen Dank, dass Sie mich auf die Lösung @stephenmoloney und @ neolit123 hingewiesen haben !

Hallo! Dieses Problem war sehr hilfreich

Ich habe einen ausgefallenen Weg gefunden, dies mit kustomize zu beheben

mkdir /tmp/kustom

cat > /tmp/kustom/kustomization.yaml <<EOF
patchesJson6902:
- target:
    version: v1
    kind: Pod
    name: kube-apiserver
    namespace: kube-system
  path: patch.yaml
EOF

cat > /tmp/kustom/patch.yaml <<EOF
- op: replace
  path: /spec/containers/0/livenessProbe/initialDelaySeconds
  value: 30
- op: replace
  path: /spec/containers/0/livenessProbe/timeoutSeconds
  value: 30
EOF

sudo kubeadm init --config config.yaml -k /tmp/kustom
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen