parent
98b9ce7901
commit
a5f1d76beb
|
|
@ -1,89 +1,186 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# 校验是否为root用户执行
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "错误:脚本需以root权限执行"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 初始化参数变量
|
||||
# -------------------------- 全局变量定义 --------------------------
|
||||
master_ips=""
|
||||
node_ips=""
|
||||
target_dir="/opt/k8s-install-conf"
|
||||
CERT_KEY=""
|
||||
JOIN_CMD_BASE=""
|
||||
|
||||
# 解析命令行参数
|
||||
# -------------------------- 基础工具函数 --------------------------
|
||||
# 打印分隔符
|
||||
print_separator() {
|
||||
echo "========================================================================"
|
||||
}
|
||||
|
||||
# 打印子分隔符
|
||||
print_sub_separator() {
|
||||
echo "------------------------------------------------------------------------"
|
||||
}
|
||||
|
||||
# 自动等待5秒(替代手动确认)
|
||||
auto_wait() {
|
||||
echo "等待5秒后继续下一步..."
|
||||
sleep 5
|
||||
echo
|
||||
}
|
||||
|
||||
# -------------------------- 步骤函数:参数解析与校验 --------------------------
|
||||
parse_and_validate_args() {
|
||||
print_separator
|
||||
echo "【步骤1/7】解析命令行参数与前置校验"
|
||||
print_sub_separator
|
||||
|
||||
# 解析参数(支持 --master-ips=xxx 和 --master-ips xxx 两种格式)
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--master-ips=*)
|
||||
master_ips="${1#*=}"
|
||||
echo "已指定Master节点IP列表:$master_ips"
|
||||
shift 1
|
||||
;;
|
||||
--master-ips)
|
||||
master_ips="$2"
|
||||
echo "已指定Master节点IP列表:$master_ips"
|
||||
shift 2
|
||||
;;
|
||||
--node-ips=*)
|
||||
node_ips="${1#*=}"
|
||||
echo "已指定Node节点IP列表:$node_ips"
|
||||
shift 1
|
||||
;;
|
||||
--node-ips)
|
||||
node_ips="$2"
|
||||
echo "已指定Node节点IP列表:$node_ips"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
echo "错误:未知参数 $1"
|
||||
echo "使用方式:$0 --master-ips 192.168.61.131,192.168.61.132 --node-ips 192.168.61.134"
|
||||
echo "使用方式:$0 --master-ips=192.168.61.131,192.168.61.132 --node-ips=192.168.61.134"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 校验参数是否完整
|
||||
# 校验参数完整性
|
||||
if [ -z "$master_ips" ] && [ -z "$node_ips" ]; then
|
||||
echo "错误:必须指定 --master-ips 或 --node-ips"
|
||||
echo "使用方式:$0 --master-ips 192.168.61.131,192.168.61.132 --node-ips 192.168.61.134"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 定义目标目录
|
||||
target_dir="/opt/k8s-install-conf"
|
||||
|
||||
# 校验kubeadm-conf.yaml是否存在
|
||||
if [ ! -f "/opt/k8s-install-conf/kubeadm-conf.yaml" ]; then
|
||||
# 校验kubeadm-conf.yaml文件
|
||||
echo "校验kubeadm-conf.yaml配置文件..."
|
||||
if [ ! -f "${target_dir}/kubeadm-conf.yaml" ]; then
|
||||
echo "错误:当前目录未找到 kubeadm-conf.yaml 配置文件"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ 已找到kubeadm-conf.yaml配置文件"
|
||||
|
||||
|
||||
# -------------------------- 第一步:初始化第一台Master节点 --------------------------
|
||||
echo "=== 开始初始化第一台Master节点 ==="
|
||||
|
||||
# 执行kubeadm初始化(带证书上传)
|
||||
echo "执行 kubeadm init 初始化集群..."
|
||||
kubeadm init --config ${target_dir}/kubeadm-conf.yaml --upload-certs
|
||||
|
||||
# 配置当前用户kubeconfig
|
||||
echo "配置当前用户kubeconfig..."
|
||||
mkdir -p "$HOME/.kube"
|
||||
cp -i /etc/kubernetes/admin.conf "$HOME/.kube/config"
|
||||
chown "$(id -u):$(id -g)" "$HOME/.kube/config"
|
||||
export KUBECONFIG=/etc/kubernetes/admin.conf
|
||||
# 将环境变量写入profile,永久生效
|
||||
echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> "$HOME/.profile"
|
||||
|
||||
echo "=== 第一台Master节点初始化完成 ==="
|
||||
|
||||
# -------------------------- 第二步:生成添加节点的脚本 --------------------------
|
||||
echo "=== 开始生成添加节点脚本 ==="
|
||||
|
||||
# 创建目标目录
|
||||
mkdir -p "$target_dir"
|
||||
|
||||
# 生成certificate-key和基础join命令
|
||||
echo "生成集群加入所需参数..."
|
||||
CERT_KEY=$(kubeadm init phase upload-certs --upload-certs 2>/dev/null | grep -E '^[0-9a-f]{64,}$')
|
||||
JOIN_CMD_BASE=$(kubeadm token create --print-join-command 2>/dev/null)
|
||||
|
||||
# 校验参数生成结果
|
||||
if [ -z "$CERT_KEY" ] || [ -z "$JOIN_CMD_BASE" ]; then
|
||||
echo "错误:生成集群加入参数失败"
|
||||
# 校验root权限
|
||||
echo "校验执行权限..."
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "错误:脚本需以root权限执行"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ root权限校验通过"
|
||||
|
||||
# 生成添加Master节点的脚本(包含kubeconfig配置)
|
||||
echo "生成 $target_dir/add_master.sh ..."
|
||||
print_separator
|
||||
auto_wait
|
||||
}
|
||||
|
||||
# -------------------------- 步骤函数:初始化第一台Master --------------------------
|
||||
init_first_master() {
|
||||
print_separator
|
||||
echo "【步骤2/7】初始化第一台Master节点"
|
||||
print_sub_separator
|
||||
|
||||
# 执行kubeadm init
|
||||
echo "执行集群初始化命令:kubeadm init --config ${target_dir}/kubeadm-conf.yaml --upload-certs"
|
||||
kubeadm init --config ${target_dir}/kubeadm-conf.yaml --upload-certs
|
||||
echo "✓ kubeadm init 执行完成"
|
||||
print_sub_separator
|
||||
|
||||
# 配置kubeconfig
|
||||
echo "配置当前用户kubeconfig..."
|
||||
echo "命令1:mkdir -p $HOME/.kube"
|
||||
mkdir -p "$HOME/.kube"
|
||||
echo "命令2:cp -i /etc/kubernetes/admin.conf $HOME/.kube/config"
|
||||
cp -i /etc/kubernetes/admin.conf "$HOME/.kube/config"
|
||||
echo "命令3:chown $(id -u):$(id -g) $HOME/.kube/config"
|
||||
chown "$(id -u):$(id -g)" "$HOME/.kube/config"
|
||||
echo "命令4:export KUBECONFIG=/etc/kubernetes/admin.conf"
|
||||
export KUBECONFIG=/etc/kubernetes/admin.conf
|
||||
echo "命令5:echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> $HOME/.profile"
|
||||
echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> "$HOME/.profile"
|
||||
echo "✓ kubeconfig配置完成(已永久写入环境变量)"
|
||||
|
||||
print_separator
|
||||
auto_wait
|
||||
}
|
||||
|
||||
# -------------------------- 步骤函数:安装Calico网络插件 --------------------------
|
||||
install_calico() {
|
||||
print_separator
|
||||
echo "【步骤3/7】安装Calico网络插件"
|
||||
print_sub_separator
|
||||
|
||||
# 创建目标目录
|
||||
echo "创建配置文件目录:mkdir -p $target_dir"
|
||||
mkdir -p "$target_dir"
|
||||
echo "✓ 目录创建成功"
|
||||
print_sub_separator
|
||||
|
||||
# 下载Calico配置
|
||||
echo "下载Calico配置文件:wget -q -c -O $target_dir/calico.yaml http://116.205.97.109/scripts/calico.yaml --show-progress"
|
||||
wget -q -c -O "$target_dir/calico.yaml" http://116.205.97.109/scripts/calico.yaml --show-progress
|
||||
echo "✓ Calico配置文件下载完成"
|
||||
print_sub_separator
|
||||
|
||||
# 应用Calico配置
|
||||
echo "部署Calico网络插件:kubectl apply -f $target_dir/calico.yaml"
|
||||
kubectl apply -f "$target_dir/calico.yaml"
|
||||
echo "✓ Calico配置已提交至集群"
|
||||
print_sub_separator
|
||||
|
||||
# 查看节点状态
|
||||
echo "当前节点状态(网络插件部署中,状态可能为NotReady):"
|
||||
kubectl get node
|
||||
echo
|
||||
echo "提示:Calico组件需2-5分钟部署完成,请耐心等待"
|
||||
echo "部署完成后可执行:kubectl get node 验证节点状态(目标状态为Ready)"
|
||||
|
||||
print_separator
|
||||
auto_wait
|
||||
}
|
||||
|
||||
# -------------------------- 步骤函数:生成节点加入脚本 --------------------------
|
||||
generate_join_scripts() {
|
||||
print_separator
|
||||
echo "【步骤4/7】生成Master/Node节点加入脚本"
|
||||
print_sub_separator
|
||||
|
||||
# 生成证书密钥和基础加入命令
|
||||
echo "生成集群加入核心参数..."
|
||||
echo "命令1:kubeadm init phase upload-certs --upload-certs(刷新证书)"
|
||||
CERT_KEY=$(kubeadm init phase upload-certs --upload-certs 2>/dev/null | grep -E '^[0-9a-f]{64,}$')
|
||||
if [ -z "$CERT_KEY" ]; then
|
||||
echo "错误:生成certificate-key失败"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ certificate-key 生成完成"
|
||||
|
||||
echo "命令2:kubeadm token create --print-join-command(生成基础加入命令)"
|
||||
JOIN_CMD_BASE=$(kubeadm token create --print-join-command 2>/dev/null)
|
||||
if [ -z "$JOIN_CMD_BASE" ]; then
|
||||
echo "错误:生成join命令失败"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ 基础join命令(含token+CA哈希)生成完成"
|
||||
print_sub_separator
|
||||
|
||||
# 生成Master加入脚本
|
||||
echo "生成Master节点加入脚本:$target_dir/add_master.sh"
|
||||
cat > "$target_dir/add_master.sh" <<EOF
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
|
@ -100,9 +197,11 @@ echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> \$HOME/.profile
|
|||
|
||||
echo "Master节点加入集群并配置完成"
|
||||
EOF
|
||||
echo "✓ add_master.sh 生成完成"
|
||||
print_sub_separator
|
||||
|
||||
# 生成添加Node节点的脚本
|
||||
echo "生成 $target_dir/add_node.sh ..."
|
||||
# 生成Node加入脚本
|
||||
echo "生成Node节点加入脚本:$target_dir/add_node.sh"
|
||||
cat > "$target_dir/add_node.sh" <<EOF
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
|
@ -112,14 +211,20 @@ $JOIN_CMD_BASE
|
|||
|
||||
echo "Node节点加入集群完成"
|
||||
EOF
|
||||
echo "✓ add_node.sh 生成完成"
|
||||
print_sub_separator
|
||||
|
||||
# 赋予脚本执行权限
|
||||
# 赋予执行权限
|
||||
echo "赋予脚本执行权限:chmod +x $target_dir/add_master.sh $target_dir/add_node.sh"
|
||||
chmod +x "$target_dir/add_master.sh" "$target_dir/add_node.sh"
|
||||
echo "✓ 脚本执行权限配置完成"
|
||||
|
||||
echo "=== 添加节点脚本生成完成 ==="
|
||||
print_separator
|
||||
auto_wait
|
||||
}
|
||||
|
||||
# -------------------------- 第三步:定义通用工具函数 --------------------------
|
||||
# 免密登录验证函数
|
||||
# -------------------------- 辅助函数:远程操作工具 --------------------------
|
||||
# 免密登录验证
|
||||
check_ssh_auth() {
|
||||
local ip="$1"
|
||||
echo "验证 $ip 免密登录..."
|
||||
|
|
@ -127,63 +232,125 @@ check_ssh_auth() {
|
|||
echo "错误:$ip 免密登录失败,请先配置SSH免密登录"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ $ip 免密登录验证通过"
|
||||
}
|
||||
|
||||
# 拷贝脚本到远程节点函数
|
||||
copy_script() {
|
||||
# 拷贝脚本到远程节点
|
||||
copy_remote_script() {
|
||||
local ip="$1"
|
||||
local script_path="$2"
|
||||
echo "拷贝脚本到 $ip ..."
|
||||
local script_name=$(basename "$script_path")
|
||||
echo "拷贝 $script_name 到 $ip:/tmp/..."
|
||||
scp -o StrictHostKeyChecking=no "$script_path" "$ip:/tmp/"
|
||||
echo "✓ $script_name 拷贝完成"
|
||||
}
|
||||
|
||||
# 远程执行脚本函数
|
||||
# 远程执行脚本并清理
|
||||
run_remote_script() {
|
||||
local ip="$1"
|
||||
local script_name="$2"
|
||||
echo "在 $ip 执行 $script_name ..."
|
||||
echo "在 $ip 执行脚本:bash /tmp/$script_name"
|
||||
ssh -o StrictHostKeyChecking=no "$ip" "bash /tmp/$script_name"
|
||||
# 执行完成后删除远程临时脚本
|
||||
echo "✓ $ip 脚本执行完成"
|
||||
echo "清理 $ip 临时脚本:rm -f /tmp/$script_name"
|
||||
ssh -o StrictHostKeyChecking=no "$ip" "rm -f /tmp/$script_name"
|
||||
echo "✓ $ip 临时脚本清理完成"
|
||||
}
|
||||
|
||||
# -------------------------- 第四步:处理Master节点加入 --------------------------
|
||||
if [ -n "$master_ips" ]; then
|
||||
echo -e "\n=== 开始处理Master节点加入 ==="
|
||||
# 分割IP列表(处理逗号分隔,去除空格)
|
||||
# -------------------------- 步骤函数:处理远程Master节点 --------------------------
|
||||
process_remote_masters() {
|
||||
if [ -z "$master_ips" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
print_separator
|
||||
echo "【步骤5/7】部署远程Master节点"
|
||||
print_sub_separator
|
||||
|
||||
local master_count=$(echo "$master_ips" | tr ',' '\n' | wc -l)
|
||||
echo "待部署Master节点数量:$master_count"
|
||||
print_sub_separator
|
||||
|
||||
# 分割IP列表(兼容空格)
|
||||
IFS=',' read -ra master_ip_arr <<< "$(echo "$master_ips" | tr -d ' ')"
|
||||
|
||||
for ip in "${master_ip_arr[@]}"; do
|
||||
echo -e "\n--- 处理Master节点:$ip ---"
|
||||
# 验证免密
|
||||
echo -e "\n--- 开始处理Master节点:$ip ---"
|
||||
check_ssh_auth "$ip"
|
||||
# 拷贝脚本
|
||||
copy_script "$ip" "$target_dir/add_master.sh"
|
||||
# 远程执行
|
||||
copy_remote_script "$ip" "$target_dir/add_master.sh"
|
||||
run_remote_script "$ip" "add_master.sh"
|
||||
echo "--- Master节点 $ip 处理完成 ---"
|
||||
echo "--- Master节点 $ip 部署完成 ---"
|
||||
auto_wait # 单个节点处理完成后等待5秒
|
||||
done
|
||||
|
||||
echo -e "\n✓ 所有Master节点部署完成"
|
||||
print_separator
|
||||
auto_wait
|
||||
}
|
||||
|
||||
# -------------------------- 步骤函数:处理远程Node节点 --------------------------
|
||||
process_remote_nodes() {
|
||||
if [ -z "$node_ips" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# -------------------------- 第五步:处理Node节点加入 --------------------------
|
||||
if [ -n "$node_ips" ]; then
|
||||
echo -e "\n=== 开始处理Node节点加入 ==="
|
||||
# 分割IP列表(处理逗号分隔,去除空格)
|
||||
print_separator
|
||||
echo "【步骤6/7】部署远程Node节点"
|
||||
print_sub_separator
|
||||
|
||||
local node_count=$(echo "$node_ips" | tr ',' '\n' | wc -l)
|
||||
echo "待部署Node节点数量:$node_count"
|
||||
print_sub_separator
|
||||
|
||||
# 分割IP列表(兼容空格)
|
||||
IFS=',' read -ra node_ip_arr <<< "$(echo "$node_ips" | tr -d ' ')"
|
||||
|
||||
for ip in "${node_ip_arr[@]}"; do
|
||||
echo -e "\n--- 处理Node节点:$ip ---"
|
||||
# 验证免密
|
||||
echo -e "\n--- 开始处理Node节点:$ip ---"
|
||||
check_ssh_auth "$ip"
|
||||
# 拷贝脚本
|
||||
copy_script "$ip" "$target_dir/add_node.sh"
|
||||
# 远程执行
|
||||
copy_remote_script "$ip" "$target_dir/add_node.sh"
|
||||
run_remote_script "$ip" "add_node.sh"
|
||||
echo "--- Node节点 $ip 处理完成 ---"
|
||||
echo "--- Node节点 $ip 部署完成 ---"
|
||||
auto_wait # 单个节点处理完成后等待5秒
|
||||
done
|
||||
fi
|
||||
|
||||
# -------------------------- 第六步:执行结果提示 --------------------------
|
||||
echo -e "\n=== 所有节点处理完成 ==="
|
||||
echo "验证集群节点状态命令:kubectl get nodes"
|
||||
echo "验证控制平面组件状态命令:kubectl get pods -n kube-system -l component=kube-apiserver,kube-controller-manager,kube-scheduler"
|
||||
echo -e "\n✓ 所有Node节点部署完成"
|
||||
print_separator
|
||||
auto_wait
|
||||
}
|
||||
|
||||
# -------------------------- 步骤函数:输出最终提示 --------------------------
|
||||
print_final_tips() {
|
||||
print_separator
|
||||
echo "【步骤7/7】部署完成 - 后续验证建议"
|
||||
print_sub_separator
|
||||
echo "1. 查看集群节点状态(所有节点最终状态需为Ready):"
|
||||
echo " kubectl get nodes"
|
||||
echo
|
||||
echo "2. 查看控制平面组件状态(需全部Running):"
|
||||
echo " kubectl get pods -n kube-system -l component=kube-apiserver,kube-controller-manager,kube-scheduler"
|
||||
echo
|
||||
echo "3. 查看Calico网络组件状态(需全部Running):"
|
||||
echo " kubectl get pods -n kube-system -l k8s-app=calico-node"
|
||||
echo
|
||||
echo "4. 测试集群可用性(创建测试Pod):"
|
||||
echo " kubectl run test-pod --image=nginx:alpine && kubectl delete pod test-pod"
|
||||
print_separator
|
||||
echo "🎉 Kubernetes集群部署全流程完成!"
|
||||
print_separator
|
||||
}
|
||||
|
||||
# -------------------------- 主函数:按顺序执行所有步骤 --------------------------
|
||||
main() {
|
||||
# 按流程调用各步骤函数
|
||||
parse_and_validate_args "$@"
|
||||
init_first_master
|
||||
install_calico
|
||||
generate_join_scripts
|
||||
process_remote_masters
|
||||
process_remote_nodes
|
||||
print_final_tips
|
||||
}
|
||||
|
||||
# 启动主函数(传递所有命令行参数)
|
||||
main "$@"
|
||||
Loading…
Reference in New Issue