est-il possible (à l'aide de la commande docker
ou de l'API docker-py
directement) de démarrer un conteneur à partir d'un hôte distant?
Supposons que j'ai deux machines ayant des architectures différentes: - A est une machine x86
- B est une machine ARM
Je souhaite exécuter un conteneur sur la machine B en utilisant ma machine A. Au début, je pensais que c'était possible avec cette commande:
[A]$> DOCKER_Host=$MACHINE_B_IP:$MACHIN_B_PORT docker run hello-from-B
Mais cette commande extrait en fait l'image hello-from-B
et tente de l'exécuter sur la machine A, ce qui aboutit à un certain exec format error
car il est évidemment impossible d'exécuter des images spécifiques à ARM
sur une machine x86
.
La communication entre les machines A et B fonctionne bien. Je peux exécuter des commandes telles que images
ou ps
et cela me donne les résultats attendus:
[A]$> DOCKER_Host=$MACHINE_B_IP:$MACHIN_B_PORT docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-from-B <none> fd5059044831 13 hours ago 1.26GB
J'ai entendu parler de docker-machine
et je ne l'ai pas encore essayé, mais si j'ai bien compris, cela ne résoudra pas mon problème.
Existe-t-il un moyen d’y parvenir en utilisant docker
directement. Une solution de contournement pourrait consister à utiliser ssh
pour se connecter à l'hôte distant et utiliser le client docker
directement à partir de l'hôte distant, mais j'aimerais éviter autant que possible cette solution.
Merci d'avance,
TL; DR;
Comment DOCKER_Host=... docker run something
peut-il exécuter something
sur le DOCKER_Host
plutôt que de l'exécuter sur ma machine locale.
si votre machine ciblée B pouvait être créée sur l'une de ces ces plateformes , alors je suppose que docker-machine répondrait à vos besoins. vous créeriez votre machine en utilisant docker-machine create --driver <..driver setup..> MACHINE_B
, puis vous l'activerez en utilisant eval $(docker-machine env MACHINE_B)
. docker-machine env MACHINE_B
imprimera certaines déclarations d'exportation:
export DOCKER_TLS_VERIFY="1"
export DOCKER_Host="tcp://...."
export DOCKER_CERT_PATH="/..."
export DOCKER_MACHINE_NAME="MACHINE_B"
une fois que votre machine est active, vous pouvez utiliser la commande docker
comme vous le feriez localement pour agir à distance sur MACHINE_B.
Vérifiez si le dernier menu fixe 18.09 inclut cette fonctionnalité.
Voir docker/cli PR 1014
Ajout du support pour la connexion SSH. par exemple.
docker -H ssh://me@server
- La cli doit accepter
ssh://me@server
pourDOCKER_Host
et-H
. Utiliser cela exécuterait ssh avec la config passée.- La commande ssh appelle une commande cachée sur le binaire CLI du docker du côté distant. Par exemple, docker dial-stdio.
Cette commande établira une connexion avec la variable
DOCKER_Host
locale (presque toujours la socket locale par défaut) et transférera cette connexion sur les commandes stdio.
Même si cette commande est supposée être exécutée localement sur le binairedockerd
, nous pensons que la suppression du binaire localdocker
par cette fonctionnalité est une configuration non valide.Comment le vérifier
docker -H ssh://me@server run -it --rm busybox
La réaction jusqu'à présent:
Des administrateurs et des administrateurs système du monde entier, nous vous remercions pour cette fonctionnalité fantastique et inattendue.
J'espère que cela réduira sérieusement le nombre de fois où je vois des personnes ouvrirdockerd
TCP sans TLS et opter pour les terminaux SSH pour la gestion à distance.
Cet article explique très bien le concept: https://docs.docker.com/engine/reference/commandline/dockerd/#bind-docker-to-an-hostport-or-a-unun-socket
Compte tenu de l'énorme avertissement affiché sur la page, je vous suggère d'utiliser une connexion sécurisée via SSH, par exemple. ssh user@Host 'docker run hello-from-B'
Avertissement: le fait de changer la liaison du démon du docker par défaut en un port TCP ou un groupe d'utilisateurs du dockeur Unix augmentera vos risques de sécurité de Permettant aux utilisateurs non root d'obtenir un accès root sur l'hôte. Assurez-vous vous contrôlez l'accès au menu fixe. Si vous vous connectez à un port TCP, toute personne ayant accès à ce port dispose d'un accès complet au menu fixe, il n'est donc pas conseillé sur un réseau ouvert.
Avec -H, il est possible de faire en sorte que le démon Docker écoute sur un fichier IP et port spécifiques. Par défaut, il écoutera
unix:///var/run/docker.sock
pour n'autoriser que les connexions locales par le utilisateur root. Vous pouvez le définir sur0.0.0.0:2375
ou une adresse IP d'hôte spécifique sur donner accès à tout le monde, mais ce n'est pas recommandé, car alors est trivial pour quelqu'un d'accéder root à l'hôte où le le démon est en cours d'exécution.De même, le client Docker peut utiliser
-H
pour se connecter à un port personnalisé . Le client Docker se connectera par défaut àunix:///var/run/docker.sock
sous Linux ettcp://127.0.0.1:2376
sous Les fenêtres.-H accepte l’attribution d’hôte et de port au format suivant:
tcp://[Host]:[port][path] or unix://path
Vous pouvez utiliser multiple -H, par exemple, si vous souhaitez écouter les deux TCP et un socket Unix
# Run docker in daemon mode $ Sudo <path to>/dockerd -H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock & # Download an ubuntu image, use default Unix socket $ docker pull ubuntu # OR use the TCP port $ docker -H tcp://127.0.0.1:2375 pull ubuntu
Comme vous l'avez dit, la connectivité est disponible entre les serveurs, vous pouvez utiliser les API riches de Docker.
Il y a 2 façons de configurer le port du démon docker
1) Configuration dans le fichier / etc/default/docker:
DOCKER_OPTS="-H tcp://127.0.0.1:5000 -H unix:///var/run/docker.sock"
2) Configuration à /etc/docker/daemon.json:
{
"hosts": ["tcp://127.0.0.1:5000", "unix:///var/run/docker.sock"]
}
Pour plus de détails sur la configuration du port du démon docker, reportez-vous à configure-docker-daemon-port
Une fois les ports Docker configurés, vous pouvez accéder aux API Docker de l'hôte distant.
Fichier d'entrée JSON:
#cat container_create.json
{
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"ExposedPorts": {
"property1": {},
"property2": {}
},
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Cmd": null,
"Image": "ubuntu:14.04",
"Volumes": {
"additionalProperties": {}
},
"Labels": {
"property1": "string",
"property2": "string"
}
}
API pour créer un conteneur:
curl -X POST http://192.168.56.101:6000/containers/create -d @container_create.json --header "Content-Type: application/json" | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 602 100 90 100 512 1737 9883 --:--:-- --:--:-- --:--:-- 10039
{
"Warnings": null,
"Id": "f5d3273e48350d606bd8b9d2a5bd876dc5c2d1a73183f876a1dd56473cad8940"
}
L'ID généré est l'ID du conteneur et le statut ne sera pas actif/en cours d'exécution.
API pour démarrer le conteneur créé.
# curl -X POST http://192.168.56.101:6000/containers/f5d3273e48350/start | jq . % Total % Received % Xferd Average Speed Time Time Time Current
API pour vérifier l'état/inspecter le conteneur:
# curl -X GET http://192.168.56.101:6000/containers/f5d3273e48350/json | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4076 0 4076 0 0 278k 0 --:--:-- --:--:-- --:--:-- 306k
{
"NetworkSettings": {
"Networks": {
"bridge": {
"MacAddress": "02:42:ac:11:00:03",
"GlobalIPv6PrefixLen": 0,
"GlobalIPv6Address": "",
"IPv6Gateway": "",
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "689d6b65ce1b06c93b2c70f41760a3e7fb2b50697d71cd9c1f39c64c865e5fa6",
"EndpointID": "76bf1f8638d1ff0387e6c3fe89e8ccab1670c709ad550f9acc6f46e559654bee",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16
}
},
"MacAddress": "02:42:ac:11:00:03",
"SecondaryIPAddresses": null,
"SandboxKey": "/var/run/docker/netns/24a031d9dfda",
"Ports": {
"0/tcp": null
},
"LinkLocalIPv6PrefixLen": 0,
"LinkLocalIPv6Address": "",
"HairpinMode": false,
"SandboxID": "24a031d9dfda70026a875f4841269c5e790b12ccafcc11869111faa240020b99",
"Bridge": "",
"SecondaryIPv6Addresses": null,
"EndpointID": "76bf1f8638d1ff0387e6c3fe89e8ccab1670c709ad550f9acc6f46e559654bee",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": ""
},
},
"AttachStderr": true,
"AttachStdout": true,
"AttachStdin": true,
"User": "",
"Domainname": "",
"Hostname": "f5d3273e4835",
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"ArgsEscaped": true,
"Image": "ubuntu:14.04",
<*************REMOVING THE OUTPUT CONTENT********>
"ExecIDs": null,
"HostnamePath": "/var/lib/docker/containers/f5d3273e48350d606bd8b9d2a5bd876dc5c2d1a73183f876a1dd56473cad8940/hostname",
"ResolvConfPath": "/var/lib/docker/containers/f5d3273e48350d606bd8b9d2a5bd876dc5c2d1a73183f876a1dd56473cad8940/resolv.conf",
"Image": "sha256:132b7427a3b40f958aaeae8716e0cbb2177658d2410554ed142e583ef522309f",
"State": {
"FinishedAt": "0001-01-01T00:00:00Z",
"StartedAt": "2017-06-09T06:53:45.120357144Z",
"Error": "",
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"Path": "/bin/bash",
"Created": "2017-06-09T06:52:51.820429355Z",
"Id": "f5d3273e48350d606bd8b9d2a5bd876dc5c2d1a73183f876a1dd56473cad8940",
"HostsPath": "/var/lib/docker/containers/f5d3273e48350d606bd8b9d2a5bd876dc5c2d1a73183f876a1dd56473cad8940/hosts",
"LogPath": "/var/lib/docker/containers/f5d3273e48350d606bd8b9d2a5bd876dc5c2d1a73183f876a1dd56473cad8940/f5d3273e48350d606bd8b9d2a5bd876dc5c2d1a73183f876a1dd56473cad8940-json.log",
"Name": "/objective_bartik",
"RestartCount": 0,
"Driver": "aufs",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default"
}
Référez-vous ceci pour plus d'informations:
Comment construire une image en utilisant l'API Docker?
Comment valider Docker Container à l'aide de l'API
J'espère que cette information vous sera utile.