对于希望进行横向扩展的 GitHub Enterprise Server 客户而言,迁移到集群并进行运维是一种选择,但这需要投入大量资源和时间。 作为替代方法,我们建议将节点添加到 HA 配置。
本文中可互换使用术语“其他节点”和“无状态节点”。 无状态节点只能添加到包含至少一个副本的 HA 部署。
其他节点
在设备上运行 GitHub Enterprise Server 的所有服务中,Unicorn 通常是 CPU 和内存密集型最多的服务,紧随其后的是 Aqueduct、Git 和 MySQL。 由于 Unicorn 和 Aqueduct 是无状态服务,因此它们非常适合水平缩放,可以在一组单独的节点上运行。 其余服务可以继续使用每个数据中心的单个实例运行。
附加节点允许您水平扩展 Web 和任务工作负载。 它们还可以将 Unicorn 和 Aqueduct 从主节点迁移走,为剩余的有状态服务释放大量的计算和内存资源。 如果由于 Unicorn 实例的 CPU 使用率较高而遇到性能相关的服务中断,建议添加其他节点。 在数据中心内可以添加的这些节点的数量没有重大限制。
条件
如果由于 HA 配置中的重载主节点而导致性能下降,应考虑将其他节点添加到 HA 环境。 通过在主节点之外水平缩放 Web 角色和作业角色,这些额外的节点可以帮助减少主主机上的负载。
例如,如果你注意到 Unicorn 或 Aqueduct 队列中积压工作,或者遇到其他类型的资源争用,则应考虑此方法。 即使没有可见的队列,主节点上的 CPU 耗尽也是另一个明确的信号。 在这些情况下,可以添加其他节点并减少每个节点的工作器数,因此主节点处理的总体工作负荷更少。
添加节点
添加到 HA 部署中的每个节点都是一台运行 GitHub Enterprise Server 软件的虚拟机(VM)。 它应运行与主系统相同的软件。 通常,无状态节点不需要与主节点的内存、CPU 或存储规范匹配。 但是,无状态节点和主实例都需要子毫秒连接。 副本连接要求保持不变。
若要将节点添加到 HA 配置中的主数据中心,请使用 ghe-add-node 命令。 该 ghe-add-node 命令将当前设备设置为 HA 部署中的节点,旨在从主数据节点卸载 CPU 密集型任务,从而启用水平缩放。 这些节点旨在处理 Web 和作业工作负荷,从而提高工作负荷分发和管理效率。
此命令采用以下格式:
/usr/local/share/enterprise/ghe-add-node PRIMARY_IP [--hostname HOSTNAME]
/usr/local/share/enterprise/ghe-add-node PRIMARY_IP [--hostname HOSTNAME]
PRIMARY_IP:主节点的 IP 地址。HOSTNAME(可选):所添加主机的所需主机名。
例如,若要将主机名 ghes-node-1 的节点添加到 HA 主数据中心具有 IP 地址 192.168.1.1 的 HA 主实例,请运行以下命令:
/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
然后,在主节点上,必须运行以下命令:
ghe-config-apply ghe-cluster-balance rebalance --yes
ghe-config-apply
ghe-cluster-balance rebalance --yes
此命令 ghe-config-apply 是添加无状态节点的要求。
我们建议在维护窗口期间添加无状态节点。
删除其他节点
在删除其他节点之前,请在 HA 部署的每个节点上为功能版本安装相同的最新修补程序,并计划维护时段。 等待任何升级或配置运行完成,然后再开始删除。
-
在 HA 主节点上,检查 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 --verbose确认这两
ghe-cluster-nodes个命令都列出相同的主机名,并包括计划删除的节点的主机名。 确认每个节点的 Nomad 状态均为ready,并且对于每个节点,connect-ssh和enterprise-version均为ok。 确认主副本和任何其他副本上的有状态服务运行状况良好。 如果未保留任何副本,则会出现一条警告,指出未找到 MySQL 副本。 如果目标上的故障仅限于 Web、job 或 memcache 工作负载,则不会阻止移除。 如果任何其他节点级检查或状态化服务检查失败,请先联系 GitHub 支持,再进行移除。 -
在 HA 主节点上,删除其他节点。 用附加节点的主机名替换
HOSTNAME。Shell ghe-remove-node --verbose HOSTNAME
ghe-remove-node --verbose HOSTNAME如果另一个非主节点仍然存在,则命令会清空目标,将其从 HA 配置中删除,然后运行
ghe-config-apply。 如果未保留非主节点,该命令将删除群集元数据,并将主节点转换为独立实例,而无需运行ghe-config-apply。 无论哪种情况,都不要单独运行ghe-config-apply。 -
确认已删除。
如果另一个非主节点仍然存在,请在 HA 主节点上运行以下命令。 确认主机名不存在并且 HA 配置正常。
Shell ghe-cluster-nodes --offline ghe-cluster-status --extended --verbose
ghe-cluster-nodes --offline ghe-cluster-status --extended --verbose如果未保留非主节点,请不要运行仅限群集的命令。 确认移除操作的输出中包含
Cluster artifacts removed; now standalone.,然后确认主节点承载用户流量并处理 Web 和作业工作负载。
如果其他节点处于离线状态、无法访问或版本不同,或者 ghe-remove-node 或验证检查失败,请联系 GitHub 支持。 请勿手动编辑 cluster.conf 。
对之前托管过 GitHub Enterprise Server 的节点重新置备
您可以将先前托管并运行过 GitHub Enterprise Server 的节点用作无状态节点。 为此,节点应更新到版本 3.18 或更高版本,并且部署中的所有节点都必须运行相同的版本。 请检查在该节点上,/data/user/common/cluster.conf 是否已存在。 如果这样做,则需要在无状态节点上运行 ghe-add-node 命令之前执行清理。
例如:
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
限制和行为
可以添加的节点数没有理论限制。 但是,在实践中,添加过多的节点可能会导致问题并影响稳定性或性能。 此时,新添加的节点将处理一组预定义的任务。 无法选择要卸载的任务类型。 所有 API 都可以由其他节点处理。
如果路径中有 Git 操作,则存在仅在主节点上处理 Git 操作的逻辑。 其他节点不会处理 Git 操作。 例如,分支删除是 Git 操作,不会由无状态节点处理。
无状态节点不运行 Elasticsearch 工作负载,但它们确实运行 kafka-lite。
系统和网络要求
通常,无状态节点不需要与主节点的内存、CPU 和存储规格匹配。 系统要求应考虑到主节点上 Web 和作业服务的现有资源消耗,以及主节点是否会将这些工作负荷完全卸载到新节点。
无状态节点和主实例需要子毫秒连接。 通常,主数据中心内的所有节点都需要子毫秒连接。 副本连接要求保持不变。
流量路由和请求处理
主节点将流量路由到其他节点。 如果有多个无状态节点,主节点会向当时活动连接最少的服务器发送新连接。
使用其他节点升级 HA 部署
下面是升级序列示例:
- 开始维护时段。
- 停止复制副本。
- 并行地升级无状态节点。
- 升级主节点。
- 升级副本。 可以根据灾难恢复首选项并行或按顺序升级它们。
- 启动副本。
- 删除维护时段。
在升级期间,其他节点不应造成额外的停机。
故障转移和灾难恢复行为
无需“拆解”其他节点,因为它们不包含任何数据。
在故障转移期间,副本节点将从原始部署中删除,并转换为独立节点。 无状态节点应重新连接到升级的副本,类似于故障转移后重新连接其他副本的方式。
如果主节点正常运行,并且想要将副本提升为主节点,则应使用 ghe-remove-node 命令从主节点中删除无状态节点,然后再将其重新添加到已升级的节点。
如果主节点无法访问且不可恢复,则可以重新添加无状态节点,而无需从原始主节点中删除它们。
监控、日志和支持包
在主节点上,管理控制台监视仪表板显示所有节点(包括无状态节点)的指标。 诸如ghe-cluster-nodes和ghe-cluster-status的命令包含无状态节点的详细信息。 所有管理控制台请求都由主节点提供。
日志存储在无状态节点上。 可以将这些节点导出到第三方日志管理服务。
可以使用 ghe-cluster-support-bundle 和 ghe-support-bundle 命令生成并上传集群或单节点捆绑包。
缓解单核 softirq 饱和度
将无状态节点添加到 GitHub Enterprise Server 高可用性部署时,会使两个节点之间的所有流量都通过单个 WireGuard 隧道传输。 由于该节点对的每个数据包共享一个 UDP 端口,因此网卡会将其定向到一个接收队列,一个 CPU 核心处理所有入站数据包。 在高流量负载下,该核心会达到 100%,而其他核心则处于空闲状态,节点会发生丢包。 GitHub Enterprise Server 包括下面所述的内置缓解措施。
1.使用更多无状态节点横向扩展
每个无状态节点通过其自己的 WireGuard 隧道到达主节点,因此主节点处理每个节点在单独的接收队列和 CPU 核心上的流量。 将工作负荷分散到更多较小的无状态节点,使负载均衡器可以在更多主核心之间共享跨隧道负载,这不依赖于隧道级哈希。 两个节点大约将每个核心接收负载减半,三个节点将它削减到大约三分之一。
GitHub Enterprise Server 根据每个节点的内存确定其 Web 工作进程的数量,并将其自身的值上限设为 30。 将每个节点的 app.github.github-workers 保持在接近 30 个;数量更高会占用更多内存,而且在隧道发生停滞时,增加的是队列深度而不是吞吐量,因为额外的工作线程会阻塞在主节点上。 对于更多容量,请添加更多无状态节点。
2. 多隧道 WireGuard(可选启用)
GitHub Enterprise Server 可以将节点间流量分配到多个 WireGuard 隧道上。 每个隧道使用自己的 UDP 端口,因此不同的连接位于不同的接收队列上,不同的 CPU 核心共享工作。 将隧道计数设置为群集节点中的接收队列数最低,即“组合”值 ethtool -l eth0。
ghe-config wireguard.num-tunnels 8 ghe-config-apply
ghe-config wireguard.num-tunnels 8
ghe-config-apply
默认值为 1。 最大值为 16;更高的值将被限制为 16。 隧道数量超过该接口的接收队列数量,不会带来任何益处。 若要还原,请删除该设置并应用。
ghe-config --unset wireguard.num-tunnels ghe-config-apply
ghe-config --unset wireguard.num-tunnels
ghe-config-apply
在启用前(仅需一次):
- 在外部防火墙或云安全组中,打开所有节点(包括所有副本)之间的额外隧道 UDP 端口。 端口计数从 1194 起,因此 8 个隧道使用 UDP 1194 到 1201。 整个范围需要 UDP 1194 到 1209。
- 启用多隧道会更新主机防火墙。 只需执行一次即可使其生效:重启所有节点,或在每个节点上使用
sudo ufw reload重新加载防火墙。 先确认网络安全组已经限制了入站访问,因为执行 ufw reload 时会短暂移除并重新创建这些规则。 以后num-tunnels的更改不需要此步骤。
3.主服务器上的本地 git 代理路由(自动)
原本无状态节点会通过隧道发回的 Git 请求,现在会留在主节点上处理,因为 Git 数据本来就存放在那里。 这会删除大量跨隧道数据包,无需执行任何操作。 主节点首先使用其本地 Git 代理,仅在本地代理不可用时才回退到远程节点。
4. 基于容量的 Web 请求加权(可选启用)
当各节点运行的 Web 工作进程数量不同时,GitHub Enterprise Server 可以按照各节点的工作进程数量按比例分配请求,而不是平均分配。 当工作器数量不均衡时,请启用此项,例如主节点有 100 个工作器,而无状态节点有 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
默认值为 off。
选择要启用的内容
首先横向扩展到更多无状态节点。 这是最完整的选项,通过负载均衡器将负载分散到更多主核心,无需功能标志。 如果单个核心仍然饱和,请启用多隧道 WireGuard。 仅当工作器计数因节点而异时,才启用基于容量的权重。
已知的限制
此功能不是针对 monorepos 设计的,但添加新的无状态节点可能会通过减少主节点上的 Web 和作业工作负荷间接改善 monorepo 操作。 没有自动缩放和缩减功能。