¿Cómo expongo la API de Docker a través de TCP?

Estoy usando portainer y no puedo administrar puntos finales remotos. Intenté usar la línea de comandos para conectarme a nodos docker remotos, pero recibí un mensaje Cannot connect to the Docker daemon at tcp://<remote_ip>:<port>. Is the docker daemon running?.

Sí, están corriendo. Me he agregado al grupo de docker y puedo acceder a docker mediante SSH en los nodos. Sin embargo, no puedo acceder a ningún nodo de docker de forma remota.

Modifiqué /etc/default para agregar / quitar DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"

También modifiqué /etc/init.d/docker y /etc/init/docker.conf incluir DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock".

Reinicié el servicio docker, cerré la sesión e inicié sesión varias veces en el proceso, pero aún no puedo conectarme al nodo remoto. Ni siquiera puedo conectarme al nodo local pasando la IP.

¿Qué me perdí? ¿Qué configuración en qué archivo expone la API a través de TCP?

user@hostname:~$ docker -H tcp://<REMOTE_IP>:2375 infoCannot 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 infoCannot 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 infoCannot connect to the Docker daemon at tcp://<LOCAL_IP>:2375. Is the docker daemon running?user@hostname:~$

Editar:Ejecutar ps aux | grep -i docker devuelve esto -

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

Encontré una solución gracias a Publicación de Ivan Krizsan.

Tuve que editar /lib/systemd/system/docker.service en mi sistema Ubuntu 16.04.2 LTS para modificar la línea

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

entonces

sudo systemctl daemon-reloadsudo systemctl restart docker.service

y todo funcionó :-). El siguiente paso es descubrir cómo proteger el daemon de docker de ser secuestrado.

El directorio /etc/default es donde los mantenedores de la distribución colocan sus archivos de configuración. Si instala docker directamente desde los repositorios de Docker, este directorio no se utilizará.

El directorio / lib / systemd es donde los paquetes instalarán sus archivos systemd, y sobrescribirán cualquier cambio allí en la actualización. Si usa esto, sus cambios se perderán.

Para realizar sus propios cambios en un archivo de unidad systemd que persista, puede crear un archivo de unidad en /etc/systemd/system / docker.Servicio.d/, por ejemplo, aquí está mi estándar /etc / systemd/system / docker.Servicio.d / anular.conf:

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

Que reemplazan simplemente desactiva todos los indicadores de línea de comandos para la dockerd demonio de systemd. Una vez hecho esto, puede anular todas las configuraciones de /etc/docker/daemon.json que es utilizado por docker, y dependiendo de la configuración, se puede volver a cargar sin reiniciar el daemon. Por ejemplo, aquí hay un ejemplo de /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}

Para sus propósitos, solo necesita la línea allí para configurar los hosts.

Una parte extremadamente importante del archivo de configuración anterior son las configuraciones de TLS. Si no configura TLS mutuo entre el cliente y el servidor, y abre docker para escuchar en la red, está ejecutando el equivalente a un servidor telnet abierto con inicios de sesión raíz permitidos sin contraseña. Si prefiere ssh sobre telnet, o si prefiere tener una contraseña para su cuenta raíz, debe configurar TLS. Los puertos de la API de docker se escanean con frecuencia en Internet, y encontrará malware instalado en su host en poco tiempo si alguna vez omite este paso de configuración.

Los detalles completos sobre cómo configurar las claves TLS para el cliente y el servidor se pueden encontrar en:https://docs.docker.com/engine/security/https/


Tenga en cuenta que con las versiones de docker 18.09 y superiores en el cliente (tanto donde ejecuta el comando como en el nodo remoto), puede usar ssh en lugar de configurar TLS. Esto implica el uso de un DOCKER_HOST valor de ssh://user@host. P. ej.

docker -H ssh://user@host container ls

Hay una documentación oficial que describe cómo Configure dónde escucha el demonio de Docker las conexiones.

systemd vs demonio.json

