4
votes

Comment `` docker exec '' un conteneur construit à partir de zéro?

J'essaye de docker exec un conteneur qui est construit à partir de zéro (par exemple, un conteneur NATS). Cela semble assez simple, mais comme il est construit à partir de zéro, je ne peux pas accéder à / bin / bash , / bin / sh et littéralement à une telle commande.

J'obtiens l'erreur: oci runtime error (commande not found, file not found, etc. selon la commande que j'entre).

J'ai essayé des commandes comme:

docker exec -it <container name> /bin/bash
docker exec -it <container name> /bin/sh
docker exec -it <container name> ls

Ma question est la suivante: comment docker exec un conteneur qui est construit à partir de zéro et composé uniquement de binaires? En faisant un docker exec , je souhaite savoir si les fichiers ont été copiés avec succès de mon hôte vers le conteneur (j'ai un COPY dans le Dockerfile ).


1 commentaires

Cela dit, docker run --entrypoint ferait aussi l'affaire, puisque je souhaite juste vérifier si les fichiers ont été copiés.


3 Réponses :


1
votes

Vous ne pouvez utiliser docker exec que pour exécuter des commandes qui existent réellement dans un conteneur. Si ces commandes n'existent pas, vous ne pouvez pas les exécuter. Comme vous l'avez noté, l'image de base scratch ne contient rien - pas de shells, pas de bibliothèques, pas de fichiers système, rien .

Si tout ce que vous essayez de vérifier, c'est si une commande Dockerfile COPY a effectivement copié les fichiers que vous avez dit qu'elle le ferait, je suppose généralement que l'outillage fonctionne et ne fait référence qu'aux fichiers copiés dans mon application .

Puisqu'il semble que vous contrôliez le Dockerfile, une solution de contournement pourrait être de changer l'image de base en quelque chose de léger mais non vide, comme FROM busybox . Cela vous donnerait un ensemble minimal d'outils avec lesquels vous pourriez travailler sans trop augmenter la taille de l'image.


1 commentaires

Merci pour votre réponse. Donc, juste pour clarifier, j'ai cloné un repo de production et essayé de copier des fichiers d'hôte en conteneur en modifiant le Dockerfile local. C’est pourquoi la modification du Dockerfile pour inclure quelque chose comme busybox ne serait pas exactement ce qui se passerait en production. Bien sûr, je peux l'utiliser à des fins de test, mais s'il y a une commande que je peux utiliser pour tester le transfert, ce serait plus proche de ce qui se passe en production et serait plus utile.



3
votes

Il existe plusieurs options.

  1. Vous pouvez faire docker container cp $ {CONTAINER}: / path / to / file / on / container / path / to / temp / dir / on / host . Cela copiera les fichiers sur votre hôte où vous pourrez inspecter les choses à l'aide des outils de l'hôte.
  2. Vous pouvez ajouter un VOLUME approprié à votre Dockerfile. Ensuite, vous pouvez docker container inspecter $ {CONTAINER} . Cela exposera le nom du volume où les fichiers devraient être. Vous pouvez ensuite les inspecter dans un autre conteneur (basé sur une image avec tous les outils dont vous avez besoin).
  3. Vous pouvez au moment de l'exécution lier le conteneur à un volume ou à un répertoire hôte à l'emplacement approprié.
  4. Vous pouvez ajouter les binaires dont vous pensez avoir besoin à l'image. Si vous avez besoin de / bin / ls ou / bin / sh , vous pouvez les ajouter.
  5. Vous pouvez lier le montage des binaires nécessaires au conteneur - le conteneur les a donc à des fins de vérification mais l'image n'est pas gonflée par eux.

1 commentaires

Merci pour la réponse, mais cela ne répond pas précisément à ma question sur la possibilité de «docker exec» un conteneur minimal.



5
votes

Si votre conteneur de travail est en cours d'exécution, vous pouvez copier un shell (et d'autres utilitaires nécessaires) dans son système de fichiers, puis l'exécuter. Le shell devrait être un binaire statique. Busybox est un excellent choix ici car il peut doubler comme tant d'autres binaires.

Exemple complet:

# Assumes scratch container is last launched one, else replace with container ID of
# scratch image, e.g. from `docker ps`, for example:
# scratch_container_id=401b31621b36
scratch_container_id=$(docker ps -ql)

docker run -d busybox:latest sleep 100
busybox_container_id=$(docker ps -ql)
docker cp "$busybox_container_id":/bin/busybox .

# The busybox binary will become whatever you name it (or the first arg you pass to it), for more info run:
# docker run busybox:latest /bin/busybox
# The `busybox --install` command copies the binary with different names into a directory.

docker cp ./busybox "$scratch_container_id":/busybox

docker exec -it "$scratch_container_id" /busybox sh -c '
export PATH="/busybin:$PATH"
/busybox mkdir /busybin
/busybox --install /busybin
sh'

Pour Kubernetes, je pense que Les conteneurs éphémères fournissent ou fourniront des fonctionnalités équivalentes.

Références: Erreur d'image du docker Java distroless https://github.com/GoogleContainerTools/distroless/issues/168#issuecomment- 371077961


0 commentaires