Comment exposer l'API Docker sur TCP?

13

J'utilise portainer et je ne parviens pas à gérer les points de terminaison distants. J'ai essayé d'utiliser la ligne de commande pour me connecter à des nœuds de docker distants, mais j'ai reçu un message Cannot connect to the Docker daemon at tcp://<remote_ip>:<port>. Is the docker daemon running?.

Oui, ils courent. Je me suis ajouté au groupe Docker et je peux accéder à Docker par SSHing dans les nœuds. Cependant, je ne peux accéder à aucun nœud docker à distance.

J'ai modifié /etc/defaultpour ajouter / décommenterDOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"

J'ai également modifié /etc/init.d/dockeret /etc/init/docker.confinclus DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock".

J'ai redémarré le service Docker, je me suis déconnecté et connecté plusieurs fois au cours du processus, mais je ne parviens toujours pas à me connecter au nœud distant. Je ne peux même pas me connecter au nœud local en passant l'IP.

Qu'est-ce que j'ai raté? Quelle configuration dans quel fichier expose l'API sur TCP?

user@hostname:~$ docker -H tcp://<REMOTE_IP>:2375 info
Cannot connect to the Docker daemon at tcp://<REMOTE_IP>:2375. Is the docker daemon running?
user@hostname:~$ docker -H tcp://127.0.0.1:2375 info
Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running?
user@hostname:~$ docker -H tcp://<LOCAL_IP>:2375 info
Cannot connect to the Docker daemon at tcp://<LOCAL_IP>:2375. Is the docker daemon running?
user@hostname:~$

Edit: Running ps aux | grep -i dockerrenvoie ceci -

root      3581  0.1  0.2 596800 41540 ?        Ssl  04:17   0:35 /usr/bin/dockerd -H fd://
root      3588  0.0  0.0 653576 14492 ?        Ssl  04:17   0:18 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc
Lord Loh.
la source
Le 2375 écoute-t-il? ss -ntl
jscott
Non. Il n'y a rien d'écoute sur 2375. Et je ne peux pas comprendre quelle configuration dans quel fichier affecte cela. J'ai inclus la sortie de ps auxdans ma réponse si cela aide.
Lord Loh.
J'ai essayé des choses similaires et je soupçonne que les fichiers / etc / default / docker, /etc/init/docker.conf et /etc/init.d/docker sont simplement ignorés sur Ubuntu 16.04 avec une installation de docker-ce, quelqu'un peut-il confirmer ? Je pense que lorsque je lance "Service Docker Status", ce qui se passe vraiment est "Systemctl Status Docker", un tout autre système de gestion.
chrisinmtown

Réponses:

22

J'ai trouvé une solution grâce au post d'Ivan Krizsan .

J'ai dû éditer /lib/systemd/system/docker.servicesur mon système Ubuntu 16.04.2 LTS pour modifier la ligne

ExecStart=/usr/bin/docker daemon -H fd:// -H tcp://0.0.0.0:

ensuite

sudo systemctl daemon-reload
sudo systemctl restart docker.service

et tout a fonctionné :-). L'étape suivante consiste à comprendre comment protéger le formulaire de démon docker détourné.

Lord Loh.
la source
1
Je confirme que ce changement amène Dockerd à écouter les requêtes HTTP sur Ubuntu 16.04 avec docker-ce ver 17.06. Il est tout simplement inapproprié de modifier directement le script de service.
chrisinmtown
7
Ne modifiez jamais le script de service docker (ou tout script de service) directement. SystemD a une fonction d'édition différentielle intégrée. Utilisez systemctl edit docker.serviceet systemctl créera un nouveau fichier avec vos modifications. Cela empêche une mise à jour d'effacer vos modifications. SystemD fusionnera les deux fichiers lors de l'exécution. Bon document ici: digitalocean.com/community/tutorials/…
Routhinator
Merci! C'est terriblement utile. Je reçois toujours des avertissements pendant les mises à jour. J'examinerai ceci: _)
Lord Loh.
4
Sur Ubuntu Server 18.04, cela fonctionnait comme ceci:ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:4243
LUCIAN ALEXA
lorsque j'utilise le -H tcp://paramètre lui-même, sans le -H fd://paramètre, je ne peux pas émettre de commandes client, par exemple .., info docker, version docker, etc.
Chris F
2

Le répertoire / etc / default est l'endroit où les responsables de la distribution placent leurs fichiers de configuration. Si vous installez Docker directement à partir des référentiels de Docker, ce répertoire ne sera pas utilisé.

Le répertoire / lib / systemd est l'endroit où les packages installeront leurs fichiers systemd et ils écraseront toutes les modifications lors de la mise à niveau. Si vous l'utilisez, vos modifications seront perdues.

Pour apporter vos propres modifications à un fichier d'unité systemd qui persistent, vous pouvez créer un fichier d'unité dans /etc/systemd/system/docker.service.d/, par exemple voici mon /etc/systemd/system/docker.service standard. d / override.conf:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd

