上一篇 下一篇 分享链接 返回 返回顶部

企业如何用Consul+Nomad在香港服务器上实现自动服务发现与负载调度?

发布人:Minchunlin 发布时间:2025-07-30 19:22 阅读量:792


大约半年前,我们团队接手了一个部署在香港本地数据中心的企业项目。项目初期,我们的服务部署依赖于 shell 脚本和一些老旧的 systemd 服务编排方式。随着业务量上升,服务器开始吃紧,服务频繁 down 掉又无人知晓,每次部署都要 SSH 到好几台机器检查端口、重启服务,靠 Excel 表维护服务 IP。这种“手工时代”的操作完全跟不上节奏。

我们必须要解决两个问题:

  • 服务需要“自动注册”,否则每个节点变动就要改配置。
  • 要实现“负载调度”,避免某一台服务器 CPU 飙高而别的还很空。

在调研了 Kubernetes、Docker Swarm、Rancher、OpenShift 之后,我们最终选择了 HashiCorp 的 Consul + Nomad 组合:轻量、原生支持多数据中心、易于自托管,尤其适合我们的非容器化服务环境(大多数是 Go 和 Python 服务,直接运行二进制或虚拟环境)。

下面是我在这次架构升级中实际踩过的坑、写下的部署流程和优化策略。

一、部署拓扑设计:香港节点为主,架构应对边缘计算

我们在香港数据中心有 5 台裸金属服务器,规划如下:

  • Nomad Server 节点:3 台(部署为集群)
  • Nomad Client 节点:全部 5 台(含 Server)
  • Consul Server 节点:3 台,与 Nomad Server 共用
  • Consul Agent(Client):部署在所有节点
  • Nginx:作为入口反向代理,通过 Consul DNS 动态解析服务地址

这套架构可以有效应对服务的动态调度,服务挂掉自动替换,DNS 实时发现新节点,最大化利用机器资源。

二、Consul 安装与配置(服务发现基石)

1. 安装 Consul(二进制安装)

wget https://releases.hashicorp.com/consul/1.16.1/consul_1.16.1_linux_amd64.zip
unzip consul_1.16.1_linux_amd64.zip
mv consul /usr/local/bin/

2. 配置 Server 节点(假设服务器 IP 为 10.0.0.1, 10.0.0.2, 10.0.0.3)
/etc/consul.d/server.hcl

server = true
bootstrap_expect = 3
data_dir = "/opt/consul"
bind_addr = "10.0.0.1"
retry_join = ["10.0.0.2", "10.0.0.3"]
ui = true
client_addr = "0.0.0.0"

启动:

consul agent -config-dir=/etc/consul.d/

3. 配置 Client 节点

/etc/consul.d/client.hcl

server = false
data_dir = "/opt/consul"
bind_addr = "10.0.0.4" # 当前机器的 IP
retry_join = ["10.0.0.1", "10.0.0.2", "10.0.0.3"]

三、Nomad 安装与配置(调度引擎核心)

1. 安装 Nomad

wget https://releases.hashicorp.com/nomad/1.7.3/nomad_1.7.3_linux_amd64.zip
unzip nomad_1.7.3_linux_amd64.zip
mv nomad /usr/local/bin/

2. 配置 Nomad Server 节点

/etc/nomad.d/server.hcl

server {
  enabled = true
  bootstrap_expect = 3
}

bind_addr = "0.0.0.0"
data_dir = "/opt/nomad"
advertise {
  http = "10.0.0.1"
  rpc  = "10.0.0.1"
  serf = "10.0.0.1"
}
consul {
  address = "127.0.0.1:8500"
}

3. 配置 Nomad Client 节点

/etc/nomad.d/client.hcl

client {
  enabled = true
  servers = ["10.0.0.1", "10.0.0.2", "10.0.0.3"]
}

consul {
  address = "127.0.0.1:8500"
}

bind_addr = "0.0.0.0"
data_dir = "/opt/nomad"

启动命令:

nomad agent -config=/etc/nomad.d/

四、服务自动注册与调度部署:一步到位

1. 创建一个 Nomad Job 文件(以 Python 服务为例)

hello-python.nomad

job "hello-python" {
  datacenters = ["dc1"]
  type = "service"

  group "web" {
    count = 3

    task "python-api" {
      driver = "exec"

      config {
        command = "/usr/bin/python3"
        args = ["-m", "http.server", "8080"]
      }

      resources {
        cpu    = 100
        memory = 128
      }

      service {
        name = "python-api"
        port = "http"

        check {
          type     = "http"
          path     = "/"
          interval = "10s"
          timeout  = "2s"
        }
      }

      env {
        ENV = "production"
      }

      # 网络端口映射
      resources {
        network {
          port "http" {
            static = 8080
          }
        }
      }
    }
  }
}

2. 提交任务

nomad job run hello-python.nomad

3. 验证服务发现

在任意节点上使用 DNS 解析:

dig @127.0.0.1 -p 8600 python-api.service.consul

Nginx 中配置:

upstream api_backend {
    server python-api.service.consul:8080;
}

server {
    listen 80;
    location / {
        proxy_pass http://api_backend;
    }
}

五、负载调度策略优化:智能调度靠的就是这几点

1. 加入资源感知

每个 task 申报资源,Nomad 会自动根据空闲资源分配任务:

resources {
  cpu    = 500 # MHz
  memory = 256 # MB
}

2. Job Constraint 控制调度节点

constraint {
  attribute = "${node.class}"
  operator  = "="
  value     = "gpu"
}

3. 动态扩缩容

结合外部脚本或 API,通过 Nomad CLI 扩缩 task 数:

nomad job scale hello-python web=5

六、总结与思考

Consul + Nomad 这套组合在香港服务器上的落地,给我们带来的是:

  • 服务注册发现自动化:不用再改配置、写 nginx reload 脚本
  • 任务调度弹性化:按资源调度,不再靠拍脑袋部署
  • 架构复杂度下降:部署脚本减少 80%,维护成本大幅下降

当然,这套方案并非“银弹”。它比不上 Kubernetes 的强大生态,但胜在轻量、易于入门、对裸机/传统服务极友好。

如果你也在用自建物理机部署、服务还未容器化、希望实现基础调度和服务发现功能,那我强烈建议你试试 Nomad + Consul,这是一套可以“踩地走”的企业级方案。

目录结构
全文