El primer servicio en Nomad I se lanz贸 en septiembre de 2016. En este momento lo uso como programador y apoyo como administrador de dos clusters Nomad: un "hogar" para mis proyectos personales (6 m谩quinas micro-virtuales en Hetzner Cloud y ArubaCloud en 5 centros de datos diferentes en Europa) y el segundo en funcionamiento (alrededor de 40 servidores privados virtuales y f铆sicos en dos centros de datos).
En el pasado, se ha acumulado bastante experiencia con el entorno de Nomad, en el art铆culo describir茅 los problemas encontrados por Nomad y c贸mo lidiar con ellos.

Yamal Nomad realiza la instancia de entrega continua de su software 漏 National Geographic Russia
1. El n煤mero de nodos de servidor por centro de datos
Soluci贸n: un nodo de servidor es suficiente para un centro de datos.
La documentaci贸n no indica expl铆citamente cu谩ntos nodos de servidor se requieren en un centro de datos. Solo se indica que se necesitan 3-5 nodos por regi贸n, lo cual es l贸gico para el consenso del protocolo de balsa.

Al principio, plane茅 2-3 nodos de servidor en cada centro de datos para proporcionar redundancia.
Al usarlo result贸:
- Esto simplemente no es necesario, ya que en el caso de una falla del nodo en el centro de datos, el papel del nodo del servidor para los agentes en este centro de datos ser谩 desempe帽ado por otros nodos del servidor en la regi贸n.
- Resulta a煤n peor si el problema 8 no se resuelve. Cuando el asistente es reelegido, pueden producirse incoherencias y Nomad reiniciar谩 parte de los servicios.
2. Recursos del servidor para el nodo del servidor
Soluci贸n: una peque帽a m谩quina virtual es suficiente para el nodo del servidor. En el mismo servidor, est谩 permitido ejecutar otros servicios que no requieren muchos recursos.
El consumo de memoria del demonio Nomad depende del n煤mero de tareas en ejecuci贸n. Consumo de CPU: basado en la cantidad de tareas y la cantidad de servidores / agentes en la regi贸n (no lineal).
En nuestro caso: para 300 tareas en ejecuci贸n, el consumo de memoria es de aproximadamente 500 MB para el nodo maestro actual.
En un cl煤ster de trabajo, una m谩quina virtual para un nodo de servidor: 4 CPU, 6 GB de RAM.
Lanzado adicionalmente: Consul, Etcd, Vault.
3. Consenso sobre la falta de centros de datos.
Soluci贸n: creamos tres centros de datos virtuales y tres nodos de servidor para dos centros de datos f铆sicos.
El trabajo de Nomad dentro de la regi贸n se basa en el protocolo de la balsa. Para un funcionamiento correcto, necesita al menos 3 nodos de servidor ubicados en diferentes centros de datos. Esto permitir谩 un funcionamiento correcto con una p茅rdida completa de conectividad de red con uno de los centros de datos.
Pero solo tenemos dos centros de datos. Nos comprometemos: seleccionamos un centro de datos, en el que confiamos m谩s, y hacemos un nodo de servidor adicional en 茅l. Hacemos esto mediante la introducci贸n de un centro de datos virtual adicional, que se ubicar谩 f铆sicamente en el mismo centro de datos (consulte el subp谩rrafo 2 del problema 1).
Soluci贸n alternativa: separamos los centros de datos en regiones separadas.
Como resultado, los centros de datos funcionan de manera independiente y solo se necesita consenso dentro de un centro de datos. Dentro de un centro de datos, en este caso es mejor hacer 3 nodos de servidor implementando tres centros de datos virtuales en uno f铆sico.
Esta opci贸n es menos conveniente para la distribuci贸n de tareas, pero ofrece una garant铆a del 100% de la independencia de los servicios en caso de problemas de red entre centros de datos.
4. "Servidor" y "agente" en el mismo servidor
Soluci贸n: v谩lida si tiene un n煤mero limitado de servidores.
La documentaci贸n n贸mada dice que hacer esto no es deseable. Pero si no tiene la oportunidad de asignar m谩quinas virtuales separadas para los nodos del servidor, puede colocar el servidor y los nodos de agente en el mismo servidor.
Ejecutar simult谩neamente significa iniciar el daemon Nomad tanto en modo cliente como en modo servidor.
驴Qu茅 amenaza esto? Con una gran carga en la CPU de este servidor, el nodo del servidor Nomad funcionar谩 de manera inestable, se puede perder el consenso y el latido, y los servicios se recargar谩n.
Para evitar esto, aumentamos los l铆mites de la descripci贸n del problema No. 8.
5. Implementaci贸n de espacios de nombres
Soluci贸n: quiz谩s a trav茅s de la organizaci贸n de un centro de datos virtual.
A veces necesita ejecutar parte de los servicios en servidores separados.
La soluci贸n es la primera, simple, pero m谩s exigente en recursos. Dividimos todos los servicios en grupos de acuerdo con su prop贸sito: frontend, back-end, ... Agrega meta atributos a los servidores, prescribe los atributos para ejecutar para todos los servicios.
La segunda soluci贸n es simple. Agregamos nuevos servidores, prescribimos meta atributos para ellos, prescribimos estos atributos de lanzamiento a los servicios necesarios, y todos los dem谩s servicios prescriben la prohibici贸n de iniciar servidores con este atributo.
La tercera soluci贸n es complicada. Creamos un centro de datos virtual: inicie Consul para un nuevo centro de datos, inicie el nodo del servidor Nomad para este centro de datos, sin olvidar el n煤mero de nodos del servidor para esta regi贸n. Ahora puede ejecutar servicios individuales en este centro de datos virtual dedicado.
6. Integraci贸n con Vault
Soluci贸n: Evite las dependencias circulares de Nomad <-> Vault.
La B贸veda lanzada no deber铆a tener ninguna dependencia de Nomad. La direcci贸n de la B贸veda registrada en Nomad preferiblemente debe apuntar directamente a la B贸veda, sin capas de equilibradores (pero v谩lidos). La reserva de b贸veda en este caso se puede hacer a trav茅s de DNS - Consul DNS o externa.
Si los datos de Vault se escriben en los archivos de configuraci贸n de Nomad, Nomad intenta acceder a Vault al inicio. Si el acceso no es exitoso, Nomad se niega a comenzar.
Comet铆 un error con una dependencia c铆clica hace mucho tiempo, esto una vez destruy贸 brevemente casi por completo el grupo Nomad. Vault se lanz贸 correctamente, independientemente de Nomad, pero Nomad mir贸 la direcci贸n de Vault a trav茅s de los equilibradores que se ejecutaban en Nomad. La reconfiguraci贸n y el reinicio de los nodos del servidor Nomad provocaron un reinicio de los servicios del equilibrador, lo que provoc贸 un error al iniciar los nodos del servidor.
7. Lanzamiento de importantes servicios estatales.
Soluci贸n: v谩lida, pero yo no.
驴Es posible ejecutar PostgreSQL, ClickHouse, Redis Cluster, RabbitMQ, MongoDB a trav茅s de Nomad?
Imagine que tiene un conjunto de servicios importantes, cuyo trabajo est谩 vinculado a la mayor铆a de los otros servicios. Por ejemplo, una base de datos en PostgreSQL / ClickHouse. O almacenamiento general a corto plazo en Redis Cluster / MongoDB. O un bus de datos en Redis Cluster / RabbitMQ.
Todos estos servicios de alguna forma implementan un esquema tolerante a fallas: Stolon / Patroni para PostgreSQL, su propia implementaci贸n de balsa en Redis Cluster, su propia implementaci贸n de cl煤ster en RabbitMQ, MongoDB, ClickHouse.
S铆, todos estos servicios se pueden iniciar a trav茅s de Nomad con referencia a servidores espec铆ficos, pero 驴por qu茅?
Adem谩s: facilidad de lanzamiento, un formato de script 煤nico, como otros servicios. No hay que preocuparse por los guiones ansibles / cualquier otra cosa.
Menos es un punto adicional de falla, que no ofrece ninguna ventaja. Personalmente, elimin茅 por completo el cl煤ster Nomad dos veces por varias razones: una vez "en casa", una vez trabajando. Esto fue en las primeras etapas de la presentaci贸n de Nomad y debido a la negligencia.
Adem谩s, Nomad comienza a comportarse mal y reinicia los servicios debido al problema n煤mero 8. Pero incluso si ese problema se resuelve, el peligro permanece.
8. La estabilizaci贸n del trabajo y el servicio se reinicia en una red inestable.
Soluci贸n: use las opciones de ajuste de latidos.
De forma predeterminada, Nomad est谩 configurado para que cualquier problema de red a corto plazo o carga de CPU provoque la p茅rdida de consenso y la reelecci贸n del asistente o marque el nodo del agente como inaccesible. Y esto lleva a reinicios espont谩neos de servicios y su transferencia a otros nodos.
Estad铆sticas del cl煤ster "hogar" antes de solucionar el problema: la vida 煤til m谩xima del contenedor antes de reiniciar es de aproximadamente 10 d铆as. Aqu铆, todav铆a tiene la carga de ejecutar el agente y el servidor en el mismo servidor y colocarlo en 5 centros de datos diferentes en Europa, lo que implica una gran carga en la CPU y una red menos estable.
Estad铆sticas del cl煤ster de trabajo antes de solucionar el problema: la vida 煤til m谩xima del contenedor antes de reiniciar es m谩s de 2 meses. Aqu铆 todo es relativamente bueno debido a los servidores separados para los nodos del servidor Nomad y la excelente red entre los centros de datos.
Valores por defecto
heartbeat_grace = "10s" min_heartbeat_ttl = "10s" max_heartbeats_per_second = 50.0
A juzgar por el c贸digo: en esta configuraci贸n, los latidos se hacen cada 10 segundos. Con la p茅rdida de dos latidos, comienza la reelecci贸n del maestro o la transferencia de servicios desde el nodo del agente. Configuraciones controvertidas, en mi opini贸n. Los editamos dependiendo de la aplicaci贸n.
Si tiene todos los servicios ejecut谩ndose en varias instancias y son distribuidos por centros de datos, lo m谩s probable es que no le importe un largo per铆odo para determinar la inaccesibilidad del servidor (aproximadamente 5 minutos, en el ejemplo a continuaci贸n): hacemos menos frecuente el intervalo de latidos y un per铆odo m谩s largo para determinar la inaccesibilidad. Este es un ejemplo de c贸mo configurar mi cl煤ster de inicio:
heartbeat_grace = "300s" min_heartbeat_ttl = "30s" max_heartbeats_per_second = 10.0
Si tiene una buena conectividad de red, servidores separados para los nodos del servidor, y el per铆odo para determinar la inaccesibilidad del servidor es importante (hay alg煤n servicio ejecut谩ndose en una instancia y es importante transferirlo r谩pidamente), luego aumente el per铆odo para determinar la inaccesibilidad (heartbeat_grace). Opcionalmente, puede hacer m谩s latidos (disminuyendo min_heartbeat_ttl); esto aumentar谩 ligeramente la carga en la CPU. Ejemplo de configuraci贸n de cl煤ster de trabajo:
heartbeat_grace = "60s" min_heartbeat_ttl = "10s" max_heartbeats_per_second = 50.0
Esta configuraci贸n soluciona completamente el problema.
9. Inicio de tareas peri贸dicas.
Soluci贸n: Se pueden utilizar los servicios peri贸dicos n贸madas, pero cron es m谩s conveniente para el soporte.
Nomad tiene la capacidad de lanzar peri贸dicamente el servicio.
La 煤nica ventaja es la simplicidad de esta configuraci贸n.
El primer inconveniente es que si el servicio se inicia con frecuencia, ensuciar谩 la lista de tareas. Por ejemplo, al inicio cada 5 minutos, se agregar谩n 12 tareas adicionales a la lista cada hora, hasta que se active el GC Nomad, lo que eliminar谩 las tareas anteriores.
El segundo inconveniente: no est谩 claro c贸mo configurar adecuadamente la supervisi贸n de dicho servicio. 驴C贸mo entender que un servicio comienza, cumple y hace su trabajo hasta el final?
Como resultado, para m铆, llegu茅 a la implementaci贸n "cron" de tareas peri贸dicas:
- Puede ser un cron regular en un contenedor que se ejecuta constantemente. Cron ejecuta peri贸dicamente un cierto script. Se agrega f谩cilmente una comprobaci贸n de estado del script a dicho contenedor, que verifica cualquier indicador que cree un script en ejecuci贸n.
- Puede ser un contenedor en ejecuci贸n constante, con un servicio en ejecuci贸n constante. Ya se ha implementado un lanzamiento peri贸dico dentro del servicio. Se puede agregar f谩cilmente un script-healthcheck similar o http-healthcheck a dicho servicio, que verifica el estado inmediatamente por su "interior".
En el momento en que escribo la mayor parte del tiempo en Go, respectivamente, prefiero la segunda opci贸n con http healthcheck: on Go y el lanzamiento peri贸dico, y http healthcheck'i se agregan con algunas l铆neas de c贸digo.
10. Prestaci贸n de servicios redundantes.
Soluci贸n: no existe una soluci贸n simple. Hay dos opciones m谩s dif铆ciles.
El esquema de aprovisionamiento proporcionado por los desarrolladores de Nomad es para admitir la cantidad de servicios en ejecuci贸n. Dices que el n贸mada "lanzame 5 instancias del servicio" y 茅l las inicia en alg煤n lugar all铆. No hay control sobre la distribuci贸n. Las instancias pueden ejecutarse en el mismo servidor.
Si el servidor falla, las instancias se transfieren a otros servidores. Mientras se transfieren las instancias, el servicio no funciona. Esta es una opci贸n de provisi贸n de reserva incorrecta.
Lo hacemos bien:
- Distribuimos instancias en servidores a trav茅s de distinct_hosts .
- Distribuimos instancias en centros de datos. Desafortunadamente, solo al crear una copia del script del formulario service1, service2 con los mismos contenidos, diferentes nombres y una indicaci贸n del lanzamiento en diferentes centros de datos.
En Nomad 0.9, aparecer谩 una funcionalidad que solucionar谩 este problema: ser谩 posible distribuir servicios en una proporci贸n porcentual entre servidores y centros de datos.
11. Web UI Nomad
Soluci贸n: la interfaz de usuario integrada es terrible, el hashi-ui es hermoso.
El cliente de la consola realiza la mayor parte de la funcionalidad requerida, pero a veces desea ver los gr谩ficos, presionar los botones ...
Nomad tiene una interfaz de usuario incorporada. No es muy conveniente (incluso peor que la consola).

