Kubectl-Debug-Plugin zum Debuggen in Kubernetes-Pods



Ende letzten Jahres hat Reddit ein Plugin für kubectl eingeführt, das beim Debuggen in den Pods des Kubernetes-Clusters hilft - kubectl-debug . Diese Idee erschien unseren Ingenieuren sofort interessant und nützlich, daher haben wir uns entschlossen, ihre Implementierung zu prüfen und freuen uns, unsere Ergebnisse mit den Lesern der Habra zu teilen.

Warum ist das überhaupt notwendig?


Im Moment gibt es ernsthafte Unannehmlichkeiten beim Debuggen von etwas im Rahmen von Pods. Das Hauptziel beim Zusammenstellen des Containerbildes besteht darin , es zu minimieren , d.h. Machen Sie es so klein wie möglich und enthalten Sie so wenig "Überschuss" wie möglich. Wenn es jedoch um Probleme beim Betrieb der endgültigen Software in Containern oder beim Debuggen der Kommunikation mit anderen Diensten im Cluster / außerhalb geht ... spielt Minimalismus eine Rolle für uns - schließlich gibt es in Containern nichts für den tatsächlichen Prozess des Auffindens von Problemen. Dienstprogramme wie netstat / ip / ping / curl / wget usw. sind in der Regel nicht verfügbar.

Und oft endet alles damit, dass der Ingenieur die erforderliche Software direkt im laufenden Container bereitstellt, um das Problem zu "sehen" und zu sehen. In solchen Fällen schien das Kubectl-Debug-Plugin ein sehr nützliches Werkzeug zu sein - weil es vor dringenden Schmerzen schützt.

Mit seiner Hilfe können Sie mit einem Befehl einen Container mit allen notwendigen Tools an Bord im Rahmen eines Problem- Pods starten und alle Prozesse „von außen“ im Inneren untersuchen. Wenn Sie jetzt schon einmal auf die Fehlerbehebung bei Kubernetes gestoßen sind, klingt das attraktiv, nicht wahr?

Was ist das für ein Plugin?


Im Allgemeinen sieht die Architektur dieser Lösung aus wie eine Reihe von Plugins für kubectl und einen Agenten , der den DaemonSet-Controller verwendet. Das Plugin kubectl debug … Befehle, die mit dem kubectl debug … und interagiert mit Agenten auf den Clusterknoten. Der Agent wird wiederum im Host-Netzwerk ausgeführt, und der Host docker.sock wird im Agenten-Pod bereitgestellt, um vollen Zugriff auf die Container auf diesem Server zu erhalten.

Wenn Sie also anfordern, einen Debug-Container im angegebenen Pod zu starten:
Es gibt einen Prozess zum Identifizieren des hostIP , und eine Anforderung wird an den Agenten gesendet (der an einem geeigneten Host arbeitet), um einen Debug-Container in den Namespaces zu starten, die dem Ziel-Pod entsprechen.

Eine detailliertere Ansicht dieser Schritte finden Sie in der Projektdokumentation .

Was ist für die Arbeit erforderlich?


Der Autor von kubectl-debug behauptet, mit den Versionen des Kubernetes- Clients / Clusters 1.12.0+ kompatibel zu sein. Ich hatte jedoch K8s 1.10.8 zur Hand, auf dem alles ohne sichtbare Probleme funktionierte ... mit einem einzigen Hinweis: Damit das kubectl debug Team funktioniert In dieser Form ist die Kubectl- Version genau 1.12+ . Ansonsten sind alle Befehle ähnlich, werden aber nur über kubectl-debug … aufgerufen kubectl-debug …

Wenn Sie die in README beschriebene DaemonSet-Vorlage starten README sollten Sie den Makel README den Sie auf den Knoten verwenden, nicht vergessen: Ohne die entsprechenden Toleranzen werden sich die Pods des Agenten dort nicht niederlassen und daher können Sie die auf solchen Knoten lebenden Pods nicht verwenden kann sich mit einem Debugger verbinden.

