Wie kann ich einen Container auf Kubernetes laufen lassen?


124

Ich versuche jetzt, einen einfachen Container mit Shell (/ bin / bash) auf einem Kubernetes-Cluster auszuführen.

Ich dachte, dass es eine Möglichkeit gibt, einen Container auf einem Docker-Container laufen zu lassen, indem ich die pseudo-ttyOption ( -tdOption auf docker runBefehl) verwende und entferne .

Beispielsweise,

$ sudo docker run -td ubuntu:latest

Gibt es eine solche Option in Kubernetes?

Ich habe versucht, einen Container mit einem kubectl run-containerBefehl wie dem folgenden auszuführen:

kubectl run-container test_container ubuntu:latest --replicas=1

Der Container wird jedoch für einige Sekunden beendet (genau wie beim Starten mit dem docker runBefehl ohne die oben genannten Optionen). Und ReplicationController startet es wiederholt.

Gibt es eine Möglichkeit, einen Container auf Kubernetes wie die -tdOptionen im docker runBefehl laufen zu lassen ?


Die Verwendung dieses Bildes (wie Kubernetes docs vorschlägt) ist sehr praktisch:kubectl run curl --image=radial/busyboxplus:curl -i --tty
Matheus Santana

Diese Frage wurde in diesem Video erwähnt: Kubernetes der sehr harte Weg bei Datadog mit dem Dia-Titel "Cargo Culting" . Aus Wikipedia: Der Begriff " Cargo Cult Programmer" kann verwendet werden, wenn ein ungelernter oder unerfahrener Computerprogrammierer (oder ein mit dem Problem unerfahrener) zur Hand) kopiert einen Programmcode von einem Ort zum anderen, ohne zu verstehen, wie er funktioniert oder ob er an seiner neuen Position benötigt wird.
tgogos

Antworten:


49

Ein Container wird beendet, wenn sein Hauptprozess beendet wird. So etwas tun wie:

docker run -itd debian

Den Container offen zu halten ist offen gesagt ein Hack, der nur für schnelle Tests und Beispiele verwendet werden sollte. Wenn Sie nur einen Container zum Testen für ein paar Minuten benötigen, würde ich Folgendes tun:

docker run -d debian sleep 300

Dies hat den Vorteil, dass der Container automatisch verlassen wird, wenn Sie ihn vergessen. Alternativ können Sie so etwas in eine whileSchleife einfügen, damit es für immer läuft, oder einfach eine Anwendung wie z top. All dies sollte in Kubernetes einfach zu tun sein.

Die eigentliche Frage ist, warum Sie dies tun möchten. Ihr Container sollte einen Dienst bereitstellen, dessen Prozess den Container im Hintergrund laufen lässt.


Vielen Dank für Ihre Antwort. Ich versuche jetzt, das Verhalten von Containern zu verstehen, wobei Dutzende von Containern gleichzeitig ausgeführt werden. Eine endlose Schleife und die Verwendung anderer schwerer Befehle verhindern, dass ich weiß, wie sich Container verhalten. Das ist der Grund, warum ich einen einfachen Container brauche, wie nur / bin / bash.
Spring

Im Moment werde ich versuchen, catohne Argumente topund sleepmit Argumenten von großer Anzahl zu laufen .
Spring

30
sleep infinityfunktioniert in vielen Fällen (nicht Busybox)
rwilson04

1
Dafür gibt es viele Gründe. Beispielsweise können Sie Ihre Pods mit Steuerfreigaben und injizierter Konfiguration bereitstellen, wodurch die Wiederherstellung ähnlicher Umgebungen ärgerlich und umständlich wird. Ein Container mit dieser Konfiguration in Fällen, in denen die anderen Pods abstürzen / gelöscht werden, kann jedoch unendlich nützlich sein.
Richard Løvehjerte

Weil mein Service aus mehreren Prozessen besteht.
5онстантин Ван

133

Container sollen vollständig ausgeführt werden. Sie müssen Ihrem Container eine Aufgabe zur Verfügung stellen, die niemals abgeschlossen wird. So etwas sollte funktionieren:

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu
spec:
  containers:
  - name: ubuntu
    image: ubuntu:latest
    # Just spin & wait forever
    command: [ "/bin/bash", "-c", "--" ]
    args: [ "while true; do sleep 30; done;" ]