La 煤nica alternativa que conozco es hashi-ui .

De hecho, ahora personalmente necesito el cliente de consola solo para "nomad run". E incluso esto planea transferir a CI.
12. Soporte para sobresuscripciones de memoria
Soluci贸n: no.
En la versi贸n actual de Nomad, debe especificar un l铆mite de memoria estricto para el servicio. Si se excede el l铆mite, el servicio ser谩 asesinado por OOM Killer.
La suscripci贸n excesiva es cuando los l铆mites para un servicio se pueden especificar "desde y hacia". Algunos servicios requieren m谩s memoria al inicio que durante el funcionamiento normal. Algunos servicios pueden consumir m谩s memoria de lo habitual por un corto tiempo.
La elecci贸n de una restricci贸n estricta o suave es un tema de discusi贸n, pero, por ejemplo, Kubernetes permite al programador tomar una decisi贸n. Desafortunadamente, en las versiones actuales de Nomad no existe tal posibilidad. Admito que aparecer谩 en futuras versiones.
13. Limpieza del servidor de los servicios Nomad
Soluci贸n:
sudo systemctl stop nomad mount | fgrep alloc | awk '{print $3}' | xargs -I QQ sudo umount QQ sudo rm -rf /var/lib/nomad sudo docker ps | grep -v '(-1|-2|...)' | fgrep -v IMAGE | awk '{print $1}' | xargs -I QQ sudo docker stop QQ sudo systemctl start nomad
A veces "algo sale mal". En el servidor, mata el nodo del agente y se niega a iniciarse. O el nodo del agente deja de responder. O el nodo del agente "pierde" los servicios en este servidor.
Esto a veces sucedi贸 con versiones anteriores de Nomad, ahora esto no sucede, o muy raramente.
驴Qu茅 es lo m谩s f谩cil en este caso, dado que el servidor de drenaje no producir谩 el resultado deseado? Limpiamos el servidor manualmente:
- Det茅n al agente n贸mada.
- Desmonta en la montura que crea.
- Eliminar todos los datos del agente.
- Eliminamos todos los contenedores filtrando los contenedores de servicio (si los hay).
- Comenzamos el agente.
14. 驴Cu谩l es la mejor manera de desplegar Nomad?
Soluci贸n: por supuesto, a trav茅s del C贸nsul.
El c贸nsul en este caso no es en absoluto una capa adicional, sino un servicio que se adapta org谩nicamente a la infraestructura, lo que brinda m谩s ventajas que desventajas: DNS, almacenamiento KV, b煤squeda de servicios, monitoreo de la disponibilidad del servicio, la capacidad de intercambiar informaci贸n de manera segura.
Adem谩s, se desarrolla tan f谩cilmente como el propio Nomad.
15. 驴Qu茅 es mejor: n贸mada o kubernetes?
Soluci贸n: depende de ...
Anteriormente, a veces ten铆a la idea de comenzar una migraci贸n a Kubernetes; estaba tan molesto por el reinicio peri贸dico y espont谩neo de los servicios (vea el problema n煤mero 8). Pero despu茅s de una soluci贸n completa al problema, puedo decir: Nomad me conviene en este momento.
Por otro lado: Kubernetes tambi茅n tiene una recarga de servicios semi-espont谩nea, cuando el planificador de Kubernetes redistribuye instancias dependiendo de la carga. Esto no es muy bueno, pero es muy probable que est茅 configurado.
Ventajas de Nomad: la infraestructura es muy f谩cil de implementar, scripts simples, buena documentaci贸n, soporte integrado para Consul / Vault, que a su vez brinda: una soluci贸n simple al problema del almacenamiento de contrase帽as, DNS incorporado, helchecks f谩ciles de configurar.
Ventajas de Kubernetes: ahora es un "est谩ndar de facto". Buena documentaci贸n, muchas soluciones listas para usar, con una buena descripci贸n y estandarizaci贸n del lanzamiento.
Desafortunadamente, no tengo la misma gran experiencia en Kubernetes para responder inequ铆vocamente a la pregunta: qu茅 usar para el nuevo cl煤ster. Depende de las necesidades planificadas.
Si tiene planeados muchos espacios de nombres (problema n煤mero 5) o sus servicios espec铆ficos consumen mucha memoria al principio, luego lib茅relos (problema n煤mero 12), definitivamente Kubernetes, porque Estos dos problemas en Nomad no est谩n completamente resueltos o son inconvenientes.