2025-11-08 15:24:10 +08:00
#!/bin/bash
2025-11-08 15:59:01 +08:00
# 去掉set -e, 避免一步失败直接退出, 改为手动控制退出
set -uo pipefail
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# ===================== 核心配置 =====================
2025-11-08 15:33:42 +08:00
NFS_TAR_URL = "http://116.205.97.109/scripts/nfs-subdir-external-provisioner.tgz"
2025-11-08 15:24:10 +08:00
TARGET_DIR = "/opt/k8s-install-conf"
2025-11-08 15:59:01 +08:00
NAMESPACE = "default"
POD_LABEL = "app=nfs-client-provisioner"
SC_NAME = "nfs-client"
2025-11-08 15:24:10 +08:00
NFS_SERVER = ""
SHARE_DIR = ""
2025-11-08 15:59:01 +08:00
# ===================== 日志输出(增加步骤编号)=====================
info( ) { echo -e " \n\033[34m[INFO] 🔧 $1 \033[0m " ; }
success( ) { echo -e " \033[32m[SUCCESS] ✅ $1 \033[0m " ; }
error( ) { echo -e " \033[31m[ERROR] ❌ $1 \033[0m " >& 2; exit 1; }
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# ===================== 参数解析(增加调试)=====================
2025-11-08 15:24:10 +08:00
parse_args( ) {
2025-11-08 15:59:01 +08:00
info "步骤1/7: 解析命令行参数"
2025-11-08 15:24:10 +08:00
while [ [ $# -gt 0 ] ] ; do
case " $1 " in
2025-11-08 15:59:01 +08:00
--nfs-server) NFS_SERVER = " $2 " ; shift 2 ; ;
--share-dirs) SHARE_DIR = " $2 " ; shift 2 ; ;
--help) echo " 用法: $0 --nfs-server <NFS_IP> --share-dirs <共享目录> " ; exit 0 ; ;
*) error " 不支持参数: $1 ,使用--help查看用法 " ; ;
2025-11-08 15:24:10 +08:00
esac
done
2025-11-08 15:59:01 +08:00
# 校验参数(明确提示缺失项)
if [ [ -z " ${ NFS_SERVER } " ] ] ; then error "缺少必传参数:--nfs-server <NFS服务器IP>" ; fi
if [ [ -z " ${ SHARE_DIR } " ] ] ; then error "缺少必传参数:--share-dirs <NFS共享目录>" ; fi
if ! [ [ " ${ NFS_SERVER } " = ~ ^[ 0-9] +\. [ 0-9] +\. [ 0-9] +\. [ 0-9] +$ ] ] ; then error "NFS IP格式错误( 示例: 192.168.1.100) " ; fi
if ! [ [ " ${ SHARE_DIR } " = ~ ^/ ] ] ; then error "共享目录必须是绝对路径(示例:/data/nfs) " ; fi
success " 参数解析完成: NFS_SERVER= ${ NFS_SERVER } , SHARE_DIR=${ SHARE_DIR } "
2025-11-08 15:24:10 +08:00
}
2025-11-08 15:59:01 +08:00
# ===================== 前置检查(增加超时和详细输出)=====================
2025-11-08 15:24:10 +08:00
pre_check( ) {
2025-11-08 15:59:01 +08:00
info "步骤2/7: 前置环境检查"
# 权限检查
if [ [ " $( id -u) " -ne 0 ] ] ; then error "请用root用户执行( sudo -i 切换)" ; fi
success "✅ 权限检查通过"
# kubectl检查
if ! command -v kubectl & > /dev/null; then error "未安装kubectl, 请手动安装后重试" ; fi
success "✅ kubectl已安装"
if ! kubectl cluster-info & > /dev/null; then error "kubectl无法连接K8s集群, 请检查kubeconfig配置" ; fi
success "✅ kubectl集群连接正常"
# 依赖工具检查
local tools = ( "wget" "tar" "sed" )
for tool in " ${ tools [@] } " ; do
if ! command -v " ${ tool } " & > /dev/null; then error " 缺少依赖工具: ${ tool } , 请手动安装( apt install ${ tool } 或 yum install ${ tool } ) " ; fi
2025-11-08 15:24:10 +08:00
done
2025-11-08 15:59:01 +08:00
success "✅ 所有依赖工具已安装"
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# 部署包可达性检查( 增加超时10秒)
info " 正在检查部署包可达性: ${ NFS_TAR_URL } "
if ! wget --spider --timeout= 10 " ${ NFS_TAR_URL } " & > /dev/null; then
error "部署包不可访问! 请检查: 1) 网络是否能通该地址 2) 包是否存在 3) 防火墙是否放行"
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
success "✅ 部署包可达性检查通过"
2025-11-08 15:24:10 +08:00
}
2025-11-08 15:59:01 +08:00
# ===================== 下载解压(增加进度和错误提示)=====================
2025-11-08 15:24:10 +08:00
download_and_extract( ) {
2025-11-08 15:59:01 +08:00
info "步骤3/7: 下载部署包"
local tmp_tar = "/tmp/nfs.tgz"
# 下载( 显示进度, 超时30秒)
if ! wget -q --show-progress --timeout= 30 -O " ${ tmp_tar } " " ${ NFS_TAR_URL } " ; then
error "部署包下载失败!可能原因:网络超时、地址错误、包不存在"
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
success " ✅ 部署包下载完成(保存到: ${ tmp_tar } ) "
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
info " 步骤4/7: 解压部署包到 ${ TARGET_DIR } "
mkdir -p " ${ TARGET_DIR } " || error " 创建目标目录失败: ${ TARGET_DIR } (权限不足?) "
if ! tar -zxf " ${ tmp_tar } " -C " ${ TARGET_DIR } " ; then
error "解压失败!可能原因:压缩包损坏、权限不足"
fi
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# 校验核心文件
local deploy_dir = " ${ TARGET_DIR } /nfs-subdir-external-provisioner/deploy "
local required_files = ( "rbac.yaml" "class.yaml" "deployment.yaml" )
2025-11-08 15:24:10 +08:00
for file in " ${ required_files [@] } " ; do
2025-11-08 15:59:01 +08:00
if ! [ [ -f " ${ deploy_dir } / ${ file } " ] ] ; then
error " 解压后缺失核心文件: ${ deploy_dir } / ${ file } (压缩包损坏?) "
2025-11-08 15:24:10 +08:00
fi
done
2025-11-08 15:59:01 +08:00
success " ✅ 解压完成,部署文件路径: ${ deploy_dir } "
2025-11-08 15:24:10 +08:00
}
2025-11-08 15:59:01 +08:00
# ===================== 替换配置(增加文件存在性检查)=====================
replace_config( ) {
info "步骤5/7: 替换NFS配置"
local deploy_dir = " ${ TARGET_DIR } /nfs-subdir-external-provisioner/deploy "
local dep_file = " ${ deploy_dir } /deployment.yaml "
if ! [ [ -f " ${ dep_file } " ] ] ; then error " 未找到配置文件: ${ dep_file } " ; fi
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# 替换环境变量(显示替换前后的对比)
2025-11-08 17:03:11 +08:00
info "env替换前: NFS_SERVER=10.3.243.101, SHARE_DIR=/ifs/kubernetes"
2025-11-08 15:59:01 +08:00
info " 替换后: NFS_SERVER= ${ NFS_SERVER } , SHARE_DIR=${ SHARE_DIR } "
if ! sed -i " s#value: 10.3.243.101#value: ${ NFS_SERVER } #g " " ${ dep_file } " ; then
error "替换NFS_SERVER失败( 文件权限不足? ) "
fi
if ! sed -i " s#value: /ifs/kubernetes#value: ${ SHARE_DIR } #g " " ${ dep_file } " ; then
error "替换共享目录失败(文件权限不足?)"
2025-11-08 15:24:10 +08:00
fi
2025-11-08 17:03:11 +08:00
# 替换环境变量(显示替换前后的对比)
info "volumes替换前: NFS_SERVER=10.3.243.101, SHARE_DIR=/ifs/kubernetes"
info " 替换后: NFS_SERVER= ${ NFS_SERVER } , SHARE_DIR=${ SHARE_DIR } "
if ! sed -i " s#server: 10.3.243.101#server: ${ NFS_SERVER } #g " " ${ dep_file } " ; then
error "替换NFS_SERVER失败( 文件权限不足? ) "
fi
if ! sed -i " s#path: /ifs/kubernetes#path: ${ SHARE_DIR } #g " " ${ dep_file } " ; then
error "替换共享目录失败(文件权限不足?)"
fi
2025-11-10 08:56:38 +08:00
if ! sed -i 's#registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2#swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2#' " ${ dep_file } " ; then
error "修改国内加速镜像失败!"
fi
2025-11-08 15:24:10 +08:00
# 验证替换结果
2025-11-08 15:59:01 +08:00
if ! grep -q " value: ${ NFS_SERVER } " " ${ dep_file } " || ! grep -q " value: ${ SHARE_DIR } " " ${ dep_file } " ; then
error "配置替换验证失败(可能是文件格式异常)"
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
success "✅ 配置替换完成"
2025-11-08 15:24:10 +08:00
}
2025-11-08 15:59:01 +08:00
# ===================== 部署(每步都打印命令,失败显示详情)=====================
deploy( ) {
info " 步骤6/7: 开始部署( 命名空间: ${ NAMESPACE } ) "
local deploy_dir = " ${ TARGET_DIR } /nfs-subdir-external-provisioner/deploy "
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# 1. 部署RBAC
info "正在部署RBAC权限..."
if ! kubectl apply -f " ${ deploy_dir } /rbac.yaml " -n " ${ NAMESPACE } " ; then
error " RBAC部署失败! 执行命令: kubectl apply -f ${ deploy_dir } /rbac.yaml -n ${ NAMESPACE } 查看详情 "
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
success "✅ RBAC权限部署完成"
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# 2. 部署存储类
info "正在部署存储类..."
if ! kubectl apply -f " ${ deploy_dir } /class.yaml " -n " ${ NAMESPACE } " ; then
error " 存储类部署失败! 执行命令: kubectl apply -f ${ deploy_dir } /class.yaml -n ${ NAMESPACE } 查看详情 "
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
success "✅ 存储类部署完成"
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# 3. 部署Provisioner
info "正在部署Provisioner..."
if ! kubectl apply -f " ${ deploy_dir } /deployment.yaml " -n " ${ NAMESPACE } " ; then
error " Provisioner部署失败! 执行命令: kubectl apply -f ${ deploy_dir } /deployment.yaml -n ${ NAMESPACE } 查看详情 "
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
success "✅ Provisioner部署完成"
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# 4. 部署测试资源(失败不中断)
info "正在部署测试资源..."
if kubectl apply -f " ${ deploy_dir } /test-claim.yaml " -f " ${ deploy_dir } /test-pod.yaml " -n " ${ NAMESPACE } " ; then
success "✅ 测试资源部署完成"
2025-11-08 15:24:10 +08:00
else
2025-11-08 15:59:01 +08:00
echo -e "\033[33m[WARNING] ⚠️ 测试资源部署警告(不影响核心功能)\033[0m"
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
info "部署流程完成, 等待5秒后查看状态..."
sleep 5
}
2025-11-08 15:24:10 +08:00
2025-11-08 15:59:01 +08:00
# ===================== 打印结果(简化但清晰)=====================
print_result( ) {
info "步骤7/7: 部署结果汇总"
echo -e "\n==================================================="
echo -e "📌 核心信息"
echo -e " 部署命名空间:\033[32m ${ NAMESPACE } \033[0m "
echo -e " 存储类名称:\033[32m ${ SC_NAME } \033[0m "
echo -e " 使用方法: 创建PVC时指定 storageClassName: ${ SC_NAME } "
echo -e "\n📌 资源状态"
# 存储类状态
if kubectl get sc " ${ SC_NAME } " & > /dev/null; then
echo -e " 存储类:\033[32m✅ 已创建\033[0m( kubectl get sc ${ SC_NAME } ) "
2025-11-08 15:24:10 +08:00
else
2025-11-08 15:59:01 +08:00
echo -e " 存储类:\033[31m❌ 未创建\033[0m"
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
# Provisioner Pod状态
local pod_name = $( kubectl get pods -l " ${ POD_LABEL } " -n " ${ NAMESPACE } " -o jsonpath = '{.items[0].metadata.name}' 2>/dev/null)
if [ [ -n " ${ pod_name } " ] ] ; then
local pod_status = $( kubectl get pod " ${ pod_name } " -n " ${ NAMESPACE } " -o jsonpath = '{.status.phase}' 2>/dev/null)
echo -e " Provisioner Pod: \033[32m✅ ${ pod_name } ( ${ pod_status } ) \033[0m"
2025-11-08 15:24:10 +08:00
else
2025-11-08 15:59:01 +08:00
echo -e " Provisioner Pod: \033[31m❌ 未找到\033[0m( kubectl get pods -n ${ NAMESPACE } -l ${ POD_LABEL } ) "
2025-11-08 15:24:10 +08:00
fi
2025-11-08 15:59:01 +08:00
echo -e "==================================================="
2025-11-08 15:24:10 +08:00
}
2025-11-08 15:59:01 +08:00
# ===================== 常用命令(极简)=====================
print_maintenance( ) {
info "常用维护命令"
2025-11-08 15:24:10 +08:00
cat << EOF
2025-11-08 15:59:01 +08:00
1. 查看存储类: kubectl get sc
2. 查看Pod状态: kubectl get pods -n ${ NAMESPACE } -l ${ POD_LABEL }
3. 查看日志: kubectl logs -f -n ${ NAMESPACE } <Pod名称>
4. 卸载: kubectl delete -f ${ TARGET_DIR } /nfs-subdir-external-provisioner/deploy -n ${ NAMESPACE }
2025-11-08 15:24:10 +08:00
EOF
}
2025-11-08 15:59:01 +08:00
# ===================== 主流程 =====================
2025-11-08 15:24:10 +08:00
main( ) {
2025-11-08 15:59:01 +08:00
echo -e "\033[32m===================================================\033[0m"
echo -e "\033[32mNFS存储类快速部署脚本( 带调试版) \033[0m"
echo -e "\033[32m===================================================\033[0m"
2025-11-08 15:24:10 +08:00
echo -e " 执行时间: $( date +'%Y-%m-%d %H:%M:%S' ) "
2025-11-08 15:59:01 +08:00
# 按步骤执行,每步都有明确输出
2025-11-08 15:24:10 +08:00
parse_args " $@ "
pre_check
download_and_extract
2025-11-08 15:59:01 +08:00
replace_config
deploy
print_result
print_maintenance
2025-11-08 15:24:10 +08:00
# 清理临时文件
2025-11-08 15:59:01 +08:00
rm -f /tmp/nfs.tgz
success "🎉 所有流程执行完毕!"
2025-11-08 15:24:10 +08:00
}
2025-11-08 15:59:01 +08:00
# 脚本入口
2025-11-08 15:24:10 +08:00
main " $@ "