2025-10-30 17:25:33 +08:00
#!/bin/bash
set -euo pipefail
# ========================== 固定配置 ==========================
TEMPLATE_URL = "http://116.205.97.109/scripts/kubeadm-conf.yaml" # 固定模板地址
LOCAL_TEMPLATE = " /tmp/k8s-template- $( date +%s) .yaml " # 本地临时模板
REMOTE_CONFIG_PATH = "/opt/k8s-install-conf/kubeadm-conf.yaml" # 远程配置路径
REMOTE_USER = "root" # 默认远程用户
2025-10-30 17:44:40 +08:00
# pause镜像相关配置
PAUSE_ALI_REGISTRY = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause" # 阿里云pause镜像
PAUSE_TARGET_REGISTRY = "registry.k8s.io/pause" # 目标pause镜像( 替换后)
2025-10-30 17:25:33 +08:00
# ========================== 工具函数 ==========================
RED = '\033[0;31m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
NC = '\033[0m'
info( ) { echo -e " ${ YELLOW } [INFO] ${ NC } $1 " ; }
success( ) { echo -e " ${ GREEN } [SUCCESS] ${ NC } $1 " ; }
error( ) { echo -e " ${ RED } [ERROR] ${ NC } $1 " ; exit 1; }
# ========================== 参数解析(简化版) ==========================
2025-10-30 17:44:40 +08:00
# 核心变量( target-ip = local-ip)
2025-10-30 17:25:33 +08:00
LOCALIP = "" # 节点IP( 同时作为目标服务器IP)
HOSTNAME = "" # 节点主机名
MASTER1_IP = "" # 第1个MASTER01_IP替换值
MASTER2_IP = "" # 第2个MASTER01_IP替换值
MASTER3_IP = "" # 第3个MASTER01_IP替换值
CLUSTER_VIP = "" # 集群VIP
K8SVERSION = "" # K8s版本
CLUSTER_PORT = "" # API端口
parse_args( ) {
while [ [ $# -gt 0 ] ] ; do
case " $1 " in
--local-ip)
LOCALIP = " $2 "
shift 2
; ;
--hostname)
HOSTNAME = " $2 "
shift 2
; ;
--master1-ip)
MASTER1_IP = " $2 "
shift 2
; ;
--master2-ip)
MASTER2_IP = " $2 "
shift 2
; ;
--master3-ip)
MASTER3_IP = " $2 "
shift 2
; ;
--cluster-vip)
CLUSTER_VIP = " $2 "
shift 2
; ;
--k8s-version)
K8SVERSION = " $2 "
shift 2
; ;
--cluster-port)
CLUSTER_PORT = " $2 "
shift 2
; ;
--remote-user)
REMOTE_USER = " $2 "
shift 2
; ;
--help)
echo " 用法: $0 [必选参数] [可选参数] "
2025-10-30 17:44:40 +08:00
echo "功能: 下载模板→替换变量→拷贝到服务器→拉取镜像→自动打pause镜像标签"
2025-10-30 17:25:33 +08:00
echo "必选参数:"
2025-10-30 17:44:40 +08:00
echo " --local-ip <IP> 节点IP( 目标服务器IP) | --hostname <名称> 节点主机名"
echo " --master1-ip <IP> 第1个MASTER01_IP | --master2-ip <IP> 第2个MASTER01_IP | --master3-ip <IP> 第3个MASTER01_IP"
echo " --cluster-vip <IP> 集群VIP | --k8s-version <版本> K8s版本 | --cluster-port <端口> API端口"
echo "可选参数:--remote-user <用户> 远程登录用户( 默认root) "
2025-10-30 17:25:33 +08:00
echo "示例:"
echo " $0 --local-ip 192.168.61.10 --hostname master-01 \\ "
echo " --master1-ip 192.168.61.10 --master2-ip 192.168.61.11 --master3-ip 192.168.61.12 \\"
echo " --cluster-vip 192.168.61.200 --k8s-version 1.30.5 --cluster-port 6443"
exit 0
; ;
*)
error " 未知参数: $1 (执行 $0 --help查看用法) "
; ;
esac
done
# 校验必选参数
2025-10-30 17:44:40 +08:00
local required_params = ( "LOCALIP" "HOSTNAME" "MASTER1_IP" "MASTER2_IP" "MASTER3_IP" "CLUSTER_VIP" "K8SVERSION" "CLUSTER_PORT" )
2025-10-30 17:25:33 +08:00
for param in " ${ required_params [@] } " ; do
2025-10-30 17:44:40 +08:00
[ [ -z " ${ !param } " ] ] && error " 缺少必选参数:-- ${ param ,, } "
2025-10-30 17:25:33 +08:00
done
2025-10-30 17:44:40 +08:00
# 校验格式
[ [ ! " $LOCALIP " = ~ ^[ 0-9] +\. [ 0-9] +\. [ 0-9] +\. [ 0-9] +$ ] ] && error " 无效local-ip: $LOCALIP "
[ [ ! " $CLUSTER_PORT " = ~ ^[ 0-9] +$ || " $CLUSTER_PORT " -lt 1 || " $CLUSTER_PORT " -gt 65535 ] ] && error " 无效端口: $CLUSTER_PORT "
2025-10-30 17:25:33 +08:00
}
# ========================== 核心步骤 ==========================
# 步骤1: 下载模板
download_template( ) {
info " 下载模板: $TEMPLATE_URL "
2025-10-30 17:44:40 +08:00
command -v wget & >/dev/null && wget -q -O " $LOCAL_TEMPLATE " " $TEMPLATE_URL " || \
command -v curl & >/dev/null && curl -s -o " $LOCAL_TEMPLATE " " $TEMPLATE_URL " || \
error "请安装wget或curl"
2025-10-30 17:25:33 +08:00
[ [ -f " $LOCAL_TEMPLATE " ] ] || error "模板下载失败"
success "模板下载完成"
}
2025-10-30 17:44:40 +08:00
# 步骤2: 替换模板变量
2025-10-30 17:25:33 +08:00
replace_variables( ) {
info "替换模板变量..."
2025-10-30 17:44:40 +08:00
# 基础变量
sed -i " s/LOCALIP/ $LOCALIP /g; s/HOSTNAME/ $HOSTNAME /g; s/K8SVERSION/ $K8SVERSION /g " " $LOCAL_TEMPLATE "
sed -i " s/CLUSTER_VIP/ $CLUSTER_VIP /g; s/CLUSTER_PORT/ $CLUSTER_PORT /g " " $LOCAL_TEMPLATE "
2025-10-30 17:25:33 +08:00
# 3个MASTER01_IP按顺序替换
2025-10-30 17:44:40 +08:00
sed -i " 0,/MASTER01_IP/s/MASTER01_IP/ $MASTER1_IP /; 0,/MASTER01_IP/s/MASTER01_IP/ $MASTER2_IP /; 0,/MASTER01_IP/s/MASTER01_IP/ $MASTER3_IP / " " $LOCAL_TEMPLATE "
2025-10-30 17:25:33 +08:00
# 替换CLUSTER_VIP:CLUSTER_PORT
2025-10-30 17:44:40 +08:00
sed -i " s/CLUSTER_VIP:CLUSTER_PORT/ ${ CLUSTER_VIP } : ${ CLUSTER_PORT } /g " " $LOCAL_TEMPLATE "
2025-10-30 17:25:33 +08:00
success "变量替换完成"
}
2025-10-30 17:44:40 +08:00
# 步骤3: 拷贝到目标服务器
2025-10-30 17:25:33 +08:00
copy_to_remote( ) {
2025-10-30 17:44:40 +08:00
info " 拷贝文件到 $REMOTE_USER @ $LOCALIP : $REMOTE_CONFIG_PATH "
2025-10-30 17:25:33 +08:00
# 远程创建目录
ssh -o StrictHostKeyChecking = no " $REMOTE_USER @ $LOCALIP " " mkdir -p $( dirname " $REMOTE_CONFIG_PATH " ) " || error "远程目录创建失败"
# SCP传输
scp -o StrictHostKeyChecking = no " $LOCAL_TEMPLATE " " $REMOTE_USER @ $LOCALIP : $REMOTE_CONFIG_PATH " || error "文件传输失败"
# 校验
2025-10-30 17:44:40 +08:00
ssh " $REMOTE_USER @ $LOCALIP " " test -f $REMOTE_CONFIG_PATH " || error "远程文件不存在"
success "文件拷贝成功"
2025-10-30 17:25:33 +08:00
}
2025-10-30 17:44:40 +08:00
# 步骤4: 远程执行命令( 拉取镜像 + 自动打pause标签)
2025-10-30 17:25:33 +08:00
execute_remote_commands( ) {
2025-10-30 17:44:40 +08:00
info " 在 $LOCALIP 执行远程操作... "
# 子步骤1: 拉取K8s镜像( 含pause镜像)
info " 拉取K8s镜像: kubeadm config images pull --config $REMOTE_CONFIG_PATH "
ssh " $REMOTE_USER @ $LOCALIP " " kubeadm config images pull --config $REMOTE_CONFIG_PATH " || error "镜像拉取失败"
success "K8s镜像拉取完成"
# 子步骤2: 获取阿里云pause镜像版本( 核心逻辑)
info " 获取阿里云pause镜像版本: $PAUSE_ALI_REGISTRY "
# 命令说明: 列出k8s.io命名空间的镜像 → 过滤阿里云pause → 提取版本号(格式:镜像名:版本 → 取:后的内容)
local pause_version
pause_version = $( ssh " $REMOTE_USER @ $LOCALIP " " nerdctl -n k8s.io images --format '{{.Repository}}:{{.Tag}}' | grep ' $PAUSE_ALI_REGISTRY ' | awk -F: '{print \$2}' | head -n1 " )
# 校验版本是否获取到
if [ [ -z " $pause_version " ] ] ; then
error " 未找到阿里云pause镜像( $PAUSE_ALI_REGISTRY ),请检查镜像拉取是否成功 "
fi
success " 获取到pause镜像版本: $pause_version "
# 子步骤3: 执行nerdctl tag命令( 替换仓库地址)
local ali_pause_full = " ${ PAUSE_ALI_REGISTRY } : ${ pause_version } "
local target_pause_full = " ${ PAUSE_TARGET_REGISTRY } : ${ pause_version } "
info " 执行打标签命令: nerdctl -n k8s.io tag $ali_pause_full $target_pause_full "
ssh " $REMOTE_USER @ $LOCALIP " " nerdctl -n k8s.io tag $ali_pause_full $target_pause_full " || error "pause镜像打标签失败"
success " pause镜像标签创建完成( $target_pause_full ) "
# 子步骤4: 验证标签是否创建成功
ssh " $REMOTE_USER @ $LOCALIP " " nerdctl -n k8s.io images | grep ' $PAUSE_TARGET_REGISTRY : $pause_version ' " & >/dev/null || \
error " 标签验证失败,未找到 $PAUSE_TARGET_REGISTRY : $pause_version "
success "pause镜像标签验证成功"
2025-10-30 17:25:33 +08:00
}
2025-10-30 17:44:40 +08:00
# 步骤5: 清理本地临时文件
2025-10-30 17:25:33 +08:00
cleanup( ) {
2025-10-30 17:44:40 +08:00
info " 清理本地临时文件: $LOCAL_TEMPLATE "
rm -f " $LOCAL_TEMPLATE " || info "本地文件清理失败,可手动删除"
2025-10-30 17:25:33 +08:00
}
# ========================== 主流程 ==========================
main( ) {
parse_args " $@ "
download_template
replace_variables
copy_to_remote
2025-10-30 17:44:40 +08:00
execute_remote_commands # 包含pause打标签逻辑
2025-10-30 17:25:33 +08:00
cleanup
echo -e " \n ${ GREEN } ======================================== "
2025-10-30 17:44:40 +08:00
echo -e " 全流程完成!目标服务器: $LOCALIP "
echo -e "已完成: 1. 模板部署 2. 镜像拉取 3. pause镜像标签替换"
echo -e " 下一步:执行 kubeadm init --config $REMOTE_CONFIG_PATH (主节点)或 join命令( 从节点) "
2025-10-30 17:25:33 +08:00
echo -e "========================================"
}
2025-10-30 17:44:40 +08:00
main " $@ "