使用Python腳本實現(xiàn)同一個Git倉庫在多個機房及多臺電腦上同時同步
本文介紹了一個Python腳本,用于在多臺機器上同步Git倉庫。核心思路是通過中心控制節(jié)點并發(fā)SSH到各機器執(zhí)行g(shù)it pull或clone命令。腳本使用paramiko庫和多線程實現(xiàn),支持不同機房的服務器配置,包括SSH密鑰或密碼登錄。配置需修改倉庫地址、目標路徑和機器列表,運行后顯示同步結(jié)果。前提條件是目標機器需安裝Git并配置訪問權(quán)限。該方案適用于跨機房代碼同步場景。
要實現(xiàn) 同一個 Git 倉庫在多個機房、多臺電腦上同時同步,核心思路是:
? 在每臺目標機器上執(zhí)行 git pull(或先 clone 再 pull)
? 通過 中心控制節(jié)點(你的 Python 腳本)并發(fā) SSH 到各機器執(zhí)行命令
架構(gòu)說明
[ 控制機 (Python 腳本) ]
│
├── SSH ──? [機房A - 服務器1]
├── SSH ──? [機房A - 服務器2]
├── SSH ──? [機房B - 服務器1]
└── SSH ──? [機房C - 服務器3]
所有目標機器需:
- 安裝
git - 配置好 SSH 免密登錄(或使用密碼)
- 有權(quán)限訪問 Git 倉庫(SSH key 或 HTTPS 憑據(jù))
Python 實現(xiàn)(使用paramiko+ 多線程)
第一步:安裝依賴
pip install paramiko
第二步:編寫腳本sync_git_across_machines.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
同步同一個 Git 倉庫到多個機房的多臺機器
支持并發(fā) SSH 執(zhí)行 git clone / pull
"""
import paramiko
import logging
from concurrent.futures import ThreadPoolExecutor, as_completed
from dataclasses import dataclass
from typing import Optional
# ================== 配置區(qū) ==================
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) # 并發(fā)數(shù) = 機器數(shù)
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 連接成功")
# 構(gòu)造 Git 同步命令
cmd = f"""
if [ ! -d "{LOCAL_PATH_ON_REMOTE}" ]; then
echo "目錄不存在,開始 clone..."
git clone {GIT_REPO_URL} {LOCAL_PATH_ON_REMOTE}
else
echo "目錄存在,執(zhí)行 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 或執(zhí)行異常: {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)
# 匯總結(jié)果
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()
前提條件
- 控制機(運行此腳本的機器)能 SSH 到所有目標機器
- 目標機器:
- 已安裝
git - 若用 SSH 方式拉取 Git,需配置好
~/.ssh/id_rsa且有權(quán)限 - 若用 HTTPS,建議提前配置
credential.helper避免交互
- 已安裝
推薦:在目標機器上部署統(tǒng)一的 deploy 用戶,并配置 Git 訪問權(quán)限。
使用步驟
- 修改
GIT_REPO_URL為你的倉庫地址(如git@github.com:org/repo.git) - 修改
LOCAL_PATH_ON_REMOTE(如/data/myapp) - 填寫
MACHINES列表(IP、端口、用戶名、密碼/None) - 確保 SSH 免密登錄已配置(或提供密碼)
- 運行腳本:
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
高級優(yōu)化建議
| 需求 | 方案 |
|---|---|
| 批量管理機器 | 從 YAML/JSON 文件讀取 MACHINES |
| 指定分支 | 在 git clone -b main 和 git pull origin main |
| 失敗重試 | 在 sync_to_machine 中加 retry 邏輯 |
| 日志分離 | 每臺機器輸出到獨立日志文件 |
| Ansible 替代 | 若環(huán)境復雜,可用 Ansible + git 模塊 |
此方案適用于 中小規(guī)模集群(幾十臺以內(nèi))。若超大規(guī)模,建議結(jié)合 配置管理工具(如 Ansible、SaltStack)。
如需我?guī)湍闵?YAML 配置版 或 支持 Git LFS/子模塊 的版本,請繼續(xù)提問!
以上就是使用Python腳本實現(xiàn)同一個Git倉庫在多個機房及多臺電腦上同時同步的詳細內(nèi)容,更多關(guān)于Python腳本同一個Git倉庫同時同步的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決Python 函數(shù)聲明先后順序出現(xiàn)的問題
這篇文章主要介紹了如何解決Python 函數(shù)聲明先后順序的問題,幫助大家更好的理解和學習python,感興趣的朋友可以了解下2020-09-09
Django中數(shù)據(jù)庫遷移常用的命令小結(jié)
在Django中數(shù)據(jù)庫遷移用于保持數(shù)據(jù)庫結(jié)構(gòu)與模型定義同步,這篇文章主要介紹了Django中數(shù)據(jù)庫遷移常用的命令,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2025-03-03
Python通過requests模塊實現(xiàn)抓取王者榮耀全套皮膚
只學書上的理論是遠遠不如實踐帶來的提升快,只有在實例中才能獲得能力的提升,本篇文章手把手帶你用Python實現(xiàn)抓取王者榮耀全套皮膚,大家可以在過程中查缺補漏,提升水平2021-10-10
Python打包成exe(windows)或者app(mac)實踐
文章主要介紹了使用pyinstaller將Python腳本打包成可執(zhí)行文件的步驟,包括在Windows和macOS上的操作方法,詳細解釋了命令參數(shù)的作用和使用方法2026-04-04

