Customer story

How we built an automation platform for 600+ managed servers

And why we replaced n8n with Laravel along the way

Portrait of Toon Van Dooren

Toon Van DoorenCTO · Savvii Hosting

600+
Servers managed
3–4k
Final scale across all verticals
7
Infrastructure stacks unified post-merger
6
Tools evaluated before committing

当我们开始构建内部自动化平台时,我们以为自己选对了技术栈。我们用 n8n 进行工作流编排,用 Semaphore UI 运行 Ansible playbook,并对如何全面自动化托管运营有一套设想。几个月后,我面对的只能用一张蜘蛛网来形容——我知道我们必须从头再来。

1

我们试图解决的问题

我是 Savvii 的 CTO,这是一家位于荷兰的托管托管服务公司。我们专注于基于 PHP 的网站——电子商务、WordPress 及类似工作负载——并服务于三类客户:小型客户、分销商和代理商。每一类都有不同的需求、不同的规模和不同的期望。

代理商这一客户群是我们感受到压力最大的地方。代理商是成熟的客户,但他们的内部团队往往是技术与非技术人员的混合体。他们需要一个图形界面。他们无法靠命令行生存。我们接入的代理商越多,一件事就越发明显: 我们需要一个由真正的自动化支撑的合适的控制面板。

Ansible Tower 及类似工具曾在我们的考量范围内,但它们要么设置过于复杂,要么文档不一致,要么带有性能和数据主权方面的顾虑。 我们想要一个可以自托管、升级时不会带来麻烦的东西, 并且能够移交给我们的支持团队,而无需一周的培训。

2

评估各种选项

在做出任何决定之前,我们进行了一次全面的比较。有两个因素很快缩小了选择范围。

数据主权。 不接受任何会把状态或凭证存储在第三方云中的工具。自托管是不可妥协的。

面向非工程师的用户体验。 一线支持团队是优秀的沟通者,而非系统管理员。无论我们选择什么,都必须能够在不把每个事件升级给 DevOps 的情况下使用。我们评估的工具包括:

评判标准 Semaphore UI n8n AWX / Tower Rundeck
默认自托管 是——单一二进制文件 / 熟悉的部署方式 是——自托管版本 是(AWX)/ 混合(AAP 云选项)
一线支持的用户体验 任务&清单清晰度强 适合编写者;运维移交较弱 RBAC 概念繁重;对支持团队上手困难 以作业为中心;Ansible 使用体验较差
Ansible 清单&执行的用户体验 围绕项目&模板构建 不是 Ansible 控制平面 原生但升级路径复杂 可行;并非以 Ansible 为先
用于自定义中间件的 API 一致的任务&项目 API 功能广泛;运营模型不同 Tower API 表面随版本而异 成熟的作业 API;原语不同
升级&运营负担 实践中升级摩擦低 取决于工作流的蔓延程度 通常较重(K8s / 捆绑依赖) 中等;JVM 占用

Semaphore UI 在这两方面都胜出。安装很简单。升级毫无痛苦。界面足够清晰,连非工程师都能理解正在发生什么。接入我们现有的 Ansible 清单几乎没有摩擦——唯一需要帮助的地方是连接清单,而这通过支持团队很快得到了解决。Semaphore 的文档很扎实,这给了我们信心。

3

第一套架构:以 n8n 作为中间件

最初的架构使用 n8n 作为 HostBill(计费)、Semaphore UI 和 CMDB 之间的编排层。在纸面上看起来很干净——低代码、可视化,无需开发人员维护。

1
客户在 HostBill 中购买一台服务器
2
HostBill 向 n8n 发送一个 webhook
3
n8n 触发一个 Semaphore 任务,运行配置 Ansible playbook
4
playbook 在基础设施上运行
5
任务完成后 Semaphore 发送一个回调
6
n8n 接收回调并收集生成的数据
7
n8n 将服务器信息写入我们的 CMDB
8
客户收到他们的服务器凭证和连接详情
4

n8n 出了什么问题

n8n 的可视化界面对于简单的线性流程非常出色。但一旦条件判断、错误处理、多步回调和状态管理进入画面——全局视图就消失了。原本干净的图示变成了一块超现实主义的电路板。

没有安全的状态存储

在我们使用的版本中,没有安全的方式在步骤之间存储中间状态。

安全方面的顾虑

日志中没有可靠的密码掩码——当 Ansible 回调包含生成的凭证时,这是一个严重的问题。

脆弱的回调

n8n、Semaphore 和 CMDB 之间的回调处理需要过多的来回交互,这使得流程变得脆弱。

5

新架构:以 Laravel 作为中间件

我们用一个 Laravel 应用替换了 n8n。它是真正的中间件——不是无代码工具,而是我们团队完全拥有并理解的东西。

服务器配置流程
1
客户在 HostBill(计费面板)中订购一台服务器
2
HostBill 向 Laravel 中间件发送一个 webhook
3
Laravel 收集请求数据并在我们的 CMDB 中预留一个槽位
4
Laravel 调用 Semaphore 来触发配置 playbook
5
Semaphore 运行 playbook 并返回一个任务 ID
6
Laravel 将任务 ID 关联到 CMDB 记录
7
当 Semaphore 在完成时回调时,Laravel 用服务器 IP 更新 CMDB
8
客户被告知他们的服务器详情

安全模型

每台服务器都有一个 authorized_keys 文件,用于限制 Semaphore 的 SSH 密钥实际能做什么。通过使用 authorized_keys 中的 command 指令,我们精确定义了 Semaphore 被允许运行哪些命令。在初始设置之后,Semaphore 还会失去 root 访问权限——它只能连接到用户账户。

这显著限制了万一发生任何泄露时的影响范围。

6

我们现在所处的阶段

我们起步的代理商客户群,通过这套架构运行着约 600 台服务器。三类客户群的总体规模最终将达到 3,000 到 4,000 台服务器,我们正在逐步推广这一平台。

Semaphore 的调度器是下一个要上线的功能,用于服务器更新——目前由外部工具处理,但将转向由调度器驱动的 Ansible。

支持团队的独立性

支持团队可以独立使用 Semaphore,而无需在每个事件中拉上 DevOps。

实时告警

Slack 集成在 playbook 失败时为工程团队提供即时告警。

整洁的模板

通过 API 传递变量,使模板数量保持较低——避免了蔓延。

准确的 CMDB

CMDB 会自动保持准确——不再需要手动维护。

7

如果今天让我们重新开始

我们会做出的最大改变是: 在写下一行自动化代码之前,花更多时间进行架构设计。 我们不止一次从头再来,因为我们没有足够仔细地思考哪些流程能够扩展,以及哪些流程能够优雅地处理失败。

架构优先

在写下一行自动化代码之前,花更多时间进行架构设计。仔细思考哪些流程能够扩展并优雅地处理失败。

以用户体验评估,而不仅仅是功能

如果你的支持团队在凌晨两点不打电话给资深工程师就无法使用它,那它就是错误的工具。

数据主权很重要

在进入生产环境之前,先弄清楚你的凭证和状态存放在哪里。

好的文档是一个信号

如果一个工具的文档一团糟,那这个工具很可能也是如此。

Ready to automate your infrastructure?

Start with OSS, upgrade to Pro when your team grows. Enterprise support and SLA are available — including for hosting providers running thousands of servers.