使用Python脚本实现同一个Git仓库在多个机房及多台电脑上同时同步

 更新时间:2026年04月03日 09:33:38   作者:独隅  
本文介绍了一个Python脚本,用于在多台机器上同步Git仓库,通过中心控制节点并发SSH到各机器执行git pull或clone命令,支持SSH密钥或密码登录,配置需修改仓库地址、目标路径和机器列表,适用于跨机房代码同步场景,需要的朋友可以参考下

本文介绍了一个Python脚本,用于在多台机器上同步Git仓库。核心思路是通过中心控制节点并发SSH到各机器执行git pull或clone命令。脚本使用paramiko库和多线程实现,支持不同机房的服务器配置,包括SSH密钥或密码登录。配置需修改仓库地址、目标路径和机器列表,运行后显示同步结果。前提条件是目标机器需安装Git并配置访问权限。该方案适用于跨机房代码同步场景。

要实现 同一个 Git 仓库在多个机房、多台电脑上同时同步,核心思路是:

✅ 在每台目标机器上执行 git pull(或先 clone 再 pull)
✅ 通过 中心控制节点(你的 Python 脚本)并发 SSH 到各机器执行命令

架构说明

[ 控制机 (Python 脚本) ]
        │
        ├── SSH ──▶ [机房A - 服务器1]
        ├── SSH ──▶ [机房A - 服务器2]
        ├── SSH ──▶ [机房B - 服务器1]
        └── SSH ──▶ [机房C - 服务器3]

所有目标机器需:

  • 安装 git
  • 配置好 SSH 免密登录(或使用密码)
  • 有权限访问 Git 仓库(SSH key 或 HTTPS 凭据)

Python 实现(使用paramiko+ 多线程)

第一步:安装依赖

pip install paramiko

第二步:编写脚本sync_git_across_machines.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
同步同一个 Git 仓库到多个机房的多台机器
支持并发 SSH 执行 git clone / pull
"""

import paramiko
import logging
from concurrent.futures import ThreadPoolExecutor, as_completed
from dataclasses import dataclass
from typing import Optional

# ================== 配置区 ==================
GIT_REPO_URL = "git@github.com:your-team/your-app.git"  # 替换为你的仓库地址
LOCAL_PATH_ON_REMOTE = "/opt/app"                      # 远程机器上的本地路径

# 目标机器列表(支持不同机房)
MACHINES = [
    # 格式: (hostname, port, username, password 或 None 表示用 SSH key)
    ("192.168.10.101", 22, "deploy", None),      # 机房A - server1
    ("192.168.10.102", 22, "deploy", None),      # 机房A - server2
    ("10.20.30.40",   22, "ubuntu", None),       # 机房B - server1
    ("172.16.5.60",   22, "root", "your_password"),  # 机房C - server3(用密码)
]

MAX_WORKERS = len(MACHINES)  # 并发数 = 机器数
SSH_TIMEOUT = 10
GIT_TIMEOUT = 300

# ===========================================

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s"
)
logger = logging.getLogger(__name__)

@dataclass
class SyncResult:
    host: str
    success: bool
    message: str

def sync_to_machine(hostname: str, port: int, username: str, password: Optional[str]) -> SyncResult:
    """在单台远程机器上同步 Git 仓库"""
    try:
        # 建立 SSH 连接
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        
        if password:
            client.connect(hostname, port=port, username=username, password=password, timeout=SSH_TIMEOUT)
        else:
            client.connect(hostname, port=port, username=username, timeout=SSH_TIMEOUT)
        
        logger.info(f"[{hostname}] SSH 连接成功")

        # 构造 Git 同步命令
        cmd = f"""
        if [ ! -d "{LOCAL_PATH_ON_REMOTE}" ]; then
            echo "目录不存在,开始 clone..."
            git clone {GIT_REPO_URL} {LOCAL_PATH_ON_REMOTE}
        else
            echo "目录存在,执行 pull..."
            cd {LOCAL_PATH_ON_REMOTE} && git pull
        fi
        """
        
        stdin, stdout, stderr = client.exec_command(cmd, timeout=GIT_TIMEOUT)
        exit_code = stdout.channel.recv_exit_status()
        
        if exit_code == 0:
            output = stdout.read().decode().strip()
            logger.info(f"[{hostname}] 同步成功")
            return SyncResult(hostname, True, output)
        else:
            error = stderr.read().decode().strip()
            logger.error(f"[{hostname}] 同步失败: {error}")
            return SyncResult(hostname, False, error)
            
    except Exception as e:
        logger.error(f"[{hostname}] SSH 或执行异常: {e}")
        return SyncResult(hostname, False, str(e))
    finally:
        try:
            client.close()
        except:
            pass

def main():
    logger.info(f"开始同步 Git 仓库到 {len(MACHINES)} 台机器...")
    
    results = []
    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        futures = {
            executor.submit(sync_to_machine, host, port, user, pwd): host
            for host, port, user, pwd in MACHINES
        }
        for future in as_completed(futures):
            result = future.result()
            results.append(result)
    
    # 汇总结果
    success_count = sum(1 for r in results if r.success)
    logger.info(f"同步完成!成功: {success_count}/{len(MACHINES)}")
    
    # 打印失败详情
    for r in results:
        if not r.success:
            logger.error(f"❌ {r.host}: {r.message}")

if __name__ == "__main__":
    main()

前提条件

  1. 控制机(运行此脚本的机器)能 SSH 到所有目标机器
  2. 目标机器
    • 已安装 git
    • 若用 SSH 方式拉取 Git,需配置好 ~/.ssh/id_rsa 且有权限
    • 若用 HTTPS,建议提前配置 credential.helper 避免交互

推荐:在目标机器上部署统一的 deploy 用户,并配置 Git 访问权限。

使用步骤

  1. 修改 GIT_REPO_URL 为你的仓库地址(如 git@github.com:org/repo.git
  2. 修改 LOCAL_PATH_ON_REMOTE(如 /data/myapp
  3. 填写 MACHINES 列表(IP、端口、用户名、密码/None)
  4. 确保 SSH 免密登录已配置(或提供密码)
  5. 运行脚本:
python3 sync_git_across_machines.py

输出示例

2026-03-18 11:00:01 [INFO] 开始同步 Git 仓库到 4 台机器...
2026-03-18 11:00:02 [INFO] [192.168.10.101] SSH 连接成功
2026-03-18 11:00:02 [INFO] [10.20.30.40] SSH 连接成功
...
2026-03-18 11:00:08 [INFO] [192.168.10.101] 同步成功
2026-03-18 11:00:10 [ERROR] [172.16.5.60] 同步失败: Permission denied (publickey).
2026-03-18 11:00:12 [INFO] 同步完成!成功: 3/4

高级优化建议

需求方案
批量管理机器从 YAML/JSON 文件读取 MACHINES
指定分支git clone -b maingit pull origin main
失败重试sync_to_machine 中加 retry 逻辑
日志分离每台机器输出到独立日志文件
Ansible 替代若环境复杂,可用 Ansible + git 模块

此方案适用于 中小规模集群(几十台以内)。若超大规模,建议结合 配置管理工具(如 Ansible、SaltStack)。

如需我帮你生成 YAML 配置版支持 Git LFS/子模块 的版本,请继续提问!

以上就是使用Python脚本实现同一个Git仓库在多个机房及多台电脑上同时同步的详细内容,更多关于Python脚本同一个Git仓库同时同步的资料请关注脚本之家其它相关文章!

相关文章

最新评论