golang简单高效的服务器网络部署工具插件Stack Up的使用

Golang简单高效的服务器网络部署工具插件Stack Up的使用

Stack Up是一个简单的部署工具,可以在多个主机上并行执行给定的命令集。它读取Supfile(一个YAML配置文件)来定义网络(主机组)、命令和目标。

安装

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

基本用法

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

选项

选项 描述
-f Supfile 自定义Supfile路径
-e, --env=[] 设置环境变量
--only REGEXP 过滤匹配正则表达式的主机
--except REGEXP 过滤掉匹配正则表达式的主机
--debug, -D 启用调试/详细模式
--disable-prefix 禁用主机名前缀
--help, -h 显示帮助/使用信息
--version, -v 打印版本信息

网络

网络是一组主机的集合。

# Supfile

networks:
    production:
        hosts:
            - api1.example.com
            - api2.example.com
            - api3.example.com
    staging:
        # 动态获取主机列表
        inventory: curl http://example.com/latest/meta-data/hostname

$ sup production COMMAND 将在 api1api2api3 主机上并行运行 COMMAND。

命令

要在远程主机上运行的shell命令。

# Supfile

commands:
    restart:
        desc: 重启示例Docker容器
        run: sudo docker restart example
    tail-logs:
        desc: 查看所有主机的Docker日志尾部
        run: sudo docker logs --tail=20 -f example

$ sup staging restart 将在所有staging Docker容器上并行重启。

$ sup production tail-logs 将在所有生产容器上并行查看Docker日志。

串行命令(即滚动更新)

serial: N 限制命令最多在N个主机上同时运行。免费获得滚动更新功能!

# Supfile

commands:
    restart:
        desc: 重启示例Docker容器
        run: sudo docker restart example
        serial: 2

$ sup production restart 将重启所有Docker容器,最多同时重启两个。

单主机命令

once: true 限制命令只在一台主机上运行。适用于一次性任务。

# Supfile

commands:
    build:
        desc: 构建Docker镜像并推送到注册表
        run: sudo docker build -t image:latest . && sudo docker push image:latest
        once: true # 仅在一台主机上运行
    pull:
        desc: 从注册表拉取最新Docker镜像
        run: sudo docker pull image:latest

$ sup production build pull 将在一台生产主机上构建Docker镜像,然后分发到所有主机。

本地命令

总是在本地主机上运行的命令。

# Supfile

commands:
    prepare:
        desc: 准备上传
        local: npm run build

上传命令

将文件/目录上传到所有远程主机。内部使用tar

# Supfile

commands:
    upload:
        desc: 上传dist文件到所有主机
        upload:
          - src: ./dist
            dst: /tmp/

在所有主机上的交互式Bash

# Supfile

commands:
    bash:
        desc: 在所有主机上的交互式Bash
        stdin: true
        run: bash
$ sup production bash
#
# 输入命令并查看所有主机的输出!
# ^C

向所有主机传递预准备的命令:

$ echo 'sudo apt-get update -y' | sup production bash

# 或者:
$ sup production bash <<< 'sudo apt-get update -y'

# 或者:
$ cat <<EOF | sup production bash
sudo apt-get update -y
date
uname -a
EOF

在所有主机上的交互式Docker Exec

# Supfile

commands:
    exec:
        desc: 在所有主机上进入Docker容器
        stdin: true
        run: sudo docker exec -i $CONTAINER bash
$ sup production exec
ps aux
strace -p 1 # 在所有生产主机上跟踪系统调用和信号

目标

目标是多个命令的别名。每个命令将在所有主机上并行运行,sup将检查所有主机的返回状态,并且仅在成功时运行后续命令(因此任何主机上的任何错误都将中断流程)。

# Supfile

targets:
    deploy:
        - build
        - pull
        - migrate-db-up
        - stop-rm-run
        - health
        - slack-notify
        - airbrake-notify

$ sup production deploy 等同于:

$ sup production build pull migrate-db-up stop-rm-run health slack-notify airbrake-notify

Supfile

基本结构

# Supfile
---
version: 0.4

# 全局环境变量
env:
  NAME: api
  IMAGE: example/api

networks:
  local:
    hosts:
      - localhost
  staging:
    hosts:
      - stg1.example.com
  production:
    hosts:
      - api1.example.com
      - api2.example.com

commands:
  echo:
    desc: 打印一些环境变量
    run: echo $NAME $IMAGE $SUP_NETWORK
  date:
    desc: 打印操作系统名称和当前日期/时间
    run: uname -a; date

targets:
  all:
    - echo
    - date

Supfile中可用的默认环境变量

  • $SUP_HOST - 当前主机
  • $SUP_NETWORK - 当前网络
  • $SUP_USER - 调用sup命令的用户
  • $SUP_TIME - sup命令调用的日期/时间
  • $SUP_ENV - sup命令调用时提供的环境变量。您可以在Supfile中将$SUP_ENV传递给另一个supdocker命令。

从Supfile运行sup

Supfile不允许您导入另一个Supfile。相反,它允许您从Supfile内部运行sup子进程。这是构建大型项目的方式:

./Supfile
./database/Supfile
./services/scheduler/Supfile

顶层Supfile调用带有子项目Supfile的sup

 restart-scheduler:
    desc: 重启调度程序
    local: >
      sup -f ./services/scheduler/Supfile $SUP_ENV $SUP_NETWORK restart
 db-up:
    desc: 迁移数据库
    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-agent
