# go_deployment **Repository Path**: pantian/go_deployment ## Basic Information - **Project Name**: go_deployment - **Description**: 部署脚本 - **Primary Language**: Go - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-04 - **Last Updated**: 2025-11-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Go 自动化部署工具 一个基于 Go 语言开发的自动化部署工具,通过 SFTP 和 SSH 协议实现多服务器并发部署。 ## 核心特性 - ✅ 支持多服务器并发部署 - ✅ 支持服务器分组(开发/测试/生产环境) - ✅ SSH 密钥认证,安全可靠 - ✅ 文件压缩传输,显著提升传输效率(60%-90%) - ✅ 自动备份和快速回滚 - ✅ 灵活的部署钩子机制 - ✅ 智能重试机制,自动处理网络抖动 - ✅ 详细的部署日志和报告 - ✅ 支持 Dry-Run 模式模拟部署 ## 快速开始 ### 安装 ```bash go build -o deploy main.go ``` ### 配置 复制示例配置文件: ```bash cp deploy.example.yaml deploy.yaml ``` 编辑 `deploy.yaml` 文件,配置服务器信息和部署参数。 ### 使用 #### 0. 查看帮助信息 ```bash # 查看所有可用命令 ./deploy --help # 查看 deploy 命令的详细帮助 ./deploy deploy --help # 查看 validate 命令的帮助 ./deploy validate --help ``` #### 1. 验证配置 ```bash ./deploy validate --config deploy.yaml ``` #### 2. 部署到指定环境 ```bash # 部署到开发环境 ./deploy deploy --config deploy.yaml --env development # 部署到生产环境 ./deploy deploy --config deploy.yaml --env production # 详细输出模式 ./deploy deploy --config deploy.yaml --env production --verbose # 模拟运行(不实际部署) ./deploy deploy --config deploy.yaml --env production --dry-run ``` #### 3. 查看帮助 ```bash ./deploy --help ./deploy deploy --help ``` ## 配置说明 ### 环境配置 ```yaml environments: - name: production # 环境名称 servers: - name: prod-server-1 # 服务器标识名称 host: 192.168.1.10 # 服务器地址 port: 22 # SSH 端口(默认22) user: deployer # SSH 用户名 key_path: ~/.ssh/id_rsa # SSH 私钥路径 ``` ### 部署配置 ```yaml deployment: source_dir: ./dist # 本地源文件目录 target_dir: /var/www/app # 远程目标目录 excludes: # 排除的文件或目录 - "*.log" - ".git" backup: true # 是否启用备份 backup_dir: /var/backups/app # 备份目录 compress: true # 是否压缩传输 compress_format: tar.gz # 压缩格式(tar.gz/zip) compress_level: 6 # 压缩级别(1-9) timeout: 600 # 部署超时时间(秒) retry: max_attempts: 3 # 最大重试次数 interval: 2 # 重试间隔(秒) backoff: true # 是否使用指数退避 ``` ### 钩子配置 ```yaml hooks: timeout: 300 # 钩子命令超时时间(秒) continue_on_error: false # 命令失败是否继续 pre_deploy: # 部署前执行的命令 - "echo '开始部署...'" - "df -h" post_deploy: # 部署后执行的命令 - "chmod -R 755 /var/www/app" restart: # 服务重启命令 - "systemctl restart nginx" ``` ### 并发配置 ```yaml concurrency: 5 # 最大并发部署数 ``` ## 部署流程 1. **加载配置** - 读取并验证配置文件 2. **建立连接** - 与所有目标服务器建立 SSH 连接 3. **执行 pre_deploy 钩子** - 部署前准备工作 4. **备份(可选)** - 备份现有文件 5. **文件传输** - 压缩并上传文件到远程服务器 6. **执行 post_deploy 钩子** - 部署后处理 7. **执行 restart 钩子** - 重启服务 8. **生成报告** - 生成详细的部署报告 ## 日志和报告 ### 日志文件 日志文件保存在 `./logs/` 目录: ``` logs/ deploy_production_20240115_103045_a1b2c3d4.log reports/ report_production_20240115_103528.txt report_production_20240115_103528.json ``` ### 报告内容 - 部署摘要(成功/失败统计) - 传输统计(文件数量、压缩率、传输速度) - 重试统计(重试次数、成功率) - 服务器明细(每台服务器的详细执行结果) - 错误汇总 - 性能分析 - 优化建议 ## 使用场景 ### 场景一:前端静态文件部署 ```yaml deployment: source_dir: ./build target_dir: /usr/share/nginx/html excludes: - "*.map" compress: true hooks: post_deploy: - "chmod -R 644 /usr/share/nginx/html/*" restart: - "nginx -t" - "nginx -s reload" ``` ### 场景二:Go 应用程序部署 ```yaml deployment: source_dir: ./bin target_dir: /opt/myapp compress: true hooks: pre_deploy: - "systemctl stop myapp" post_deploy: - "chmod +x /opt/myapp/myapp" restart: - "systemctl start myapp" - "systemctl status myapp" ``` ## 性能优化 ### 压缩传输 默认启用压缩传输,可显著减少网络传输时间: - 前端项目:传输速度提升 **73%** - Go 二进制:传输速度提升 **49%** - 大量小文件:传输速度提升 **93%** ### 并发部署 支持多服务器并发部署,默认并发数为 5,可根据实际情况调整。 ### 智能重试 自动重试失败的操作,支持指数退避策略: - SSH 连接失败:重试 3 次(2s → 4s → 8s) - 文件传输失败:重试 3 次 - 远程解压失败:重试 2 次 ## 安全建议 ### 1. 使用专用部署账户 **不推荐:** ```yaml servers: - user: root # ❌ 避免使用 root ``` **推荐:** ```yaml servers: - user: deployer # ✓ 使用专用部署账户 ``` **创建部署账户:** ```bash # 在远程服务器上创建部署账户 sudo useradd -m -s /bin/bash deployer sudo mkdir -p /home/deployer/.ssh sudo chown -R deployer:deployer /home/deployer/.ssh ``` ### 2. 限制账户权限 **设置目录权限:** ```bash # 允许 deployer 访问部署目录 sudo chown -R deployer:deployer /var/www/app sudo chmod -R 755 /var/www/app ``` **配置 sudo 权限(仅允许必要命令):** ```bash # /etc/sudoers.d/deployer deployer ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx deployer ALL=(ALL) NOPASSWD: /bin/systemctl reload nginx deployer ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp ``` ### 3. 保护私钥 **设置私钥权限:** ```bash # 确保私钥文件权限正确 chmod 600 ~/.ssh/id_rsa chmod 700 ~/.ssh ``` **生成专用部署密钥:** ```bash # 生成专用的部署密钥对 ssh-keygen -t rsa -b 4096 -C "deploy@myapp" -f ~/.ssh/deploy_key # 将公钥复制到远程服务器 ssh-copy-id -i ~/.ssh/deploy_key.pub deployer@192.168.1.10 ``` ### 4. 配置文件安全 **添加到 .gitignore:** ``` # .gitignore deploy.yaml deploy.*.yaml *.pem *.key ``` **使用环境变量(可选):** ```yaml servers: - key_path: ${DEPLOY_SSH_KEY} # 从环境变量读取 ``` **加密敏感配置:** ```bash # 使用 git-crypt 或 ansible-vault 加密配置文件 git-crypt init git-crypt add-gpg-user YOUR_GPG_KEY echo "deploy.yaml filter=git-crypt diff=git-crypt" >> .gitattributes ``` ### 5. 使用 sudo 配置细粒度权限 **示例:只允许重启特定服务** ```bash # /etc/sudoers.d/deployer deployer ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp deployer ALL=(ALL) NOPASSWD: /bin/systemctl status myapp deployer ALL=(ALL) NOPASSWD: /usr/sbin/nginx -t deployer ALL=(ALL) NOPASSWD: /usr/sbin/nginx -s reload ``` **验证 sudo 配置:** ```bash # 测试 sudo 配置是否正确 sudo -l -U deployer ``` ### 6. 网络安全 **限制 SSH 访问:** ```bash # 在服务器防火墙中限制 SSH 访问来源 sudo ufw allow from 192.168.1.0/24 to any port 22 sudo ufw deny 22 ``` **使用堡垒机/跳板机:** ```yaml # 通过跳板机连接(需要配置 SSH ProxyJump) # 在 ~/.ssh/config 中配置: Host production-server HostName 10.0.1.10 User deployer ProxyJump bastion.example.com ``` ## 故障排查 ### 连接失败 **症状:** - 错误信息: "Failed to connect to server" - 错误信息: "Permission denied (publickey)" - 错误信息: "Connection timeout" **诊断步骤:** 1. **验证网络连通性** ```bash # 检查服务器是否可达 ping 192.168.1.10 # 检查 SSH 端口是否开放 telnet 192.168.1.10 22 # 或使用 nc (Windows 上可用 Test-NetConnection) Test-NetConnection -ComputerName 192.168.1.10 -Port 22 ``` 2. **测试 SSH 连接** ```bash # 手动测试 SSH 连接 ssh -i ~/.ssh/id_rsa deployer@192.168.1.10 # 使用详细模式查看连接过程 ssh -vvv -i ~/.ssh/id_rsa deployer@192.168.1.10 ``` 3. **检查私钥配置** ```bash # 验证私钥文件存在 ls -l ~/.ssh/id_rsa # 检查私钥权限(应为 600) # Windows: icacls ~/.ssh/id_rsa # Linux: stat -c "%a %n" ~/.ssh/id_rsa ``` 4. **检查服务器端配置** ```bash # 在服务器上检查 SSH 服务状态 sudo systemctl status sshd # 检查服务器端 authorized_keys cat ~/.ssh/authorized_keys # 查看 SSH 服务日志 sudo tail -f /var/log/auth.log # Ubuntu/Debian sudo tail -f /var/log/secure # CentOS/RHEL ``` **常见解决方案:** | 错误原因 | 解决方案 | |---------|----------| | 防火墙阻止 | 在服务器上开放 SSH 端口: `sudo ufw allow 22` | | 私钥权限错误 | 修正权限: `chmod 600 ~/.ssh/id_rsa` | | 公钥未添加 | 复制公钥: `ssh-copy-id -i ~/.ssh/id_rsa.pub user@host` | | SSH 服务未启动 | 启动服务: `sudo systemctl start sshd` | | 端口配置错误 | 检查配置文件中的 port 参数是否正确 | ### 文件传输失败 **症状:** - 错误信息: "Failed to upload file" - 错误信息: "No space left on device" - 错误信息: "Permission denied" **诊断步骤:** 1. **检查远程磁盘空间** ```bash # 在部署配置中添加 pre_deploy 钩子 hooks: pre_deploy: - "df -h" - "df -h /var/www/app" ``` 2. **检查目标目录权限** ```bash # 手动检查 ssh user@host "ls -ld /var/www/app" # 测试写权限 ssh user@host "touch /var/www/app/test.txt && rm /var/www/app/test.txt" ``` 3. **验证排除规则** ```bash # 使用 --verbose 模式查看传输详情 ./deploy deploy --env production --verbose ``` 4. **测试压缩和解压** ```bash # 手动测试压缩 tar -czf test.tar.gz ./dist # 测试远程解压 ssh user@host "tar -tzf /tmp/test.tar.gz" ``` **常见解决方案:** | 错误原因 | 解决方案 | |---------|----------| | 磁盘空间不足 | 清理磁盘: `ssh user@host "sudo du -sh /var/* \| sort -h"` | | 目录不存在 | 创建目录: `ssh user@host "mkdir -p /var/www/app"` | | 权限不足 | 修改所有者: `ssh user@host "sudo chown -R deployer /var/www/app"` | | 压缩包损坏 | 检查本地磁盘空间,重新尝试 | | 网络中断 | 启用重试机制(默认已启用) | | 远程无解压命令 | 安装: `ssh user@host "sudo yum install tar gzip"` | ### 钩子执行失败 **症状:** - 错误信息: "Hook command failed" - 错误信息: "command not found" - 服务重启失败 **诊断步骤:** 1. **查看详细错误输出** ```bash # 使用 verbose 模式 ./deploy deploy --env production --verbose ``` 2. **手动测试钩子命令** ```bash # 在服务器上手动执行钩子命令 ssh user@host "systemctl restart nginx" ssh user@host "chmod -R 755 /var/www/app" ``` 3. **检查命令路径** ```bash # 查看命令完整路径 ssh user@host "which systemctl" ssh user@host "which nginx" ``` 4. **检查 sudo 权限** ```bash # 测试 sudo 权限 ssh user@host "sudo -l" ``` **常见解决方案:** | 错误原因 | 解决方案 | |---------|----------| | 命令不存在 | 使用完整路径: `/usr/bin/systemctl restart nginx` | | 权限不足 | 配置 sudo: 见"安全建议"部分 | | 服务不存在 | 检查服务名称: `systemctl list-units --type=service` | | 命令超时 | 增加超时时间: `hooks.timeout: 600` | | 非关键命令失败 | 允许失败: `systemctl stop app \|\| true` 或设置 `continue_on_error: true` | ### 使用 Dry-Run 模式排查 **推荐排查流程:** ```bash # 1. 首先验证配置 ./deploy validate --config deploy.yaml # 2. 使用 dry-run 模拟部署 ./deploy deploy --env production --dry-run --verbose # 3. 确认无误后执行实际部署 ./deploy deploy --env production --verbose ``` ### 查看日志文件 **日志位置:** ```bash # 查看最新的部署日志 (PowerShell) Get-ChildItem logs\deploy_*.log | Sort-Object LastWriteTime -Descending | Select-Object -First 1 # 实时查看日志 (PowerShell) Get-Content logs\deploy_production_*.log -Wait -Tail 50 # 搜索错误信息 (PowerShell) Select-String -Path "logs\deploy_*.log" -Pattern "error|failed" -CaseSensitive:$false ``` **日志分析建议:** - 关注 [ERROR] 和 [WARN] 级别的日志 - 检查每台服务器的详细执行结果 - 注意重试次数和重试原因 - 查看传输统计,判断是否网络问题 ## 依赖库 | 依赖库 | 版本要求 | 用途 | |--------|---------|------| | golang.org/x/crypto/ssh | latest | SSH 客户端连接和认证 | | github.com/pkg/sftp | latest | SFTP 文件传输协议 | | gopkg.in/yaml.v3 | v3.x | YAML 配置文件解析 | | github.com/spf13/cobra | latest | 命令行框架和参数解析 | | golang.org/x/sync/semaphore | latest | 并发控制和协程管理 | **安装依赖:** ```bash go mod download # 或 go mod tidy ``` **更新依赖:** ```bash go get -u ./... go mod tidy ``` ## 开发环境要求 | 要求 | 版本/说明 | |------|----------| | Go 版本 | 1.24.5 或更高 | | 操作系统 | Linux, macOS, Windows | | 编译工具 | Go 编译器 (go build) | | 依赖管理 | Go Modules | **编译命令:** ```bash # Windows go build -o deploy.exe main.go # Linux/macOS go build -o deploy main.go ``` **交叉编译:** ```bash # 编译 Linux 64位版本 $env:GOOS="linux"; $env:GOARCH="amd64"; go build -o deploy-linux-amd64 main.go # 编译 macOS 64位版本 $env:GOOS="darwin"; $env:GOARCH="amd64"; go build -o deploy-darwin-amd64 main.go # 编译 Windows 64位版本 $env:GOOS="windows"; $env:GOARCH="amd64"; go build -o deploy-windows-amd64.exe main.go ``` ## 许可证 MIT License ## 贡献 欢迎提交 Issue 和 Pull Request!