Nota:
La compatibilidad con nodos adicionales en una configuración de alta disponibilidad está actualmente en versión preliminar pública y está sujeta a cambios.
Para GitHub Enterprise Server los clientes que buscan escalar horizontalmente, la migración a un clúster y el funcionamiento de un clúster es una opción, pero requiere mucho recursos y consume mucho tiempo. Como alternativa, se recomienda agregar nodos a una configuración de alta disponibilidad.
Los términos "nodo adicional" y "nodo sin estado" se usan indistintamente en este artículo. Los nodos sin estado solo pueden agregarse a las implementaciones de alta disponibilidad que contienen al menos una réplica.
Nodos adicionales
De todos los servicios que se ejecutan en un GitHub Enterprise Server dispositivo, Unicorn suele ser el más intensivo de CPU y memoria, seguido de Aqueduct, Git y MySQL. Dado que Unicorn y Aqueduct son servicios sin estado, son adecuados para el escalado horizontal y se pueden ejecutar en un conjunto independiente de nodos. Los servicios restantes pueden seguir funcionando con una sola instancia por centro de datos.
Los nodos adicionales permiten escalar las cargas de trabajo web y de trabajo horizontalmente. También pueden descargar Unicorn y Aqueduct desde el nodo principal, liberando considerables recursos de proceso y memoria para los servicios con estado restantes. Si experimenta interrupciones relacionadas con el rendimiento debido al uso elevado de CPU por instancias de Unicorn, se recomienda agregar nodos adicionales. No hay restricciones significativas en el número de estos nodos que puede agregar dentro de un centro de datos.
Criterios
Si experimenta un rendimiento degradado debido a un nodo principal sobrecargado en una configuración de alta disponibilidad, debe considerar la posibilidad de agregar nodos adicionales al entorno de alta disponibilidad. Al escalar los roles web y de trabajo horizontalmente más allá del nodo principal, estos nodos adicionales pueden ayudar a reducir la carga en el host principal.
Por ejemplo, si observa trabajos pendientes en las colas de Unicorn o Aqueduct, o experimenta otros tipos de contención de recursos, debería considerar este enfoque. Incluso si no hay cola visible, quedarse sin CPU en el nodo principal es otra señal clara. En estos casos, puede agregar nodos adicionales y reducir el número de trabajos por nodo, por lo que el nodo principal controla menos la carga de trabajo general.
Adición de un nodo
Cada nodo que agregue a una implementación de alta disponibilidad es una máquina virtual que ejecuta el GitHub Enterprise Server software. Debe ejecutar el mismo software que el principal. Por lo general, un nodo sin estado no necesita coincidir con las especificaciones de memoria, CPU o almacenamiento principal. Sin embargo, tanto el nodo sin estado como la instancia principal requieren conectividad de submilisegundos. Los requisitos de conectividad para las réplicas permanecen sin cambios.
Para agregar nodos al centro de datos principal en una configuración de alta disponibilidad, use el ghe-add-node comando . El ghe-add-node comando configura el dispositivo actual como un nodo dentro de la implementación de alta disponibilidad y está pensado para descargar tareas intensivas de CPU desde el nodo de datos principal, lo que permite el escalado horizontal. Estos nodos están diseñados para controlar las cargas de trabajo y web, lo que permite una distribución y administración de cargas de trabajo más eficaces.
Este comando toma la forma:
/usr/local/share/enterprise/ghe-add-node PRIMARY_IP [--hostname HOSTNAME]
/usr/local/share/enterprise/ghe-add-node PRIMARY_IP [--hostname HOSTNAME]
PRIMARY_IP: la dirección IP del nodo principal.HOSTNAME(opcional): nombre de host deseado para el host agregado.
Por ejemplo, para agregar un nodo con el nombre de host ghes-node-1 a la instancia principal de alta disponibilidad con dirección IP 192.168.1.1 en el centro de datos principal de alta disponibilidad, ejecutaría el siguiente comando:
/usr/local/share/enterprise/ghe-add-node 192.168.1.1 --hostname ghes-node-1
/usr/local/share/enterprise/ghe-add-node 192.168.1.1 --hostname ghes-node-1
A continuación, en el nodo principal, debe ejecutar los siguientes comandos:
ghe-config-apply ghe-cluster-balance rebalance --yes
ghe-config-apply
ghe-cluster-balance rebalance --yes
El ghe-config-apply comando es un requisito para agregar nodos sin estado.
Se recomienda una ventana de mantenimiento para agregar nodos sin estado.
Eliminación de un nodo adicional
Antes de retirar un nodo adicional, instale en cada nodo del despliegue de alta disponibilidad el mismo parche más reciente correspondiente a su versión de funcionalidad y programe una ventana de mantenimiento. Espere a que finalice cualquier actualización o ejecución de configuración antes de iniciar la eliminación.
-
En el nodo principal de HA, compruebe el estado de cada nodo de la implementación de HA.
Shell ghe-cluster-nodes ghe-cluster-nodes --offline nomad node status ghe-cluster-status --extended --verbose
ghe-cluster-nodes ghe-cluster-nodes --offline nomad node status ghe-cluster-status --extended --verboseConfirme que ambos
ghe-cluster-nodescomandos enumeran los mismos nombres de host e incluyen el nombre de host del nodo que planea quitar. Confirme que cada nodo tiene el estado de Nomadreadyy queconnect-sshyenterprise-versionsonokpara cada nodo. Confirme que los servicios con estado principales y las réplicas, si las hay, están en buen estado. Si no queda ninguna réplica, es de esperar una advertencia de que no se encontró ninguna réplica de MySQL. Los errores limitados a cargas de trabajo web, trabajo o memcache en el destino no bloquean la eliminación. Si falla cualquier otra comprobación a nivel de nodo o del servicio con estado, póngase en contacto con Soporte de GitHub antes de retirarlo. -
En el nodo principal de alta disponibilidad, quite el nodo adicional. Reemplace por
HOSTNAMEel nombre de host del nodo adicional.Shell ghe-remove-node --verbose HOSTNAME
ghe-remove-node --verbose HOSTNAMESi queda otro nodo no principal, el comando vacía el nodo de destino, lo elimina de la configuración de alta disponibilidad y ejecuta
ghe-config-apply. Si no permanece ningún nodo no principal, el comando quita los metadatos del clúster y convierte la principal en una instancia independiente sin ejecutarghe-config-apply. No ejecutarghe-config-applypor separado en ninguno de los dos casos. -
Compruebe la eliminación.
Si queda otro nodo no principal, ejecute los siguientes comandos en el nodo principal de alta disponibilidad. Compruebe que el nombre de host no esté presente y que la configuración de HA esté en buen estado.
Shell ghe-cluster-nodes --offline ghe-cluster-status --extended --verbose
ghe-cluster-nodes --offline ghe-cluster-status --extended --verboseSi no permanece ningún nodo no principal, no ejecute los comandos de solo clúster. Confirme que la salida de eliminación contiene
Cluster artifacts removed; now standalone.y confirme que el servidor principal atiende el tráfico de usuario y procesa las cargas de trabajo y web.
Si un nodo adicional está sin conexión, es inaccesible o tiene una versión diferente, o si falla ghe-remove-node o una comprobación de verificación, póngase en contacto con Soporte de GitHub. No edite cluster.conf manualmente.
Volver a aprovisionar un nodo que anteriormente alojaba GitHub Enterprise Server
Puede usar un nodo que se hospedó y ejecutó GitHub Enterprise Server previamente como un nodo sin estado. Para ello, el nodo debe actualizarse a la versión 3.18 o superior y todos los nodos de la implementación deben ejecutar la misma versión. En ese nodo, compruebe si /data/user/common/cluster.conf ya existe. Si lo hace, deberá realizar la limpieza antes de ejecutar el comando ghe-add-node en el nodo sin estado.
Por ejemplo:
sudo rm -f /etc/github/cluster /data/user/common/cluster.conf sudo timeout -k4 10 systemctl stop wireguard 2>/dev/null || sudo ip link delete tun0 || true
sudo rm -f /etc/github/cluster /data/user/common/cluster.conf
sudo timeout -k4 10 systemctl stop wireguard 2>/dev/null || sudo ip link delete tun0 || true
Límites y comportamiento
No hay ningún límite teórico para el número de nodos que se pueden agregar. Sin embargo, en la práctica, agregar demasiados nodos puede causar problemas y afectar a la estabilidad o el rendimiento. En este momento, los nodos recién agregados procesarán un conjunto predefinido de tareas. No puede elegir qué tipo de tareas se descargan. El nodo adicional puede procesar todas las API.
Si una operación de Git está en la ruta, hay lógica para procesar las operaciones de Git solo en el nodo principal. El nodo adicional no controla las operaciones de Git. Por ejemplo, la eliminación de ramas es una operación de Git y no la controlará el nodo sin estado.
Los nodos sin estado no ejecutan cargas de trabajo de Elasticsearch, pero ejecutan kafka-lite.
Requisitos de sistema y redes
Por lo general, los nodos sin estado no necesitan coincidir con las especificaciones de memoria, CPU y almacenamiento del nodo principal. Los requisitos del sistema deben tener en cuenta el consumo de recursos existente de servicios web y de trabajo en el nodo principal y si el nodo principal descargará completamente esas cargas de trabajo en el nuevo nodo.
El nodo sin estado y la instancia principal requieren conectividad de submilisegundos. Por lo general, todos los nodos del centro de datos principal requieren conectividad de submilisegundos. Los requisitos de conectividad para las réplicas permanecen sin cambios.
Enrutamiento del tráfico y control de solicitudes
Principal enruta el tráfico a los nodos adicionales. En el caso de varios nodos sin estado, el primario envía nuevas conexiones al servidor con menos conexiones activas en ese momento.
Actualización de una implementación de alta disponibilidad con nodos adicionales
A continuación se muestra una secuencia de actualización de ejemplo:
- Inicie la ventana de mantenimiento.
- Detenga las réplicas.
- Actualice los nodos sin estado en paralelo.
- Actualice el nodo principal.
- Actualice las réplicas. Se pueden actualizar en paralelo o secuencialmente en función de las preferencias de recuperación ante desastres.
- Iniciar réplicas.
- Quite la ventana de mantenimiento.
Los nodos adicionales no deben provocar tiempo de inactividad adicional durante las actualizaciones.
Comportamiento de conmutación por error y recuperación ante desastres
No es necesario "anular" nodos adicionales, ya que no contienen ningún dato.
Durante la conmutación por error, el nodo de réplica se quita de la implementación original y se convierte en un nodo independiente. Los nodos sin estado deben volver a vincularse a la réplica promovida, tal como se vuelven a adjuntar réplicas adicionales tras una conmutación por error.
Si el nodo principal es funcional y desea promover una réplica para que sea principal, debe quitar los nodos sin estado del principal con el ghe-remove-node comando , antes de volver a agregarlos al nodo promocionado.
Si el nodo principal no es accesible e irrecuperable, los nodos sin estado se pueden volver a agregar sin quitarlos del nodo principal original.
Supervisión, registros y paquetes de soporte
En el nodo principal, los paneles de supervisión de la Consola de administración muestran métricas para todos los nodos, incluidos los nodos sin estado. Comandos como ghe-cluster-nodes y ghe-cluster-status contienen detalles sobre nodos sin estado. El nodo principal atiende todas las solicitudes de la Consola de administración.
Los registros se almacenan localmente en los nodos sin estado. Se pueden exportar desde estos nodos a servicios de administración de registros de terceros.
Puede usar los ghe-cluster-support-bundle comandos y ghe-support-bundle para generar y cargar paquetes de clúster o de un solo nodo.
Mitigación de la saturación de softirq de un solo núcleo
Agregar un nodo sin estado a una GitHub Enterprise Server implementación de alta disponibilidad envía todo el tráfico entre dos nodos a través de un único túnel wireGuard. Dado que cada paquete para ese par de nodos comparte un puerto UDP, la tarjeta de red lo dirige a una cola de recepción y un núcleo de CPU procesa todos los paquetes entrantes. Bajo tráfico pesado que el núcleo alcanza el 100 % mientras los demás permanecen inactivos, y el nodo quita los paquetes. GitHub Enterprise Server incluye las mitigaciones integradas que se describen a continuación.
1. Escalado horizontal con más nodos sin estado
Cada nodo sin estado alcanza la principal a través de su propio túnel WireGuard, por lo que el principal procesa el tráfico de cada nodo en una cola de recepción independiente y el núcleo de CPU. La propagación de cargas de trabajo entre nodos más pequeños sin estado permite que el equilibrador de carga comparta la carga entre túneles en más de los núcleos principales y esto no depende del hash de nivel de túnel. Dos nodos reducen aproximadamente la carga de recepción por núcleo y tres la cortan a aproximadamente un tercio.
GitHub Enterprise Server cambia el tamaño de los trabajos web de cada nodo de su memoria y limita su propio valor en 30. Mantenga app.github.github-workers cerca de 30 por nodo; los recuentos más altos cuestan memoria y, durante una parada de túnel, agregue profundidad de cola en lugar de rendimiento, ya que los trabajos adicionales se bloquean en la principal. Para más capacidad, agregue más nodos sin estado.
2. WireGuard de varios túneles (participación)
GitHub Enterprise Server puede distribuir el tráfico entre nodos a través de varios túneles WireGuard. Cada túnel usa su propio puerto UDP, por lo que las diferentes conexiones llegan a diferentes colas de recepción y los distintos núcleos de CPU comparten el trabajo. Establezca el número de túneles en el número más bajo de colas de recepción en los nodos del clúster, el valor "Combinado" de ethtool -l eth0.
ghe-config wireguard.num-tunnels 8 ghe-config-apply
ghe-config wireguard.num-tunnels 8
ghe-config-apply
El valor predeterminado es 1. El máximo es 16; los valores más altos están limitados. Más túneles que la interfaz tiene colas de recepción no aporta ninguna ventaja. Para revertir, quite la configuración y aplique.
ghe-config --unset wireguard.num-tunnels ghe-config-apply
ghe-config --unset wireguard.num-tunnels
ghe-config-apply
Antes de habilitar (una vez):
- En el firewall externo o el grupo de seguridad en la nube, abra los puertos UDP de túnel adicionales entre todos los nodos, incluidas todas las réplicas. Los puertos cuentan desde 1194, por lo que 8 túneles usan UDP 1194 a 1201. El intervalo completo requiere UDP de 1194 a 1209.
- Al habilitar varios túneles, se actualiza el firewall del host. Aplíquelo una vez reiniciando todos los nodos o volviendo a cargar el firewall con
sudo ufw reloaden cada nodo. Confirme que el grupo de seguridad de red ya restringe primero el acceso entrante, ya que ufw vuelve a cargar brevemente y vuelve a crear las reglas. Los cambios posterioresnum-tunnelsno necesitan este paso.
3. Enrutamiento local de git-proxy en la principal (automática)
Las solicitudes de Git que un nodo sin estado enviaría de otro modo a través del túnel ahora permanecen en la principal, donde ya residen los datos de Git. Esto elimina una gran parte de paquetes entre túneles y no necesita ninguna acción. La principal usa primero su proxy de Git local y vuelve a un nodo remoto solo si el local no está disponible.
4. Ponderación de solicitudes web basadas en capacidad (participación)
Cuando los nodos ejecutan diferentes números de trabajos web, GitHub Enterprise Server pueden distribuir las solicitudes en proporción al recuento de trabajos de cada nodo en lugar de uniformemente. Habilite cuando los recuentos de trabajos sean desiguales, por ejemplo, una principal con 100 trabajos y un nodo sin estado con 30.
ghe-config app.github.unicorn-weight-by-capacity true ghe-config-apply
ghe-config app.github.unicorn-weight-by-capacity true
ghe-config-apply
El valor predeterminado está desactivado.
Elección de lo que se va a habilitar
Empiece por escalar horizontalmente a más nodos sin estado. Es la opción más completa, distribuye la carga en más de los núcleos principales a través del equilibrador de carga y no necesita ninguna marca de característica. Si un solo núcleo sigue saturando, habilite WireGuard de varios túneles. Habilite la ponderación basada en la capacidad solo cuando los recuentos de trabajo difieren entre los nodos.
Limitaciones conocidas
Esta característica no está diseñada para monorepositorios, pero la adición de nuevos nodos sin estado puede mejorar indirectamente las operaciones de monorepositorio al reducir las cargas de trabajo en la web y en los trabajos en el nodo principal. No hay características de autoscalado ni reducción de escala.