Aber ist das eine bewährte Methode?
Aneesh Joshi

3
@aneeshjoshi Ich würde nicht sagen, dass dies die beste Vorgehensweise ist . Dies ist nur ein Beispiel für einen Pod, der ausgeführt wird, ohne sofort beendet zu werden. Es wird empfohlen, Ihre Container so zu erstellen, dass sie den Job ausführen, für den sie entwickelt wurden (ein Job, der vollständig ausgeführt wird, ein Webserver, der ständig ausgeführt wird usw.). Ich habe dies als Beispiel gepostet, da Kubernetes anfänglich frustrierend sein kann, wenn Sie weiterhin Pods erstellen, um diese verschwinden zu lassen, da der Standardbefehl sofort beendet wird.
Joel B

@ JoelB Danke. Ich habe mich gefragt, was der "richtige" Weg ist, es zu tun.
Aneesh Joshi

1
Vielen Dank dafür, da ich einen Container brauche, der eine Weile leben kann und den ich betreten kann. Ich habe versucht , das gleiche mit einem helleren Bild zu tun , als ubuntuund versuchte bashBild kann aber nicht an der Arbeit. Irgendeine Idee, wie man dasselbe mit dem bashBild macht?
Cryanbhu

Ich weiß, dass dies ein altes Problem ist. Kubernetes wird jedoch gestartet, um kurzlebige Container zu unterstützen. Link: kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers . Diese Container weisen einige Einschränkungen auf, z. B. Ressourcenbeschränkungen. Sie wurden jedoch für Debugging-Zwecke entwickelt.
Shubham Singh

111

Sie können dieses CMD verwenden in Dockerfile:

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

Dadurch bleibt Ihr Container am Leben, bis er zum Anhalten aufgefordert wird. Wenn Sie Trap und Wait verwenden, reagiert Ihr Container sofort auf eine Stoppanforderung . Ohne Trap / Wait dauert das Anhalten einige Sekunden.

Bei Busybox-basierten Bildern (die in alpinen Bildern verwendet werden) kennt der Schlaf das Unendlichkeitsargument nicht. Mit dieser Problemumgehung erhalten Sie die gleiche sofortige Antwort auf ein Problem docker stopwie im obigen Beispiel:

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

Ich verwende das gleiche auf Kubernetes Deployment Yaml für Debugging-Zwecke
SDKKS

das gibt mir "Schlaf: ungültige Nummer 'unendlich'"
arunkjn

@arunkjn Danke dafür. Sie stecken wahrscheinlich mit einem Bild fest, das Busybox verwendet (wie alpine Bilder). Siehe die aktualisierte Antwort.
Feuer

24
  1. Verwenden Sie in Ihrer Docker-Datei diesen Befehl:

    CMD ["sh", "-c", "tail -f /dev/null"]
    
  2. Erstellen Sie Ihr Docker-Image.

  3. Schieben Sie es in Ihren Cluster oder ähnliches, um sicherzustellen, dass das Image verfügbar ist.
  4. kubectl run debug-container -it --image=<your-image>
    

Tolle Tipps zum Debuggen des Containers.
kta

15

Um einen POD am Laufen zu halten, sollte der POD eine bestimmte Aufgabe ausführen, andernfalls wird er von Kubernetes als unnötig angesehen und daher beendet. Es gibt viele Möglichkeiten, einen POD am Laufen zu halten.

Ich hatte ähnliche Probleme, als ich einen POD brauchte, um ununterbrochen zu laufen, ohne etwas zu tun. Die folgenden zwei Methoden haben für mich funktioniert:

  1. Starten eines Schlafbefehls beim Ausführen des Containers.
  2. Ausführen einer Endlosschleife im Container.

Obwohl die erste Option einfacher als die zweite ist und möglicherweise die Anforderung erfüllt, ist sie nicht die beste Option. Es gibt eine Begrenzung für die Anzahl der Sekunden, die Sie im Schlafbefehl zuweisen möchten. Ein Container mit einer darin laufenden Endlosschleife wird jedoch nie verlassen.

Ich werde jedoch beide Möglichkeiten beschreiben (wenn Sie den Busybox-Container ausführen):

