编程 sup:用一份 Supfile 把命令并行发到多台主机,无需 agent 的部署工具

2026-10-16 21:31:15

sup:用 Supfile 把命令并行发到多台主机

Stack Up(sup)是一个简单的部署工具,把一组给定的命令并行发到多台主机上执行。它读取 Supfile —— 一个 YAML 配置文件,里面定义 networks(主机分组)、commands(命令)和 targets(命令别名)。它走的是你系统上的 ssh,不需要在目标机器上装 agent。

项目地址:pressly/sup,主页:pressly.github.io/sup。

适合少量到几十台主机、想复用 ~/.ssh/config 和既有 ssh 语义、不想为一个部署脚本引入 Ansible 的场景;主机清单规模很大、需要复杂编排与状态管理时,它不是合适的选择。

安装

$ go get -u github.com/pressly/sup/cmd/sup

用法

$ sup [OPTIONS] NETWORK COMMAND [...]

选项

选项说明
-f Supfile自定义 Supfile 路径
-e, --env=[]设置环境变量
--only REGEXP只保留匹配正则的主机
--except REGEXP过滤掉匹配正则的主机
--debug, -D打开 debug/verbose 模式
--disable-prefix关闭主机名前缀
--help, -h显示帮助/用法
--version, -v打印版本

Network

Network 是一组主机。

networks:
production:
hosts:
- api1.example.com
- api2.example.com
- api3.example.com
staging:
# fetch dynamic list of hosts
inventory: curl http://example.com/latest/meta-data/hostname

$ sup production COMMAND 会在 api1、api2、api3 上并行执行 COMMAND。

Command

Command 是一段要在远端执行的 shell 命令。

commands:
restart:
desc: Restart example Docker container
run: sudo docker restart example
tail-logs:
desc: Watch tail of Docker logs from all hosts
run: sudo docker logs --tail=20 -f example

$ sup staging restart 会并行重启所有 staging 主机上的 Docker 容器。

Serial 命令(也就是滚动更新)

serial: N 把一条命令限制为一次最多在 N 台主机上执行,等于白送一个滚动更新。

commands:
restart:
desc: Restart example Docker container
run: sudo docker restart example
serial: 2

$ sup production restart 会重启所有 Docker 容器,一次最多两台。

Once 命令(只在一台主机上)

once: true 把一条命令限制为只在一台主机上执行,适合一次性任务。

commands:
build:
desc: Build Docker image and push to registry
run: sudo docker build -t image:latest . && sudo docker push image:latest
once: true # one host only
pull:
desc: Pull latest Docker image from registry
run: sudo docker pull image:latest

$ sup production build pull 只在一台 production 主机上构建 Docker 镜像,再把它分发到所有主机。

Local 命令

始终在 localhost 上执行。

commands:
prepare:
desc: Prepare to upload
local: npm run build

Upload 命令

把文件/目录上传到所有远端主机,底层用的是 tar。

commands:
upload:
desc: Upload dist files to all hosts
upload:
- src: ./dist
dst: /tmp/

在所有主机上交互式跑 Bash

commands:
bash:
desc: Interactive Bash on all hosts
stdin: true
run: bash
$ sup production bash
# type in commands and see output from all hosts!

把准备好的命令传给所有主机:

$ echo 'sudo apt-get update -y' | sup production bash
$ sup production bash
sup -f ./services/scheduler/Supfile $SUP_ENV $SUP_NETWORK restart
db-up:
desc: Migrate database
local: >
sup -f ./database/Supfile $SUP_ENV $SUP_NETWORK up

常见的 SSH 问题

如果 sup 连不上,出现下面这条报错:

connecting to clients failed: connecting to remote host failed: Connect("myserver@xxx.xxx.xxx.xxx"): ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain

说明你的 ssh-agent 拿不到公钥和私钥。按下面的步骤修复:

  • 运行 ssh-add -l。如果看到 The agent has no identities.,运行 ssh-add ~/.ssh/id_rsa。之后就应该能用 ssh key 正常使用 sup 了。

开发

$ make build

Homepage: https://pressly.github.io/sup
Repo: https://github.com/pressly/sup

复制全文 生成海报 Shell 部署 运维 SSH Go

推荐文章

程序员茄子在线接单