Configuración de Docker para que escuche las conexiones mediante el archivo de unidad systemd y el demonio.el archivo json causa un conflicto que impide que se inicie Docker.

Configuración del acceso remoto con el archivo de unidad systemd

  1. Utilice el comando sudo systemctl edit docker.servicio para abrir un archivo de anulación para docker.servicio en un editor de texto.

  2. Agregue o modifique las siguientes líneas, sustituyendo sus propios valores.

    [Service]ExecStart=ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375
  3. Guarde el archivo.

  4. Vuelva a cargar la configuración de systemctl.

    $ sudo systemctl daemon-reload
  5. Reinicie Docker.

    $ sudo systemctl restart docker.service
  6. Compruebe si se ha respetado el cambio revisando la salida de netstat para confirmar que dockerd está escuchando en el puerto configurado.

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

Configuración del acceso remoto con daemon.json

  1. Establezca la matriz de hosts en /etc/docker / daemon.json para conectarse al socket UNIX y una dirección IP, de la siguiente manera:

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

    Configuración de Docker para que escuche las conexiones mediante el archivo de unidad systemd y el demonio.el archivo json causa un conflicto que impide que se inicie Docker.

    1. Agregue o modifique las siguientes líneas, sustituyendo sus propios valores.

      [Service]ExecStart=ExecStart=/usr/bin/dockerd
    2. Guarde el archivo.

    3. Vuelva a cargar la configuración de systemctl.

      $ sudo systemctl daemon-reload
  2. Reinicie Docker.

  3. Compruebe si se ha respetado el cambio revisando la salida de netstat para confirmar que dockerd está escuchando en el puerto configurado.

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

El cliente Docker respetará el DOCKER_HOST variable de entorno para establecer el -H bandera para el cliente. Utilice uno de los comandos siguientes:

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

o

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

Si no desea reconfigurar y reiniciar su demonio docker, simplemente puede conectar el socket unix a un socket TCP usando ncat (de la nmap paquete):

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

Como alternativa, puede utilizar socat u otras herramientas.

Para aquellos que buscan esta respuesta en el contexto de Ubuntu Server 20.04 que usa ENCAJAR:

Este comentario problema de github debería darte el contexto que necesitas. En mi caso, no encontré el conjunto de variables de entorno SNAP SNAP_DATA, así que tuve que buscar todo el demonio.archivos json en el sistema y usó el que tiene el /var prefijo

$ sudo find / -name daemon.json

En mi caso, tenía dos entradas no relacionadas, así que solo agregué la mía:

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

La IP anterior determina desde dónde será accesible, y el puerto puede ser cualquier puerto que desee exponer. En mi caso particular, no pude hacer que funcionara con una IP específica, en su lugar tuve que usar 0.0.0.0, de lo contrario fallaría con el siguiente error al reiniciar:

aufs aufs_fill_super:918:mount[3724]: no argoverlayfs: missing 'lowerdir'aufs aufs_fill_super:918:mount[3772]: no argoverlayfs: missing 'lowerdir'aufs aufs_fill_super:918:mount[3820]: no argoverlayfs: missing 'lowerdir'

Curiosamente, cuando se usa 0.0.0.0, en realidad escupe un par de las líneas de error anteriores, pero funciona después. En mi caso, como se trata de una máquina virtual, esto es aceptable para mí.

Intenté cosas similares y sospecho que los archivos /etc/default/docker, /etc/init/docker.conf y /etc / init.d / docker simplemente se ignoran en Ubuntu 16.04 con una instalación de docker-ce, ¿alguien puede confirmar? Creo que cuando ejecuto " service docker status “lo que realmente sucede es” systemctl status docker", un sistema de administración completamente diferente.

Es 2375 escuchando? "ss-ntl`

No. No hay nada escuchando en el 2375. Y no puedo averiguar qué configuración en qué archivo afecta esto. He incluido la salida de ‘ps aux’ en mi respuesta si eso ayuda.