Permet construir una malla de serveis fent servir sidecar proxies.
Introducció
Nomad és una aplicació distribuïda que gestiona contenidors, i pot garantit que si volem 5 apaches funcionant hi hauran 5 contenidors apache funcionant.
Altre cosa és on estaran aquests contenidors, per tant les IPs que haurem de fer servir, i en quin port estaran escoltant.
A més, les IPs no estan garantides; en qualsevol moment Nomad pot moure els contenidors de lloc.
Servei
Les arquitectures modernes es basen en la composició de serveis enlloc de grans aplicacions, serveis que cada cop tenen funcions més específiques i són més reduïts, que es poden replicar i modificar sense afectar al sistema.
Per poder-se comunicar, els serveis necessiten una manera de localitzar-se uns als altres, i Nomad no facilita gens la tasca.
La solució és fer servir noms que es resoldran a IPs, una solució que ja coneixes perquè has estudiat DNS.
En el nostre cas farem servir Consul, una pseudo base de dades distribuïda d’alta disponibilitat, que a més utilitza Envoy per crear una malla de serveis.
En el nostre desplegament, Nomad està integrat amb Consul.
Consul
Consul és una eina per localitzar i configurar i serveis. Les característiques principals de Consul inclouen la localització de serveis, verificar que estan actius, un sistema d’emmagatzematge clau-valor, i la capacitat de desplegar serveis en múltiples centres de dades de manera fiable.
Al integrar Nomad amb Consul, Nomad s’encarrega de manera automàtica de registrar els serveis (els contenidors) en el servei de localització que proporciona Consul, i de generar de manera dinàmica els fitxers de configuració i les variables d’entorn.
Consul Server
Per interactuar amb el servidor has de configurar el terminal.
$ export CONSUL_HTTP_ADDR="http://192.168.56.15:8500"
Si vols consulta els membres del cluster:
$ consul members
La resposta tindria que ser semblant a aquesta:
Node Address Status Type Build Protocol DC Partition Segment
box-1 192.168.56.101:8301 alive server 1.14.4 2 dc1 default <all>
box-5 192.168.56.105:8301 alive client 1.14.4 2 dc1 default <default>
box-7 192.168.56.107:8301 alive client 1.14.4 2 dc1 default <default>
box-8 192.168.56.108:8301 alive client 1.14.4 2 dc1 default <default>
També pots utilitzar la interfície gràfica: http://192.168.56.15:8500
Consul KV
Consul inclou un emmagatzematge clau/valor (KV) que pots fer servir per gestionar la configuració dels serveis.
Crea una clau db_port
amb valor 5432
:
$ consul kv put consul/configuration/db_port 5432
Success! Data written to: consul/configuration/db_port
A continuació, recupera el valor emmagatzemat:
$ consul kv get consul/configuration/db_port
5432
Consul DNS
Consul també proporcionar un servidor DNS que pots fer servir per resoldre les IPs dels teus serveis. Per defecte, el servi Consul DNS està configurat per escoltar al port 8600:
$ dig @127.0.0.1 -p 8600 consul.service.consul
Servei
Nomad està configurat perquè registri tots els serveis a Consul:
Per demostrar com funciona crearem un server nginx:
$ nano nginx.nomad
Perquè nomad registri el servei has de configurar el fitxer nomad, i afegir un block service tal com s’explica a Service Block - Job Specification
job "nginx" {
datacenters = ["dc1"]
group "nginx" {
count = 1
network {
port "http" {
to = 80
}
}
task "nginx" {
driver = "docker"
config {
image = "nginx:1.22.1"
ports = ["http"]
auth_soft_fail = true
}
service {
name = "nginx"
port = "http"
provider = "consul"
}
resources {
cpu = 500
memory = 256
}
}
}
}
Registra la tasca a Nomad:
$ nomad job run nginx.nomad
Nomad crea un contenidor nginx i registra a Consul on està localitzat aquest servei:
Localitzar serveis mitjançant DNS
Una de les maneres de localitzar serveis a Consul és mitjançant una consulta DNS, enlloc de fer servir la API HTTP (que és el sistema que farien servir les aplicacions).
Per exemple, per saber on està el servei nginx, per tant, on estan alguns dels contenidors, pots fer servir el servei DNS de consul:
$ dig @127.0.0.1 -p 8600 nginx.service.consul ANY
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;nginx.service.consul. IN A
;; ANSWER SECTION:
nginx.service.consul. 0 IN A 192.168.56.15
Quan Consul rep aquesta consulta, busca tots els serveis registrats que proporcionin el servei nginx, i que estan actius.
Encara que pots conèixer la IP, una consulta DNS no et permet conèixer en quin port està escoltant el servei.
Per tant, una consulta DNS només té utilitat per aquelles consultes que es fan a serveis que estan a un port determinat, per exemple HTTP és el port 80 i HTTPS és el port 443.
Malla de serveis (pendent)
Fer servir DNS per localitzar serveis no és una opció, com tampoc és viable que les aplicacions facin servir l’API HTTP per localitzar serveis.
Per això fem servir un desplegament "sidecar", i configurem Consul perquè faci servir Envoy com un Connect Proxy.
Envoy s’encarrega de gestionar tota la complexitat de localitzar serveis, la seva disponibilitat, etc. i les aplicacions o contenidors que fan servir aquests serveis no s’han d’ocupar d’aquests problemes.
D’aquesta manera aconseguim l¡alta disponibilitat.
Continuarà
Pots crear un job d'exemple que fa servir Consul connect (i Envoy).
nomad job init -short -connect count.nomad
nomad job run count.nomad
Pendent: setup the plugins to make bridge networking work
Avaluació
01
1.- Desplega un servei nginx com el que està a la documentació.
2.- Para la màquina virtual on està el contenidor on està nginx, i verifica amb la comanda dig
que el servei s’ha desplegat en un altre node.
Tarda una estona, no és immediat.
$ dig @127.0.0.1 -p 8600 nginx.service.consul ANY
;; ANSWER SECTION:
nginx.service.consul. 0 IN A 192.168.56.107
3.- Modifica el fitxer nomad perquè enlloc d’un servei nginx hi hagin 3, i registra el job actualitzat a Nomad.
Localitza on estan aquest serveis amb la comanda dig
.
Verifica amb la interfície gràfica de consul de que aquesta informació és correcta.
job "nginx" {
datacenters = ["dc1"]
group "nginx" {
count = 3
network {
port "http" {
to = 80
}
}
$ nomad job run nginx.nomad
$ dig @127.0.0.1 -p 8600 nginx.service.consul ANY
;; ANSWER SECTION:
nginx.service.consul. 0 IN A 192.168.56.107
nginx.service.consul. 0 IN A 192.168.56.108
02
1.- Modifica la configuració de network de nginx.nomad perquè es faci servir un port estàtic, el 80.
job "nginx" {
datacenters = ["dc1"]
group "nginx" {
count = 3
network {
port "http" {
static = 80
to = 80
}
}
Registra el job actualitzat i verifica amb Consul que tots els serveis nginx estan al port 80.
2.- Fes una consulta DNS i obre el navegador a la primera IP que et retorni
$ dig @127.0.0.1 -p 8600 nginx.service.consul ANY
;; ANSWER SECTION:
nginx.service.consul. 0 IN A 192.168.56.108
nginx.service.consul. 0 IN A 192.168.56.107
nginx.service.consul. 0 IN A 192.168.56.106
3.- Para dos màquines virtuals i verifica que només hi ha un contenidor actiu.
El motiu és que el job està configurat amb un port estàtic, i el port només el pot fer servir un contenidor.
03
1.- Elimina el job nginx i registra un job que desplegui només un contenidor apache i es registri a consul.
Fes servir d’exemple el job nginx.
$ nomad job stop -purge nginx
$ nano apache.nomad
job "apache" {
datacenters = ["dc1"]
group "apache" {
count = 1
network {
port "http" {
to = 80
}
}
task "apache" {
driver = "docker"
config {
image = "httpd:2.4.55"
ports = ["http"]
auth_soft_fail = true
}
service {
name = "apache"
port = "http"
provider = "consul"
}
resources {
cpu = 500
memory = 256
}
}
}
}
$ nomad job run apache.nomad
2.- Com que les respostes DNS tenen la limitació de que no ens diuen quin port fa servir el servei, farem servir l’endpoint /agent/service
de l’agent local de Consul per obtenir la resposta.
Cada màquina virtual té un agent Consul executant-se, i aquest agent té una copia sincronitzada de tots els serveis del cluster, i pot donar una resposta immediata (no hi ha latència, ni problemes de xarxa).
Això és alta disponibilitat.
Consulta a totes les màquines client els serveis que tenen registrats, fins que trobis on està apache amb la petició de llistar serveis: Service - Agent - HTTP API
Per exemple:
$ curl http://192.168.56.101:8500/v1/agent/services | json_pp
$ curl http://192.168.56.105:8500/v1/agent/services | json_pp
...
$ curl http://192.168.56.108:8500/v1/agent/services | json_pp
Només afegeix captura de la consulta que l’ha trobat.
3.- Per saber tots els serveis que estan registrats en el nostre centre de dades dc1:, pots fer una consulta HTTP a l’API de Consul de qualsevol agent:
$ curl http://192.168.56.106:8500/v1/catalog/services
{"apache":[],"consul":[],"nomad":["http","serf","rpc"],"nomad-client":["http"]}
$ curl http://192.168.56.107:8500/v1/catalog/services
...
Pots consultar l'API a Catalog - HTTP API
4.- Però si tens un cluster de 100 màquines això és molta feina.
Per saber on estan els serveis apache pots consultar l'endpoint /catalog/service
:
$ curl http://192.168.56.106:8500/v1/catalog/service/apache | json_pp