Actualización 1

Actualización 1

Estoy intentando configurar un enjambre de ventanas acoplables.

Necesito que mis nodos se comuniquen a través de TLS.

He creado un certificado para el nodo administrador con extendedKeyUsage = serverAuth

He configurado el nodo administrador con el siguiente daemon.json:

{
    "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
    "tlscacert": "/var/docker/ca.pem",
    "tlscert": "/var/docker/server-cert.pem",
    "tlskey": "/var/docker/server-key.pem",
    "tlsverify": true
}

Para probar esto, creé un certificado de cliente y lo usé para conectarme a la API de Docker desde mi computadora portátil y puedo conectarme exitosamente.

Ahora necesito agregar un nodo trabajador al enjambre.

Lo configuré de la misma manera que el nodo administrador; con un daemon.json similar. Utilicé una clave SSL con extendedKeyUsage = serverAuth y probé la conexión del cliente de la misma manera que en el nodo administrador.

Luego, en el administrador ejecuté docker swarm init

Para unir el nodo trabajador al enjambre uso el siguiente comando: docker swarm join --token XXX dockman.myhost.com:2376

Pero me sale un error:

Error response from daemon: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: authentication handshake failed: remote error: tls: bad certificate"

Pensé que podría probarlo más al intentar conectarme a la API de la ventana acoplable en el nodo administrador desde el nodo trabajador:

sudo docker --tlsverify --tlscacert=/var/docker/ca.pem --tlscert=./server-cert.pem --tlskey=./server-key.pem -H=127.0.0.1:2376 version

El resultado es:

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false
The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: Get https://127.0.0.1:2376/v1.40/version: remote error: tls: bad certificate

Esta segunda prueba me ha dado mucho más en qué pensar. Por supuesto, fallará porque estoy intentando conectarme con un certificado de servidor y no con un certificado de cliente, pero ¿no es eso exactamente lo que intenta hacer Docker Swarm Join? Para mí no tiene sentido poner el certificado del cliente en daemon.json. Busqué en Google cómo crear un certificado único tanto para el servidor como para el cliente y es posible, pero parece ser una mala práctica. Pensé que se habría cubierto en el tutorial si fuera necesario.

Me he quedado estancado en este punto. No puedo determinar qué configuración de certificado se requiere.

he estado siguiendo https://github.com/docker/docker.github.io/blob/master/swarm/configure-tls.md Esto describe la creación de certificados pero no menciona en absoluto la autenticación del cliente o del servidor.

Actualización 1

Encontré un documento que decía que los certificados deben ser cliente y servidor.

https://hub.docker.com/_/swarm/

Así que rehice el certificado del nodo para que sea tanto cliente como servidor. Ahora el comando de la versión de Docker funciona cuando se ejecuta desde el nodo pero no cuando se une al enjambre.

Respuesta1

Estás mezclando el modo Swarm ( docker swarmy CLI similares) con el Swarm clásico basado en contenedores (alojado como un contenedor en Docker Hub). Estas son dos herramientas diferentes.

Para los dos conjuntos de documentación, consulte:

No es necesario realizar ninguna configuración TLS manual con el modo Swarm, todo está integrado y los puertos para el modo Swarm son diferentes de los puertos para el socket API de Docker. No desea exponer la API de Docker en la red sin una buena razón (esta es una fuente común de piratería), y el modo Swarm no es una razón.

Por lo tanto, debes eliminar la -Hopción del dockerdcomando, junto con cualquier opción TLS allí. Luego ejecute docker swarm initel primer administrador que generará las credenciales TLS y proporcionará un token que incluye un hash de los certificados autofirmados. Luego, los otros administradores y trabajadores ejecutan a docker swarm joinpara generar los certificados de cliente, conectarse al administrador, validar el hash de los certificados del administrador del token y autenticarse ante el administrador con la parte secreta del token de unión.

Lo anterior cifrará el plano de gestión entre los gerentes y los trabajadores. Para cifrar los datos transmitidos en redes superpuestas entre trabajadores, debe habilitar IPSec en las redes superpuestas que cree:

docker network create --opt encrypted --driver overlay app-overlay-net

La documentación sobre esta característica se encuentra en:https://docs.docker.com/v17.09/engine/userguide/networking/overlay-security-model/

Respuesta2

Tenía razón en que todos los certificados tenían que ser certificados de cliente y de servidor para funcionar.

Luego encontré otros problemas, el principal es que las máquinas virtuales en el host que estoy usando prohíben el uso del puerto 4789 tal como lo usa VMWare. Este es el puerto de ruta de datos predeterminado utilizado para la red superpuesta.

Tuve que eliminar por completo todos los nodos y administradores del enjambre (eliminándolos efectivamente) y reiniciarlo usando el parámetro data-path-port:

docker swarm init --data-path-port=7777

(También especifiqué la dirección de publicidad como la IP para cada nodo, pero no creo que fuera necesario)

Por supuesto, todos mis secretos de Docker, la configuración de Docker y algunas de mis redes de Docker se perdieron en este proceso y tuvieron que volver a crearse.

Una vez que completé esto y cambié el firewall para permitir la comunicación UDP entre nodos usando el puerto de ruta de datos, las cosas volvieron a funcionar.

Como la red del enjambre está cifrada, creo que todo debería funcionar.

información relacionada