1. Schlafbefehl

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  containers:
  - name: busybox
    image: busybox
    ports:
    - containerPort: 80
    command: ["/bin/sh", "-ec", "sleep 1000"]
  nodeSelector:
    beta.kubernetes.io/os: linux

2. Endlosschleife

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  containers:
  - name: busybox
    image: busybox
    ports:
    - containerPort: 80
    command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"]
  nodeSelector:
    beta.kubernetes.io/os: linux

Führen Sie den folgenden Befehl aus, um den Pod auszuführen:

kubectl apply -f <pod-yaml-file-name>.yaml

Ich hoffe es hilft!


Darf ich fragen, was ist Schlaf? Ist es ein Befehl innerhalb von Ubuntu? Oder Docker-Befehl?
Faraz

@Faraz Es ist ein Linux-Shell-Befehl, der nicht spezifisch für Docker ist.
Arbaaz

11

Ich konnte dies mit dem Befehl sleep infinityin Kubernetes zum Laufen bringen, der den Container offen hält. In dieser Antwort finden Sie Alternativen, wenn dies nicht funktioniert.


Dies gibt keine Antwort auf die Frage. Um einen Autor zu kritisieren oder um Klärung zu bitten, hinterlassen Sie einen Kommentar unter seinem Beitrag. - Von der Überprüfung
Will

1
@ Will sicher, dass es tut. sleep infinityHält den Container offen und bietet die gleiche Art von Funktionalität, nach der die Frage fragt (für die meisten Containertypen). Es bietet auch einen Link zu Alternativen für Fälle, in denen dieser bestimmte Befehl nicht funktioniert
rwilson04

Dies war aus der Überprüfung. Wenn Sie den Kommentartext dort zur Antwort hinzufügen, ist dies eine qualitativ hochwertige Antwort :) Meine anfängliche Markierung / Empfehlung basierte darauf, dass Ihr Kommentar nicht erfolgreich war, was mich glauben ließ, dass dies ein Kommentar sein sollte. Eine schnelle Bearbeitung hinzugefügt und positiv bewertet.
Will

"... Schlaf unendlich in Kubernetes" ist eine nicht informierte Aussage. Dies bedeutet, dass das Bild kein Unix und keinen Docker enthält.
mmla

10

Der einfachste Befehl für k8s pod manifest, Container für immer auszuführen:

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu
spec:
  containers:
  - name: ubuntu
    image: ubuntu:latest
    # Just sleep forever
    command: [ "sleep" ]
    args: [ "infinity" ]

5

Verwenden Sie diesen Befehl in Ihrer Docker-Datei, um den Container in Ihrem K8s-Cluster am Laufen zu halten:

  • CMD-Schwanz -f / dev / null

3

In meinem Fall konnte ein Pod mit einem initContainer nicht initialisiert werden. Laufen docker ps -aund docker logs exited-container-id-heregab mir dann eine Protokollmeldung, die kubectl logs podnamenicht angezeigt wurde. Geheimnis gelüftet :-)


1

Es gibt viele verschiedene Möglichkeiten, dies zu erreichen, aber eine der elegantesten ist:

kubectl run -i --tty --image ubuntu:latest ubuntu-test --restart=Never --rm /bin/sh

Warum halten Sie es für die eleganteste Lösung?
Mordowiciel

0

Meine wenigen Cent zu diesem Thema. Angenommen, dies kubectlfunktioniert, dann wäre der nächste Befehl, der dem Docker-Befehl entspricht, den Sie in Ihrer Frage erwähnt haben, ungefähr so.

$ kubectl run ubuntu --image=ubuntu --restart=Never --command sleep infinity

Obige Befehl wird ein einzelnes erstellen Podin defaultNamespace und wird es ausführen sleepBefehl infinityArgument -einer Art und Weise erhalten Sie einen Prozess haben , dass läuft im Vordergrund zu halten Container am Leben.

Nachwörtern, mit denen Sie interagieren können, Podindem Sie den kubectl execBefehl ausführen.

$ kubectl exec ubuntu -it -- bash

Diese Technik ist sehr nützlich zum Erstellen einer Pod-Ressource und zum Ad-hoc-Debuggen.


1
Funktioniert super. Keine Notwendigkeit für --restart=Never, rufen Sie einfach ankubectl run ubuntu --image=ubuntu -- sleep infinity
Noam Manos
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.