当前位置: 代码网 > it编程>前端脚本>Python > 使用Python脚本实现同一个Git仓库在多个机房及多台电脑上同时同步

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

2026年04月03日 Python 我要评论
本文介绍了一个python脚本,用于在多台机器上同步git仓库。核心思路是通过中心控制节点并发ssh到各机器执行git pull或clone命令。脚本使用paramiko库和多线程实现,支持不同机房的

本文介绍了一个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仓库同时同步的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com