Einführung | Kürzlich habe ich mehrere Verbesserungen an lxc exec vorgenommen. Wenn Sie es nicht wissen, möchte ich es Ihnen vorstellen: lxc exec ist das Client-Tool von LXD. Es verwendet die LXD-Client-API, um mit dem LXD-Daemon zu kommunizieren und verschiedene Programme auszuführen, die der Benutzer ausführen möchte von dem, was Sie verwenden können: |
Eines unserer Hauptziele ist es, lxc exec ssh ähnlich zu machen, da es der Standard für die Remote-Ausführung von Befehlen, interaktiv oder nicht interaktiv, ist. Das macht es etwas schwierig, lxc exec gut zu machen.
1. Hintergrundaufgaben verarbeitenEin seit langem bestehendes Problem ist natürlich, wie man Hintergrundaufgaben richtig erledigt. Hier ist ein Beispiel für ein Problem mit einer LXD 2.7-Instanz:
Sie können sehen, dass die Ausführung von Aufgaben im Hintergrund dazu führt, dass lxc exec nicht beendet werden kann. Viele Befehle können dieses Problem auslösen:
chb@conventiont|~ > lxc exec zest1 bash root@zest1:~# yes & y y y . . .
Nichts kann dich jetzt retten. Ja, es wird immer direkt nach stdout geschrieben.
Die Ursache des Problems liegt darin, dass stdout immer geöffnet ist. Dies ist jedoch notwendig, da es verwendet wird, um sicherzustellen, dass alle vom vom Benutzer gestarteten Prozess geschriebenen Daten tatsächlich gelesen und über die von uns hergestellte Websocket-Verbindung zurückgesendet werden.
Wenn Sie dies tun möchten, führen Sie eine Shell-Sitzung aus, führen Sie dann einen Prozess im Hintergrund aus und verlassen Sie die Shell sofort. Leider funktioniert es nicht wie erwartet.
Der erste und primitive Ansatz besteht darin, stdout einfach zu schließen, sobald Sie feststellen, dass das Vordergrundprogramm (z. B. Shell) beendet wurde. Aber das ist nicht so gut, wie es scheint. Dieses Problem wird offensichtlich, wenn Sie Programme mit schneller Ausführung ausführen, wie zum Beispiel:
lxc exec -- ls -al /usr/lib
Hier wird der lxc-exec-Prozess (und der zugehörige forkexec-Prozess. Aber denken Sie jetzt nicht darüber nach, sondern denken Sie daran, dass Go + setns() nicht interagieren...) beendet wird, bevor alle gepufferten Daten in stdout gelesen wurden . Diese Situation führt zu einer verkürzten Ausgabe, die niemand möchte. Nachdem ich mehrere Methoden ausprobiert hatte, um das Problem zu lösen, darunter das Deaktivieren der PTY-Pufferung (ich sage Ihnen, das ist nicht schön und funktioniert nicht wie erwartet.) und andere seltsame Ideen, gelang es mir, ein paar poll()-„Tricks“ durchzustehen ( In gewisser Weise löst ein „Trick“) dieses Problem. Jetzt können Sie endlich Hintergrundaufgaben ausführen und den Vorgang vollständig beenden. Wie im Bild gezeigt:
2. Durch Signale verursachte Exit-Codes meldenssh ist ein tolles Tool. Was mir jedoch immer nicht gefallen hat, ist, dass ssh immer -1, also den Exit-Code 255, meldet, wenn ein von ssh ausgeführter Befehl ein Signal empfängt. Dies ist ärgerlich, wenn Sie das Signal verstehen möchten, das zum Beenden des Programms geführt hat. Aus diesem Grund habe ich kürzlich die Konvention implementiert, die von Standard-Shells verwendet wird, um jeden Exit zu melden, der durch ein Signal verursacht wird, 128 + n, wobei n als das Semaphor definiert ist, das den Executor zum Exit gebracht hat. Beim SIGKILL-Signal würden Sie beispielsweise 128 + SIGKILL = 137 sehen (berechnet die Exit-Codes für andere schwerwiegende Signale als Übung für den Leser). So können Sie Folgendes tun:
chb@conventiont|~ > lxc exec zest1 sleep 100
Senden Sie nun SIGKILL an den Executor (nicht an lxc exec selbst, da SIGKILL nicht weiterleitbar ist).
kill -KILL $(pidof sleep 100)
Überprüfen Sie abschließend den Exit-Code Ihres Programms:
chb@conventiont|~ > echo $? 137
Schau. Dies funktioniert offenbar nur, wenn a) der Exit-Code die 8-Bit-Rechenbarriere nicht überschreitet und b) wenn der Ausführende nicht 137 verwendet, um den Erfolg anzuzeigen (wie...interessant?!). Keines der Argumente erscheint mir sehr überzeugend. Ersteres liegt daran, dass fatale Semaphore diesen Bereich nicht überschreiten sollten. Letzteres, weil (i) es sich um ein Benutzerproblem handelt, (ii) diese Exit-Codes tatsächlich beibehalten werden (glaube ich schon) und (iii) Sie das gleiche Problem haben werden, wenn Sie das Programm lokal oder anderswo ausführen.
Der Hauptvorteil, den ich sehe, ist die Möglichkeit, dem Testamentsvollstrecker einen detaillierten Exit-Status zu melden. Beachten Sie, dass wir nicht alle durch Signale getöteten Programminstanzen melden. Wenn Ihr Programm beispielsweise SIGTERM verarbeiten und sauber beenden kann, hat LXD keine einfache Möglichkeit, dies zu erkennen und zu melden, dass das Programm durch das Signal beendet wurde. Sie erhalten einfach den Exit-Code 0.
3. VorwärtssignalDas macht vielleicht keinen großen Spaß (oder vielleicht auch nicht, wer weiß), aber ich finde es sehr nützlich. Wie Sie im SIGKILL-Fall sehen können, habe ich ausdrücklich angegeben, dass SIGKILL an den Executor gesendet werden muss, nicht an den Befehl lxc exec selbst. Dies liegt daran, dass SIGKILL im Programm nicht verarbeitet werden kann. Das Einzige, was ein Programm tun kann, ist, wie jetzt ... wie in diesem Beispiel ... sofort zu sterben (Sie verstehen, was ich meine ...). Aber das Programm kann viele andere Signale verarbeiten, SIGTERM, SIGHUP' und natürlich SIGUSR1 und SIGUSR2. Wenn Sie also ein Signal senden, das von „lxc exec“, aber nicht vom Executor verarbeitet werden kann, leiten neuere Versionen von LXD das Signal an den Executor weiter. Dies ist in Skripten sehr praktisch.
Wie auch immer, ich hoffe, dass Sie diesen kleinen Artikel/Kauderwelsch über lxc exec nützlich fanden. Viel Spaß mit LXD, es spielt mit einem verrückten, wunderschönen Biest. Bitte probieren Sie das Online-Experiment aus: https://linuxcontainers.org/lxd/try-it/, und für Entwickler schauen Sie hier: https://github.com/lxc/lxd und senden Sie uns Patches.
Wir verlangen keine Signatur einer CLA, wir folgen dem Kernel-Stil, solange darin eine „Signed-off-by“-Zeile enthalten ist.
Das obige ist der detaillierte Inhalt vonlxc exec: Entdecken Sie seinen einzigartigen Charme. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!