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