ssh-add -l

如果您看到类似The agent has no identities.的内容,这意味着您需要手动将密钥添加到ssh-agent。为此,请运行以下命令:

ssh-add ~/.ssh/id_rsa

您现在应该能够使用您的ssh密钥使用sup了。

开发

fork it, hack it..

$ make build

create new Pull Request

我们很乐意审查和接受新的Pull Requests!

许可证

根据MIT许可证授权。


更多关于golang简单高效的服务器网络部署工具插件Stack Up的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang简单高效的服务器网络部署工具插件Stack Up的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Stack Up - Golang 简单高效的服务器网络部署工具

Stack Up 是一个用 Go 语言编写的轻量级服务器部署工具,它可以帮助开发者快速、简单地部署和管理服务器应用。下面我将介绍 Stack Up 的基本使用方法和示例代码。

Stack Up 主要特点

  1. 轻量级且易于使用
  2. 支持多服务器并行部署
  3. 内置 SSH 连接管理
  4. 支持自定义部署脚本
  5. 可扩展的插件系统

安装 Stack Up

go get github.com/stack-up/stack-up

基本使用示例

1. 创建配置文件

首先创建一个 stack.yml 配置文件:

servers:
  - name: "web-server"
    host: "example.com"
    user: "deploy"
    port: 22
    key_path: "~/.ssh/id_rsa"

tasks:
  deploy:
    - name: "Pull latest code"
      command: "cd /var/www/app && git pull origin master"
    
    - name: "Install dependencies"
      command: "cd /var/www/app && npm install"
    
    - name: "Restart service"
      command: "sudo systemctl restart app.service"

2. 基本 Go 代码示例

package main

import (
	"fmt"
	"log"

	"github.com/stack-up/stack-up/stack"
)

func main() {
	// 加载配置文件
	config, err := stack.LoadConfig("stack.yml")
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}

	// 创建部署器
	deployer, err := stack.NewDeployer(config)
	if err != nil {
		log.Fatalf("Failed to create deployer: %v", err)
	}

	// 执行部署任务
	err = deployer.RunTask("deploy")
	if err != nil {
		log.Fatalf("Deployment failed: %v", err)
	}

	fmt.Println("Deployment completed successfully!")
}

3. 高级功能示例

并行部署多个服务器

package main

import (
	"fmt"
	"log"

	"github.com/stack-up/stack-up/stack"
)

func main() {
	config, err := stack.LoadConfig("stack.yml")
	if err != nil {
		log.Fatal(err)
	}

	deployer, err := stack.NewDeployer(config)
	if err != nil {
		log.Fatal(err)
	}

	// 并行执行任务
	results := deployer.RunTaskParallel("deploy")

	for server, err := range results {
		if err != nil {
			fmt.Printf("Deployment failed on %s: %v\n", server, err)
		} else {
			fmt.Printf("Deployment succeeded on %s\n", server)
		}
	}
}

自定义任务

package main

import (
	"fmt"
	"log"

	"github.com/stack-up/stack-up/stack"
)

func main() {
	config, err := stack.LoadConfig("stack.yml")
	if err != nil {
		log.Fatal(err)
	}

	deployer, err := stack.NewDeployer(config)
	if err != nil {
		log.Fatal(err)
	}

	// 添加自定义任务
	customTask := stack.Task{
		Name: "custom",
		Steps: []stack.Step{
			{
				Name:    "Check disk space",
				Command: "df -h",
			},
			{
				Name:    "Check memory",
				Command: "free -m",
			},
		},
	}

	config.Tasks["custom"] = customTask

	// 执行自定义任务
	err = deployer.RunTask("custom")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Custom task executed successfully")
}

实际应用场景示例

部署 Go Web 应用

# stack.yml
servers:
  - name: "go-app-server"
    host: "go.example.com"
    user: "deploy"
    port: 22
    key_path: "~/.ssh/id_rsa"

tasks:
  deploy-go-app:
    - name: "Stop existing service"
      command: "sudo systemctl stop goapp.service"
    
    - name: "Pull latest code"
      command: "cd /opt/goapp && git pull origin main"
    
    - name: "Build application"
      command: "cd /opt/goapp && go build -o app ."
    
    - name: "Restart service"
      command: "sudo systemctl restart goapp.service"

部署 Node.js 应用

# stack.yml
servers:
  - name: "node-app-server"
    host: "node.example.com"
    user: "deploy"
    port: 22
    key_path: "~/.ssh/id_rsa"

tasks:
  deploy-node-app:
    - name: "Pull latest code"
      command: "cd /var/www/nodeapp && git pull origin master"
    
    - name: "Install dependencies"
      command: "cd /var/www/nodeapp && npm install --production"
    
    - name: "Restart PM2"
      command: "pm2 restart ecosystem.config.js"

最佳实践

  1. 使用环境变量:将敏感信息存储在环境变量中
  2. 错误处理:为每个任务添加适当的错误处理
  3. 日志记录:记录详细的部署日志
  4. 回滚机制:考虑添加回滚任务
  5. 测试环境:先在测试环境验证部署脚本

Stack Up 提供了一种简单而强大的方式来管理服务器部署,特别适合中小型项目。通过合理的配置和自定义任务,可以满足大多数部署需求。

回到顶部