Cette substitution désactive simplement tous les indicateurs de ligne de commande pour le démon dockerd de systemd. Une fois cela fait, vous pouvez remplacer chaque paramètre de /etc/docker/daemon.json qui est utilisé par docker et, selon le paramètre, peut être rechargé sans redémarrer le démon. Par exemple, voici un exemple /etc/docker/daemon.json:

{
"debug": false,
"experimental": true,
"hosts": ["fd://", "tcp://0.0.0.0:2376"],
"labels": ["foo=bar", "fez=baz"],
"log-driver": "json-file",
"log-opts": {"max-size": "10m", "max-file": "3"},
"storage-driver": "overlay2",
"tlscacert": "/etc/docker/certs/ca.pem",
"tlscert": "/etc/docker/certs/host-cert.pem",
"tlskey": "/etc/docker/certs/host-key.pem",
"tlsverify": true
}

Pour vos besoins, vous n'avez besoin que de la ligne pour définir les hôtes.

Les paramètres TLS sont une partie extrêmement importante du fichier de configuration ci-dessus. Si vous ne configurez pas TLS mutuel entre le client et le serveur et que vous ouvrez Docker pour écouter sur le réseau, vous exécutez l'équivalent d'un serveur Telnet ouvert avec des connexions root autorisées sans mot de passe. Si vous préférez ssh à telnet ou si vous préférez avoir un mot de passe pour votre compte root, vous devez configurer TLS. Les ports de l'API Docker sont fréquemment analysés sur Internet et vous trouverez rapidement des logiciels malveillants installés sur votre hôte si vous sautez cette étape de configuration.

Tous les détails sur la façon de configurer les clés TLS pour le client et le serveur sont disponibles sur: https://docs.docker.com/engine/security/https/

BMitch
la source
1
Une très bonne réponse qui survivra aux futures mises à jour du service docker. C'est la bonne façon de procéder.
Fopedush
2

Si vous ne voulez pas reconfigurer et redémarrer votre démon docker, vous pouvez simplement relier le socket unix à un socket TCP en utilisant ncat(à partir du nmappackage):

ncat -lknvp 2375 -c "ncat -U /var/run/docker.sock"

Comme alternative, vous pouvez utiliser socat ou d'autres outils .

eadmaster
la source
incroyable! puis-je exécuter cette commande en arrière-plan? quand je ferme ma connexion au terminal est perdue
Felix
ah j'ai trouvé nohupet&
Felix
0

Il existe une documentation officielle qui décrit comment configurer où le démon Docker écoute les connexions .

systemd vs daemon.json

La configuration de Docker pour écouter les connexions utilisant à la fois le fichier d'unité systemd et le fichier daemon.json provoque un conflit qui empêche le démarrage de Docker.

Configuration de l'accès à distance avec le fichier d'unité systemd

  1. Utilisez la commande sudo systemctl edit docker.service pour ouvrir un fichier de remplacement pour docker.service dans un éditeur de texte.

  2. Ajoutez ou modifiez les lignes suivantes, en remplaçant vos propres valeurs.

    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375
    
  3. Enregistrez le fichier.

  4. Rechargez la configuration systemctl.

    $ sudo systemctl daemon-reload
    
  5. Redémarrez Docker.

    $ sudo systemctl restart docker.service
    
  6. Vérifiez si la modification a été respectée en examinant la sortie de netstat pour confirmer que dockerd écoute sur le port configuré.

    $ sudo netstat -lntp | grep dockerd
    tcp        0      0 127.0.0.1:2375          0.0.0.0:*               LISTEN      3758/dockerd
    

Configuration de l'accès à distance avec daemon.json

  1. Définissez le tableau d'hôtes dans /etc/docker/daemon.json pour se connecter au socket UNIX et à une adresse IP, comme suit:

    {
    "hosts": ["unix:///var/run/docker.sock", "tcp://127.0.0.1:2375"]
    }
    

    La configuration de Docker pour écouter les connexions utilisant à la fois le fichier d'unité systemd et le fichier daemon.json provoque un conflit qui empêche le démarrage de Docker.

    1. Ajoutez ou modifiez les lignes suivantes, en remplaçant vos propres valeurs.

      [Service]
      ExecStart=
      ExecStart=/usr/bin/dockerd
      
    2. Enregistrez le fichier.

    3. Rechargez la configuration systemctl.

      $ sudo systemctl daemon-reload
      
  2. Redémarrez Docker.

  3. Vérifiez si la modification a été respectée en examinant la sortie de netstat pour confirmer que dockerd écoute sur le port configuré.

    $ sudo netstat -lntp | grep dockerd
    tcp        0      0 127.0.0.1:2375          0.0.0.0:*               LISTEN      3758/dockerd
    

Le client Docker honorera la DOCKER_HOSTvariable d'environnement pour définir l' -Hindicateur pour le client. Utilisez l'une des commandes suivantes:

$ docker -H tcp://127.0.0.1:2375 ps

ou

$ export DOCKER_HOST="tcp://127.0.0.1:2375"
$ docker ps
ROY
la source