ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

01 Paramiko 多机批量初始化实战:从手工运维到脚本化

01 Paramiko 多机批量初始化实战:从手工运维到脚本化 01 Paramiko 多机批量初始化实战从手工运维到脚本化摘要4 台华为云 ECS8C16G / 5Mbit从零开始用 Python Paramiko 并发框架 75 秒完成主机名、hosts 互信、时区、内核参数、Docker Containerd 安装与 SSH 免密配置告别逐台手工敲命令。一、背景与目标企业里买了一批新服务器要初始化是很常见的场景设置主机名、写 /etc/hosts、同步时区、调内核参数、装 Docker、配 SSH 免密……一台一台手工 SSH 上去敲命令4 台也许 40 分钟40 台就是 400 分钟还容易漏步骤、敲错字。本文记录一次真实的 4 节点批量初始化实践只用 Python Paramiko 写一个并发执行框架把初始化脚本一次性下发到所有机器并执行全程 75 秒完成且脚本幂等重复执行不报错、不重复安装可复现、可留证。二、环境说明项目值云厂商华为云 ECS规格8 vCPU / 16 GiB / 40G 系统盘系统Ubuntu 24.04.4 LTS (kernel 6.8.0-106-generic)带宽5 Mbit/s 弹性公网 IP客户端Windows 11 Python 3.13 Paramiko 5.0节点数41 控制 2 K8s Worker 1 监控版本清单Docker 29.1.3docker.io 包自带、Containerd 2.2.1、Python 3.13.13、Paramiko 5.0.0、Git 2.55.0。三、架构设计本地编排机Orchestrator: Python ParamikoThreadPoolExecutor 4 并发ecs-0001Master 120.46.211.233ecs-0002Worker 1.92.137.234ecs-0003Worker 119.3.218.198ecs-0004监控节点 1.92.92.140init_node.sh 下发init_node.sh 下发init_node.sh 下发init_node.sh 下发日志落盘 logs/日志落盘 logs/日志落盘 logs/日志落盘 logs/初始化脚本职责划分单机幂等主机名hostnamectl set-hostname 写入 /etc/hostname/etc/hosts写入 4 台私有 IP ↔ 主机名映射grep 去重时区/时间同步Asia/Shanghai chronyapt 源加速替换为阿里云镜像关键国内 apt 默认源很慢内核参数/etc/sysctl.d/99-k8s.confK8s 网络要求关闭 swapswapoff -a 注释 fstabK8s 硬性要求Docker Containerddocker.io 包安装 国内镜像加速 daemon.json systemd 托管基础工具curl / wget / vim / htop / jq 等四、实操步骤4.1 环境准备# Windows 本机: 安装 paramikopython-m pip install paramiko# 凭据通过环境变量注入(不写入任何脚本)$env:ECS_PASSWORD ******# 实际从 .credentials.local 读取安全原则密码/Token 一律走环境变量或 gitignore 的本地文件绝不写进代码和日志。4.2 单机初始化脚本 init_node.sh节选# 主机名 hosts 互信hostnamectl set-hostname$TARGET_HOSTHOSTS_MAP192.168.0.16 ecs-5c2d-6542-0001 192.168.0.77 ecs-5c2d-6542-0002 192.168.0.33 ecs-5c2d-6542-0003 192.168.0.12 ecs-5c2d-6542-0004echo$HOSTS_MAP|whileread-ripname;dogrep-qE[[:space:]]$name\$/etc/hosts||echo$ip$name/etc/hostsdone# apt 源切换阿里云(幂等: 仅当还是默认源时替换)ifgrep-qEarchive\.ubuntu\.com|security\.ubuntu\.com/etc/apt/sources.list.d/ubuntu.sources2/dev/null;thensed-is|http://archive.ubuntu.com/ubuntu/|https://mirrors.aliyun.com/ubuntu/|g; .../etc/apt/sources.list.d/ubuntu.sourcesfi# 内核参数 关闭 swapcat/etc/sysctl.d/99-k8s.confEOF net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1 vm.swappiness 0 EOFsysctl--systemswapoff -a;sed-i/swap/s/^/#//etc/fstab# Docker 镜像加速apt-getinstall-ydocker.io containerdcat/etc/docker/daemon.jsonEOF { registry-mirrors: [https://docker.m.daocloud.io, https://mirror.ccs.tencentyun.com], exec-opts: [native.cgroupdriversystemd], storage-driver: overlay2 } EOFsystemctlenable--nowdocker完整脚本见仓库scripts/init_node.sh。4.3 并发执行框架 batch_init.py核心fromconcurrent.futuresimportThreadPoolExecutor,as_completedimportparamikodefrun_one(name,ip,password):clientparamiko.SSHClient()client.set_missing_host_key_policy(paramiko.AutoAddPolicy())client.connect(ip,22,usernameroot,passwordpassword,timeout20)sftpclient.open_sftp()sftp.put(SCRIPT,/root/init_node.sh)# 脚本先行: 先上传再执行sftp.close()_in,out,errclient.exec_command(fbash /root/init_node.sh{name},timeout1200,get_ptyTrue)# 流式读取输出, 落盘 logs/P0-1-init-host.log...withThreadPoolExecutor(max_workers4)aspool:# 4 台并发futs{pool.submit(run_one,n,ip,password):nforn,ipinHOSTS}要点exec_command 流式读取不等待命令结束再统一读防止管道缓冲撑爆、每台独立日志文件、异常捕获不中断其他节点。4.4 执行与结果 batch_init 总耗时 75.1s ecs-5c2d-6542-0004: OK docker29.1.3 containerd 2.2.1 ecs-5c2d-6542-0002: OK docker29.1.3 containerd 2.2.1 ecs-5c2d-6542-0003: OK docker29.1.3 containerd 2.2.1 ecs-5c2d-6542-0001: OK docker29.1.3 containerd 2.2.14 台机器并发初始化75.1 秒完成含 apt 源切换后的全量 update 与 Docker 安装。4.5 SSH 免密互通在 master 生成 ed25519 密钥公钥并发分发到 4 台最后从 master 走私有 IP 验证192.168.0.16 - ecs-5c2d-6542-0001 192.168.0.77 - ecs-5c2d-6542-0002 192.168.0.33 - ecs-5c2d-6542-0003 192.168.0.12 - ecs-5c2d-6542-0004五、效果验证✅ 4 台机器 SSH 连通性探测全部 OK首次脚本化探测输出见logs/00-connectivity.log✅ 主机名 / /etc/hosts / 时区 / 内核参数一次到位✅ Docker 29.1.3 Containerd 2.2.1 全部就绪docker version、containerd --version回显验证✅ master → 4 节点私有 IP SSH 免密全部成功✅ 整体耗时 75.1s单机 44~50s并发 4 台 vs 串行约 3 分钟六、踩坑与解决方案坑 1PowerShell 执行策略禁止运行 .ps1现象 load-creds.ps1报UnauthorizedAccess凭据没加载。原因Windows PowerShell 默认Restricted执行策略。解决放弃 .ps1改为在每个命令前内联读取凭据文件并Set-Item Env:...一行搞定。坑 2环境变量不跨 bash 工具会话现象上一条命令$env:ECS_PASSWORDxxx下一条命令 Python 里读不到。原因每次命令调用是新的 shell 会话环境变量不持久。解决把从 .credentials.local 加载 → 注入当前会话做成统一前缀每个脚本执行前先加载。坑 3本机连不到私有 IP现象公钥分发时全部timed out。原因分发脚本误用私有 IP192.168.0.x从 Windows 本机连接——本机根本不在那个内网。解决区分本机→服务器用公网 IP连接服务器间互访才用私有 IP由 master 验证。七、总结与延伸脚本先行是批量运维的第一原则任何变更先落脚本可复现、可审计、可回滚。并发是效率的倍增器4 台串行约 4 分钟线程池并发 75 秒规模化后收益更明显。幂等是脚本的底线每步都做存在则跳过判断误操作重跑也安全。延伸方向把初始化脚本升级为 Ansible Playbook 或 Shell 模板引擎支持 40 台机器把凭据改为 SSH Key 免密登录彻底告别密码传输本框架已为下一篇《Ubuntu 24.04 手把手部署 K8s 集群》铺好了地基。配套源码https://gitcode.com/cpyaxjq/k8s-ai-ops scripts/、deploy/、logs/
返回列表