Ich versuche jetzt, einen einfachen Container mit Shell (/ bin/bash) auf einem Kubernetes-Cluster auszuführen.
Ich dachte, es gäbe eine Möglichkeit, einen Container in einem Docker-Container unter Verwendung von pseudo-tty
und der Option zum Trennen (-td
-Option im Befehl docker run
) auszuführen.
Zum Beispiel,
$ Sudo docker run -td ubuntu:latest
Gibt es eine solche Option in Kubernetes?
Ich habe versucht, einen Container mit einem kubectl run-container
-Befehl auszuführen:
kubectl run-container test_container ubuntu:latest --replicas=1
Der Container wird jedoch für einige Sekunden beendet (genauso wie das Starten mit dem Befehl docker run
ohne die oben erwähnten Optionen). ReplicationController startet es immer wieder neu.
Gibt es eine Möglichkeit, einen Container auf Kubernetes wie die -td
-Optionen im docker run
-Befehl laufen zu lassen?
Ein Container wird beendet, wenn sein Hauptprozess beendet wird. Etwas tun wie:
docker run -itd debian
offenhalten des Behälters ist ein Hack, der nur für schnelle Tests und Beispiele verwendet werden sollte. Wenn Sie nur für einige Minuten einen Container zum Testen wünschen, würde ich Folgendes tun:
docker run -d debian sleep 300
Dies hat den Vorteil, dass der Container automatisch beendet wird, wenn Sie ihn vergessen. Alternativ können Sie so etwas in eine while
-Schleife einfügen, um es für immer laufen zu lassen, oder einfach eine Anwendung wie top
ausführen. All dies sollte in Kubernetes leicht zu bewerkstelligen sein.
Die eigentliche Frage ist, warum sollten Sie das tun? Ihr Container sollte einen Dienst bereitstellen, dessen Prozess den Container im Hintergrund laufen lässt.
Sie könnten diese CMD in Ihrer Dockerfile
verwenden:
CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"
Dies hält Ihren Container am Leben, bis er aufgefordert wird, anzuhalten. Wenn Sie trap and wait verwenden, wird Ihr Container sofort auf eine Stop-Anforderung reagieren . Ohne Trap/Wait dauert das Stoppen einige Sekunden.
Für busybox-basierte Bilder (in Alpine-basierten Bildern verwendet) kennt der Schlaf keine Informationen über das Argument unendlich. Diese Problemumgehung gibt Ihnen dieselbe unmittelbare Antwort auf einen docker stop
wie im obigen Beispiel:
CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"
Container sollen komplett ausgeführt werden. Sie müssen Ihrem Container eine Aufgabe geben, 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;" ]
Verwenden Sie in Ihrer Docker-Datei diesen Befehl:
CMD ["sh", "-c", "tail -f /dev/null"]
Bauen Sie Ihr Docker-Image auf.
kubectl run debug-container -it --image=<your-image>
Um einen POD am Laufen zu halten, sollte der POD eine bestimmte Aufgabe ausführen, da Kubernetes ihn sonst für unnötig hält und ihn 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 beiden folgenden Möglichkeiten haben bei mir funktioniert:
Die erste Option ist zwar einfacher als die zweite und reicht möglicherweise aus, sie ist jedoch nicht die beste Option. Es gibt ein Limit für die Anzahl der Sekunden, die Sie im Befehl sleep zuweisen. Ein Container mit einer Endlosschleife wird jedoch niemals verlassen.
Ich werde jedoch beide Möglichkeiten beschreiben (unter der Annahme, dass 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
Hoffe es hilft!
Ich konnte dies mit dem Befehl sleep infinity
in Kubernetes erreichen, der den Container offen hält. Siehe diese Antwort für Alternativen, wenn das nicht funktioniert.
Verwenden Sie diesen Befehl in Ihrer Docker-Datei, um den Container in Ihrem K8-Cluster weiter auszuführen:
Der einfachste Befehl für das Podmanifest von k8s, 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" ]
In meinem Fall konnte ein Pod mit einem initContainer nicht initialisiert werden. Durch Ausführen von docker ps -a
und dann docker logs exited-container-id-here
wurde eine Protokollmeldung angezeigt, die kubectl logs podname
nicht angezeigt wurde. Geheimnis gelüftet :-)