J'essaie maintenant d'exécuter un simple conteneur avec Shell (/ bin/bash) sur un cluster Kubernetes.
Je pensais qu'il était possible de garder un conteneur en cours d'exécution sur un conteneur Docker en utilisant pseudo-tty
et l'option detach (option -td
sur la commande docker run
).
Par exemple,
$ Sudo docker run -td ubuntu:latest
Existe-t-il une option comme celle-ci dans Kubernetes?
J'ai essayé d'exécuter un conteneur en utilisant une commande kubectl run-container
comme:
kubectl run-container test_container ubuntu:latest --replicas=1
Mais le conteneur se ferme pendant quelques secondes (comme si vous lanciez avec la commande docker run
sans les options mentionnées ci-dessus). Et ReplicationController le relance à plusieurs reprises.
Existe-t-il un moyen de garder un conteneur s'exécutant sur Kubernetes tel que les options -td
de la commande docker run
?
Un conteneur se ferme lorsque son processus principal se termine. Faire quelque chose comme:
docker run -itd debian
tenir le conteneur ouvert est franchement un hack qui ne devrait être utilisé que pour des tests rapides et des exemples. Si vous voulez juste un conteneur pour tester pendant quelques minutes, je ferais:
docker run -d debian sleep 300
Ce qui a l'avantage que le conteneur se fermera automatiquement si vous l'oubliez. Alternativement, vous pouvez mettre quelque chose comme ceci dans une boucle while
pour qu'elle continue à fonctionner pour toujours, ou simplement exécuter une application telle que top
. Tout cela devrait être facile à faire à Kubernetes.
La vraie question est pourquoi voudriez-vous faire cela? Votre conteneur doit fournir un service, dont le processus gardera le conteneur en cours d'exécution en arrière-plan.
Vous pouvez utiliser ce CMD dans votre Dockerfile
:
CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"
Cela gardera votre conteneur en vie jusqu'à ce qu'on vous dise d'arrêter L'utilisation de trap et wait fera en sorte que votre conteneur réagisse immédiatement à une demande d'arrêt . Sans piège/attente, l’arrêt prendra quelques secondes.
Pour les images basées sur busybox (utilisées dans les images basées sur Alpine), le sommeil ne connaît pas l'argument infini. Cette solution de contournement vous donne la même réponse immédiate à un docker stop
comme dans l'exemple ci-dessus:
CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"
Les conteneurs sont destinés à être terminés. Vous devez fournir à votre conteneur une tâche qui ne sera jamais terminée. Quelque chose comme ça devrait marcher:
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;" ]
Dans votre fichier Docker, utilisez cette commande:
CMD ["sh", "-c", "tail -f /dev/null"]
Construisez votre image de menu fixe.
kubectl run debug-container -it --image=<your-image>
Afin de laisser un POD en fonctionnement, le POD doit exécuter certaines tâches, sinon Kubernetes le jugera inutile et par conséquent il se fermera. Il y a beaucoup de façons de faire fonctionner un POD.
J'ai rencontré des problèmes similaires lorsque j'avais besoin d'un POD pour pouvoir continuer à fonctionner sans rien faire. Voici les deux façons dont ceux-ci ont fonctionné pour moi:
Bien que la première option soit plus facile que la seconde et puisse suffire à l'exigence, ce n'est pas la meilleure option. En tant que, il existe une limite quant au nombre de secondes que vous allez attribuer dans la commande de veille. Mais un conteneur avec une boucle infinie s'exécutant à l'intérieur ne se ferme jamais.
Cependant, je vais décrire les deux manières (considérant que vous utilisez un conteneur busybox):
1. Commande de sommeil
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. Boucle Infinie
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
Exécutez la commande suivante pour exécuter le pod:
kubectl apply -f <pod-yaml-file-name>.yaml
J'espère que ça aide!
J'ai pu faire en sorte que cela fonctionne avec la commande sleep infinity
dans Kubernetes, qui gardera le conteneur ouvert. Voir cette réponse pour des alternatives lorsque cela ne fonctionne pas.
Utilisez cette commande à l'intérieur de votre fichier Docker pour conserver le conteneur en cours d'exécution dans votre cluster K8:
La commande la plus simple qui soit pour le manifeste du k8s pod consiste à exécuter le conteneur pour toujours:
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
containers:
- name: ubuntu
image: ubuntu:latest
# Just sleep forever
command: [ "sleep" ]
args: [ "infinity" ]
Dans mon cas, un pod avec un initContainer n'a pas pu s'initialiser. Exécuter docker ps -a
puis docker logs exited-container-id-here
m’a donné un message de journal que kubectl logs podname
n’a pas affiché. Mystère résolu :-)