Die Hilfe des Debuggers ist sehr umfassend und scheint alle aktuellen Möglichkeiten zum Starten / Konfigurieren des Plugins zu beschreiben. Im Allgemeinen kann das Dienstprogramm eine große Anzahl von Anweisungen ausführen: Sie können Zertifikate anhängen, den kubectl-Kontext angeben, eine separate kubectl-Konfiguration oder die Adresse des Cluster-API-Servers angeben und vieles mehr.

Arbeiten Sie mit einem Debugger


Die Installation bis zu dem Moment, in dem „alles funktioniert“, ist auf zwei Stufen reduziert:

  1. kubectl apply -f agent_daemonset.yml ;
  2. Installieren Sie das Plugin direkt selbst - im Allgemeinen ist alles wie hier beschrieben.

Wie benutzt man es? Angenommen, wir haben das folgende Problem: Die Metriken eines der Dienste im Cluster werden nicht erfasst - und wir möchten überprüfen, ob zwischen Prometheus und dem Zieldienst Netzwerkprobleme bestehen. Wie Sie vielleicht erraten haben, fehlen dem Prometheus-Bild die erforderlichen Werkzeuge.

Versuchen wir, mit Prometheus eine Verbindung zum Container herzustellen (wenn sich mehrere Pods im Pod befinden, müssen Sie angeben, zu welchem ​​Container eine Verbindung hergestellt werden soll, andernfalls wählt der Debugger standardmäßig den ersten aus):

 kubectl-debug --namespace kube-prometheus prometheus-main-0 Defaulting container name to prometheus. pulling image nicolaka/netshoot:latest... latest: Pulling from nicolaka/netshoot 4fe2ade4980c: Already exists ad6ddc9cd13b: Pull complete cc720038bf2b: Pull complete ff17a2bb9965: Pull complete 6fe9f5dade08: Pull complete d11fc7653a2e: Pull complete 4bd8b4917a85: Pull complete 2bd767dcee18: Pull complete Digest: sha256:897c19b0b79192ee5de9d7fb40d186aae3c42b6e284e71b93d0b8f1c472c54d3 Status: Downloaded newer image for nicolaka/netshoot:latest starting debug container... container created, open tty... [1] → root @ / 

Zuvor haben wir festgestellt, dass der problematische Dienst unter der Adresse 10.244.1.214 ausgeführt wird und auf Port 8080 überwacht wird. Natürlich können wir auch die Verfügbarkeit von den Hosts überprüfen. Für einen zuverlässigen Debugging-Prozess müssen diese Vorgänge jedoch unter identischen (oder möglichst engen) Bedingungen reproduziert werden. Daher ist die Überprüfung von einem Pod / Container mit Prometheus die beste Option. Beginnen wir mit einem einfachen:

  [1] → ping 10.244.1.214 PING 10.244.1.214 (10.244.1.214) 56(84) bytes of data. 64 bytes from 10.244.1.214: icmp_seq=1 ttl=64 time=0.056 ms 64 bytes from 10.244.1.214: icmp_seq=2 ttl=64 time=0.061 ms 64 bytes from 10.244.1.214: icmp_seq=3 ttl=64 time=0.047 ms 64 bytes from 10.244.1.214: icmp_seq=4 ttl=64 time=0.049 ms ^C --- 10.244.1.214 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 61ms rtt min/avg/max/mdev = 0.047/0.053/0.061/0.007 ms 

Alles ist gut. Vielleicht ist der Port nicht verfügbar?

  [1] → curl -I 10.244.1.214:8080 HTTP/1.1 200 OK Date: Sat, 12 Jan 2019 14:01:29 GMT Content-Length: 143 Content-Type: text/html; charset=utf-8 

