前言

过去手动部署 1 个高可用 apollo 集群并验证往往需要 1 ~ 2 个工作日,现在1 个工作日(7小时)可以部署 24 套,部署一套只需 18 分钟,并且所有集群都是生产就绪的,如何实现的?

TL;DR

  • 基于 vscode 的统一开发环境
  • 基于 libvirtd 的配套测试环境
  • 基于 wireguard 的私网 gitlab 和生产服务器集群加密通信虚拟局域网
  • 基于 gitlab 的多分支开发模式
  • 基于 gitlab ci 的运维代码自动同步

统一的开发环境 & 可重复的测试环境

在我司办公区机房有一台 Linux 物理服务器,我使用这台服务器作为统一开发环境,平时所有的 ansible 代码编写工作都是通过 vscode remote development 登录这台物理服务器完成。下面是常见的 2 种访问方式:

开发服务器网络访问流程

每一个开发者会有自己的一个 Linux 普通用户,开发者只需在自己的电脑上安装好 vscode,通过 vscode remote development 插件和自己在服务器的普通账号 ssh 连接物理服务器即可, vscode 会在各自的开发者用户下运行 vscode server 进程,因为 vscode 实际上都跑在同一台物理服务器上,所以其他开发者就有了跟我一模一样的 ansible 开发环境。

开发服务器虚拟化

这篇博客也是通过 vscode remote development 方式,编写出来的,如下图:

vscode remote development 截图

我给该物理服务器上默认配置好了全局代理加速,安装了 ansible、ansible-lint,并通过 libvirtd 虚拟化了多台跟生产环境相同系统、相同版本的虚拟机用于测试。因为这些虚拟机是运行在物理机虚拟化内的,所以可以非常方便的给这些虚拟机打快照。我给所有虚拟机准备了一份跟生产一致的快照版本,然后在这个快照基础上测试 ansible 代码,如果测试不通过需要重复测试,只需通过物理服务器上写好的恢复脚本,执行脚本一键恢复所有虚拟机的状态到最新的快照指定的状态,然后重复测试即可。

有了以上的准备,就可以实现高频率的 ansible 开发和测试,从而确保 ansible 代码的高度兼容和稳定可靠。

未来我们的生产服务器系统将逐步从 CentOS 过度到 OpenEuler(欧拉)系统,通过自建 OpenEuler 虚拟化并开展频繁的 ansible 代码兼容性测试,我们就能实现平滑的 CentOS 到 OpenEuler 的过渡了。

基于 WireGuard 的运维网络

这块与实际情况并不完全一致

公司的 gitlab 在办公区内网,但生产服务器分布在全国 34个省级行政区的自建机房,我们通过 gitlab 存放所有运维代码,然后通过 ci 自动同步到每个机房的管理服务器,最后由相关的运维同事登录管理服务器并执行 ansible playbook。如果要实现高质量、高效率的代码化运维,实现 gitlab 和每个机房的管理服务器的安全通信是必不可少的。

我们现在采用的是 WireGuard Point to Sites 的网络架构,如下图:

point-to-sites-WireGuard-network-infrastructure

运维网转发节点是整个网络的中心,上面运行 WireGuard 作为服务端,具备公网 IP (假设是 1.2.3.4)。每个省份有一台运维管理服务器用于触发 ansible-playbook,运行 WireGuard 作为客户端,具备出公网的能力(可以 ping 通 1.2.3.4)。每个加入网络的客户端服务器会多一张虚拟网卡并得到一个 10.188.188.0/22 段的 IP,网络内的所有主机通过 10.188.188.0/22 的 IP 可以互相访问。

安全上,运维网转发节点通过 firewalld 限定请求的来源 IP,只有省份的管理服务器才允许访问运维网转发节点,从而归避免安全风险。

我们让 gitlab 服务器作为运维网的其中一个客户端,同样具备 10.188.188.0/24 的 IP,在管理服务器上安装 gitlab runner,并通过这个 IP 向 gitlab 注册自己,从而实现了跨分省的自动化运维。

gitlab 多分支协同

我们的开发模式是基于 gitlab 的多分支协同,有一条以自己的名字命令的分支,通过:

git pull --rebase --autostash origin master

跟最新的 master 分支保持同步并基于 Fast Forward 的 Merge 策略,从而保持简单的 git 记录。

我们的所有运维代码都存放在一个名为 infrastructure 的仓库内,里面的运维代码分为操作数据,操作会被抽象为 ansible role 提交到 gitlab 以做复用;数据会被进一步分为敏感不敏感数据,敏感数据加密后再提交到 gitlab,加密采用的是 gnupg + ansible-vault 的形式。在统一开发环境和每个机房管理服务器有 gnupg 的私钥。在开发时,如果需要编辑私密数据,只需执行:

ansible-vault decrypt group_vars/vault_example.yml

此时会触发 gnupg 提示输入密码用于鉴权(只有知道密码的人才能执行 ansible playbook)

use-gnupg-to-decrypt-ansible-vault

编辑完成后,执行:

ansible-vault encrypt group_vars/vault_example.yml

重新加密然后提交到 gitlab 即可。

在调用 ansible playbook 时,也会自动触发 gnupg 弹出输入解密的窗口,输入正确的密码后即可顺利执行 ansible playbook。

因为运维代码化仓库中私密数据是加密的,所以我们可以向全公司开放运维代码,从而在公司内部实现安全可靠的运维设施和架构的开放。

运维代码自动同步

经过评审合并到 master 分支的运维代码会被认为是成熟的运维代码,会触发 gitlab ci 自动同步代码到所有的机房的运维管理服务器,如下图:

gitlab-auto-sync-pipeline

运维人员通过登录每个机房的运维管理服务器,执行相关的 ansible playbook,基于内网实现所有服务器的代码化管理。

最后附上开发流程图:

develop-workflow