Fecha: 2019-09-23 Tiempo de lectura: 7 minutos Categoría: Sistemas Tags: linux / entorno / docker / swarm / gateway / cluster
Continuamos con esta serie de artículos con la finalidad de crear un entorno dockerizado completo. Vamos a ir creando la infraestructura necesaria para alojar nuestro cluster de docker swarm. Esto implica crear una red privada, un gateway para esconderla, y finalmente ataremos el cluster de docker swarm.
Como ya comenté, todo este depliegue de servidores se va a hacer mediante el uso de virtualización en mi propia máquina, y se va a usar VirtualBox. Dadas las limitaciones debido a los recursos disponibles, se va a hacer un entono más bien pequeño, que puede ser ampliado según se necesite:
Todos ellos van a tener conexión de red a la red interna, y el gateway también va a tener una conexión a la red externa, que en mi caso va a ser un NAT con reenvío de puertos.
TRUCO: Instalar los 7 servidores es un trabajo largo y pesado; es más inteligente instalar uno solo con SSH y clonarlo, adaptando las peculiaridades de cada uno.
Otro detalle es la elección del segmento de red privado: docker utiliza las
direcciones del tipo 172.x.x.x y la red de mi casa las del tipo 192.168.x.x;
esto nos deja el rango 10.x.x.x para que convivan las direcciones de la red local
con las direcciones de las redes overlay de docker. Así que tengamos claro:
10.0.0.x → Red local entre los servidores virtualizados10.1.x.x → Segmento de red que servirá para las redes overlay del swarmHay que hacer esta distinción porque el swarm utiliza la red 10.x.x.x por
defecto, y eso puede causar direcciones duplicadas entre ambas redes.
AVISO: Estas instrucciones están sacadas de este otro artículo. Por comodidad se exponen aquí también, a modo de referencia.
El gateway es una máquina visible desde el exterior de la red privada, y tiene por función la de permitir el acceso al exterior a los servidores de la red privada; adicionalmente, muchas funcionan como firewall e incluso ofrecen otros servicios a los servidores de la red privada.
Esto nos obliga a darle una interfaz de red por segmento de red en el que está. Como es el único visible desde el exterior, también conviene que dirija el tráfico entrante al servidor que corresponda, siendo necesario que bloquee el tráfico que no nos interesa, o que puede representar una amenaza.
gerard@gateway:~$ ip a | grep "inet "
inet 127.0.0.1/8 scope host lo
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
inet 10.0.0.1/24 brd 10.0.0.255 scope global enp0s8
gerard@gateway:~$
gerard@gateway:~$ cat /etc/network/interfaces
...
auto enp0s8
iface enp0s8 inet static
address 10.0.0.1
netmask 255.255.255.0
gerard@gateway:~$
Para permitir las comunicaciones y servir DHCP a los servidores de la red local, vamos instalar y configurar shorewall y dnsmasq, como ya hicimos en el artículo de referencia.
gerard@gateway:~$ sudo apt install shorewall dnsmasq
...
gerard@gateway:~$
Configuramos el DHCP e instruimos al gateway a utilizarse a sí mismo como servidor DNS; Ya de paso establecemos direcciones IP “fijas” para los nodos del swarm, que usarán DHCP.
gerard@gateway:~$ cat /etc/dnsmasq.d/custom
interface=enp0s8
dhcp-range=10.0.0.200,10.0.0.250,1h
dhcp-host=docker01,10.0.0.3,1h
dhcp-host=docker02,10.0.0.4,1h
dhcp-host=docker03,10.0.0.5,1h
dhcp-host=docker04,10.0.0.6,1h
dhcp-host=docker05,10.0.0.7,1h
dhcp-host=docker06,10.0.0.8,1h
gerard@gateway:~$
gerard@gateway:~$ grep gateway /etc/hosts
10.0.0.1 gateway
gerard@gateway:~$
gerard@gateway:~$ grep prepend /etc/dhcp/dhclient.conf
prepend domain-name-servers 127.0.0.1;
gerard@gateway:~$
Repitiendo el artículo de referencia, nos limitamos a declarar las zonas, interfaces, políticas y reglas específicas; no nos podemos olvidar tampoco del MASQUERADE ni del FORWARDING.
gerard@gateway:~$ cat /etc/shorewall/zones
fw firewall
net ipv4
loc ipv4
gerard@gateway:~$
gerard@gateway:~$ cat /etc/shorewall/interfaces
net enp0s3 detect dhcp,tcpflags,nosmurfs,routefilter,logmartians
loc enp0s8 detect dhcp,tcpflags,nosmurfs,routefilter,logmartians
gerard@gateway:~$
gerard@gateway:~$ cat /etc/shorewall/policy
net all DROP info
fw all ACCEPT
loc net ACCEPT
all all REJECT info
gerard@gateway:~$
gerard@gateway:~$ cat /etc/shorewall/rules
ACCEPT net fw tcp 22
DNS(ACCEPT) loc fw
gerard@gateway:~$
gerard@gateway:~$ grep FORWARDING /etc/shorewall/shorewall.conf
IP_FORWARDING=Yes
gerard@gateway:~$
gerard@gateway:~$ cat /etc/shorewall/snat
MASQUERADE 10.0.0.0/24 enp0s3
gerard@gateway:~$
Solo necesitamos habilitar el servicio shorewall y reiniciamos el servidor:
gerard@gateway:~$ sudo systemctl enable shorewall
Synchronizing state of shorewall.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable shorewall
gerard@gateway:~$
gerard@gateway:~$ sudo reboot
Connection to gateway closed by remote host.
Para crear el cluster de docker swarm vamos a necesitar una serie de servidores con docker instalado; basándonos en las decisiones del principio del artículo van a ser 3 managers y, de momento, 3 workers. Me limitaré a instalar uno, que iré clonando.
Partimos de una imagen básica con SSH, conectada a la red interna (la misma que la segunda pata del gateway); con una configuración de red básica por DHCP debería funcionar, ya que el gateway le suministrará una dirección IP.
Vamos a llamar a esta máquina docker, por poner algo; los clones van a cambiar ese nombre.
Es importante que no incluyan la relación entre el nombre del servidor y su dirección en
/etc/hosts; de esa resolución ya se encargará el servidor DNS del gateway.
A partir de aquí, solo nos queda instalar docker, y vamos a optar por la versión fácil:
gerard@docker:~$ wget -qO- http://get.docker.com/ | bash
...
gerard@docker:~$ sudo usermod -aG docker gerard
gerard@docker:~$
Y teniendo la imagen base, solo nos queda clonarla, creando las máquinas docker01,
docker02, docker03, docker04, docker05 y docker06. Como punto a aclarar,
se recomienda levantarlas una por una; los clones declaran el mismo hostname, como indica
el fichero /etc/hostname, y por lo tanto, dnsmasq se hace un lío con la asignación de IPs.
Así pues la clono, la levanto, modifico el fichero /etc/hostname y la reinicio; repito hasta
tener las 6 máquinas que van a formar el cluster de docker swarm. La idea es que tengamos:
Si lo hemos hecho bien, tendremos las máquinas registradas en dnsmasq y con las direcciones IP “fijas” que indicamos en la configuración de dnsmasq; algo así:
gerard@gateway:~$ cat /var/lib/misc/dnsmasq.leases | awk '{print $4": "$3}' | sort
docker01: 10.0.0.3
docker02: 10.0.0.4
docker03: 10.0.0.5
docker04: 10.0.0.6
docker05: 10.0.0.7
docker06: 10.0.0.8
gerard@gateway:~$
Para montar el cluster de docker swarm solo necesitamos lanzar en sus servidores algún comando:
docker swarm init en uno de los nodos, que se va a convertir en managerdocker swarm join en el resto de nodos
Así que vamos a docker01 y lanzamos:
gerard@docker01:~$ docker swarm init --default-addr-pool 10.1.0.0/16
Swarm initialized: current node (ai1kllx5blrdxqq0r8azm8lam) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3lbcngwk7frrtgz627p9r4xna5tbh5rre3tjlmggeb7ka5y9dk-aejxw8c8rospdwk3vpkbcwc29 10.0.0.3:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
gerard@docker01:~$
NOTA: Acordáos de cambiar el rango de red para no colisionar con las IPs de la red privada.
Sacamos los tokens para unirse al swarm, tanto para managers como para workers:
gerard@docker01:~$ docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3lbcngwk7frrtgz627p9r4xna5tbh5rre3tjlmggeb7ka5y9dk-2ufy46xqt0w6etkh6oxksc0br 10.0.0.3:2377
gerard@docker01:~$
gerard@docker01:~$ docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3lbcngwk7frrtgz627p9r4xna5tbh5rre3tjlmggeb7ka5y9dk-aejxw8c8rospdwk3vpkbcwc29 10.0.0.3:2377
gerard@docker01:~$
Solo tenemos que ejecutar el primero en docker02 y en docker03 (docker01 ya es parte del cluster y un manager), y el segundo en docker04, docker05 y docker06.
gerard@docker02:~$ docker swarm join --token SWMTKN-1-3lbcngwk7frrtgz627p9r4xna5tbh5rre3tjlmggeb7ka5y9dk-2ufy46xqt0w6etkh6oxksc0br 10.0.0.3:2377
This node joined a swarm as a manager.
gerard@docker02:~$
gerard@docker03:~$ docker swarm join --token SWMTKN-1-3lbcngwk7frrtgz627p9r4xna5tbh5rre3tjlmggeb7ka5y9dk-2ufy46xqt0w6etkh6oxksc0br 10.0.0.3:2377
This node joined a swarm as a manager.
gerard@docker03:~$
gerard@docker04:~$ docker swarm join --token SWMTKN-1-3lbcngwk7frrtgz627p9r4xna5tbh5rre3tjlmggeb7ka5y9dk-aejxw8c8rospdwk3vpkbcwc29 10.0.0.3:2377
This node joined a swarm as a worker.
gerard@docker04:~$
gerard@docker05:~$ docker swarm join --token SWMTKN-1-3lbcngwk7frrtgz627p9r4xna5tbh5rre3tjlmggeb7ka5y9dk-aejxw8c8rospdwk3vpkbcwc29 10.0.0.3:2377
This node joined a swarm as a worker.
gerard@docker05:~$
gerard@docker06:~$ docker swarm join --token SWMTKN-1-3lbcngwk7frrtgz627p9r4xna5tbh5rre3tjlmggeb7ka5y9dk-aejxw8c8rospdwk3vpkbcwc29 10.0.0.3:2377
This node joined a swarm as a worker.
gerard@docker06:~$
Si lo hemos hecho bien, podremos ver la lista de nodos del swarm desde cualquier manager, así como su estado:
gerard@docker01:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ai1kllx5blrdxqq0r8azm8lam * docker01 Ready Active Leader 19.03.1
io9916f6d5u9a4lq4gufwu58i docker02 Ready Active Reachable 19.03.1
i8gf5d8zmpikkwep0yu4ml105 docker03 Ready Active Reachable 19.03.1
6djbscl0ka50r3dx5uoynhxqf docker04 Ready Active 19.03.1
ek2thbbuapf13k5sgznpv0hhp docker05 Ready Active 19.03.1
xagr8a97pw3phevilhcnu6bdu docker06 Ready Active 19.03.1
gerard@docker01:~$
Y con esto ya tenemos la infraestructura lista.