Und es gibt kein Problem. Dann prüfen wir, ob die eigentliche Kommunikation zwischen Prometheus und dem Endpunkt mit Metriken stattfindet:

  [2] → tcpdump host 10.244.1.214 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 14:04:19.234101 IP prometheus-main-0.prometheus-operated.kube-prometheus.svc.cluster.local.36278 > 10.244.1.214.8080: Flags [P.], seq 4181259750:4181259995, ack 2078193552, win 1444, options [nop,nop,TS val 3350532304 ecr 1334757657], length 245: HTTP: GET /metrics HTTP/1.1 14:04:19.234158 IP 10.244.1.214.8080 > prometheus-main-0.prometheus-operated.kube-prometheus.svc.cluster.local.36278: Flags [.], ack 245, win 1452, options [nop,nop,TS val 1334787600 ecr 3350532304], length 0 14:04:19.290904 IP 10.244.1.214.8080 > prometheus-main-0.prometheus-operated.kube-prometheus.svc.cluster.local.36278: Flags [P.], seq 1:636, ack 245, win 1452, options [nop,nop,TS val 1334787657 ecr 3350532304], length 635: HTTP: HTTP/1.1 200 OK 14:04:19.290923 IP prometheus-main-0.prometheus-operated.kube-prometheus.svc.cluster.local.36278 > 10.244.1.214.8080: Flags [.], ack 636, win 1444, options [nop,nop,TS val 3350532361 ecr 1334787657], length 0 ^C 4 packets captured 4 packets received by filter 0 packets dropped by kernel 

Anfragen für Antworten kommen. Basierend auf den Ergebnissen dieser Operationen können wir den Schluss ziehen, dass es auf der Ebene der Netzwerkinteraktion keine Probleme gibt, was bedeutet (höchstwahrscheinlich), dass Sie von der angewandten Seite aus schauen müssen. Wir verbinden uns mit dem Exporter mit dem Container (natürlich auch mit dem fraglichen Debugger, da Exporteure immer extrem minimalistische Bilder haben) und ... wir sind überrascht, dass es ein Problem bei der Konfiguration des Dienstes gibt - zum Beispiel haben wir vergessen, den Exporteur an den richtigen weiterzuleiten Zielanwendungsadresse Der Fall ist gelöst!

Natürlich sind in der hier beschriebenen Situation andere Möglichkeiten zum Debuggen möglich, aber wir werden sie außerhalb des Geltungsbereichs des Artikels belassen. Das Ergebnis ist, dass kubectl-debug viele Verwendungsmöglichkeiten bietet: Sie können jedes Bild in die Arbeit einfügen und auf Wunsch sogar ein bestimmtes zusammenstellen (mit den erforderlichen Tools).

Welche anderen Anwendungen fallen Ihnen sofort ein?

  • Eine "stille" Anwendung, für die schädliche Entwickler keine normale Protokollierung implementiert haben. Er hat jedoch die Möglichkeit, eine Verbindung zum Service-Port herzustellen und mit einem bestimmten Tool zu debuggen, das natürlich nicht in das endgültige Image aufgenommen werden sollte.
  • Starten Sie neben der Kampfanwendung, die im manuellen Modus identisch ist, jedoch das Debug aktiviert ist, um die Interaktion mit benachbarten Diensten zu überprüfen.

Im Allgemeinen ist es offensichtlich, dass es viel mehr Situationen gibt, in denen ein solches Werkzeug nützlich sein kann. Ingenieure, die ihnen jeden Tag bei der Arbeit begegnen, können das Potenzial des Versorgungsunternehmens im Hinblick auf das Live-Debugging bewerten.

Schlussfolgerungen


Kubectl-Debug ist ein nützliches und vielversprechendes Tool. Natürlich gibt es Kubernetes-Cluster und -Anwendungen, für die es nicht viel Sinn macht, aber es gibt immer noch Fälle, in denen es eine unschätzbare Hilfe beim Debuggen bietet - insbesondere, wenn es um die Kampfumgebung geht und die Notwendigkeit besteht, hier und jetzt schnell die Gründe zu finden das Problem, auf das Sie gestoßen sind.

Die erste Erfahrung mit der Verwendung ergab, dass dringend eine Verbindung zu einem Pod / Container hergestellt werden muss, der nicht bis zum Ende startet (z. B. hängt er in CrashLoopbackOff ), um CrashLoopbackOff zu überprüfen, warum die Anwendung nicht CrashLoopbackOff . Bei dieser Gelegenheit habe ich ein entsprechendes Problem im Projekt-Repository erstellt, auf das der Entwickler positiv reagiert und die Implementierung in naher Zukunft versprochen hat. Sehr zufrieden mit dem schnellen und angemessenen Feedback. Wir freuen uns also auf neue Funktionen des Dienstprogramms und dessen Weiterentwicklung!

PS


Lesen Sie auch in unserem Blog:

Source: https://habr.com/ru/post/de436112/


All Articles