Nomad 与 Kubernetes 对比:为什么我们将 SaaS 切换到 HashiCorp Nomad
Source: Dev.to
(请提供您希望翻译的正文内容,我将按照要求保留链接并保持原有的 Markdown 格式进行简体中文翻译。)
复杂度税:为什么 Kubernetes 并不总是答案
在现代 DevOps 领域,Kubernetes(K8s)常被视为容器编排的默认选择。它功能强大、经受过实战考验,并拥有庞大的生态系统。然而,对于许多中小型 SaaS 团队来说,Kubernetes 带来了显著的复杂度税。
我们花了两年时间管理一个生产环境的 K8s 集群。虽然它解决了我们的扩展问题,但我们发现自己花了大约 30 % 的工程时间 仅仅在维护编排器本身——调试 CNI 插件、管理复杂的 RBAC、以及与需要博士学位才能理解的 Helm Chart 纠缠不休。
于是我们开始关注 HashiCorp Nomad。
Nomad 是一个轻量级、灵活的编排器,能够管理容器化和非容器化的应用。它遵循 Unix 哲学:专注做好一件事。本文将阐述我们为何做出切换、两者的架构差异,以及如何实现生产就绪的 Nomad 工作流。
基本的 Nomad 代理配置
data_dir = "/opt/nomad/data"
bind_addr = "0.0.0.0"
server {
enabled = true
bootstrap_expect = 3
}
client {
enabled = true
}
这种简洁性延伸到了开发者体验。Nomad Job 使用 HCL(HashiCorp Configuration Language)定义,比 Kubernetes 那种冗长的 YAML 更易读。
生产就绪的 Nomad Job(用于 Next.js 前端)
job "webapp" {
datacenters = ["dc1"]
type = "service"
group "frontend" {
count = 3
network {
port "http" {
to = 3000
}
}
service {
name = "webapp-frontend"
port = "http"
check {
type = "http"
path = "/api/health"
interval = "10s"
timeout = "2s"
}
}
task "nextjs" {
driver = "docker"
config {
image = "my-registry/webapp:latest"
ports = ["http"]
}
resources {
cpu = 500 # MHz
memory = 256 # MB
}
env {
NODE_ENV = "production"
}
}
}
}
在 Nomad 中的层级结构是 Job → Group → Task。一个 Job 可以包含多个 Group,而 Group 包含在同一节点上共同定位的 Task(类似于 K8s 的 Pod)。
服务发现与负载均衡
Kubernetes 中的一个“坑”是 Ingress 控制器的复杂性。在 Nomad 生态系统中,你使用 Consul。当 Nomad Task 启动时,它会自动向 Consul 注册自身。随后可以使用 Fabio 或 Traefik 作为负载均衡器,它们会根据 Consul 的服务目录动态更新配置。
Vault 集成用于密钥管理
与 K8s Secrets(仅是 base64 编码的字符串)不同,Nomad 原生集成 Vault。你可以直接将密钥注入环境变量或文件中:
template {
data = <<EOH
DATABASE_URL="{{with secret \"database/creds/readonly\"}}{{.Data.url}}{{end}}"
EOH
destination = "secrets/file.env"
env = true
}
网络和存储注意事项
-
网络栈 – 默认情况下,Nomad 使用主机的网络栈,提供接近原生的性能,但需要你自行管理端口冲突。
解决方案: 使用 Nomad 的桥接网络模式并配合 CNI 插件,实现类似 K8s 的隔离容器网络。 -
存储 – Nomad 的 CSI(Container Storage Interface)支持相当稳健,虽不如 Kubernetes 那样“自动化”。
解决方案: 对于 SaaS 数据库,我们建议使用托管服务(如 RDS、Supabase)或在专用节点上使用 Nomad 的host_volume,以获得最大 IOPS。
功能比较
| 功能 | Kubernetes | HashiCorp Nomad |
|---|---|---|
| 复杂度 | 高(学习曲线陡峭) | 低(单一二进制文件) |
| 灵活性 | 仅容器(大多数情况下) | 容器、二进制文件、Java、虚拟机 |
| 生态系统 | 大规模 | 专注(HashiStack) |
| 资源使用 | 高开销 | 极低开销 |
关键要点
- Nomad 的运维和维护要容易得多。
- HashiStack(Nomad、Consul、Vault)提供了模块化、最佳实践的方案。
- HCL 是一种更优秀的基础设施即代码的配置语言。
您对编排的做法是什么?您是否感受到 “Kubernetes 疲劳”,或者您认为生态系统的收益大于复杂性?请在评论中留下您的想法。