#!/bin/bash # 去掉set -e,避免一步失败直接退出,改为手动控制退出 set -uo pipefail # ===================== 核心配置 ===================== NFS_TAR_URL="http://116.205.97.109/scripts/nfs-subdir-external-provisioner.tgz" TARGET_DIR="/opt/k8s-install-conf" NAMESPACE="default" POD_LABEL="app=nfs-client-provisioner" SC_NAME="nfs-client" NFS_SERVER="" SHARE_DIR="" # ===================== 日志输出(增加步骤编号)===================== 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; } # ===================== 参数解析(增加调试)===================== parse_args() { info "步骤1/7:解析命令行参数" while [[ $# -gt 0 ]]; do case "$1" in --nfs-server) NFS_SERVER="$2"; shift 2 ;; --share-dirs) SHARE_DIR="$2"; shift 2 ;; --help) echo "用法:$0 --nfs-server --share-dirs <共享目录>"; exit 0 ;; *) error "不支持参数:$1,使用--help查看用法" ;; esac done # 校验参数(明确提示缺失项) if [[ -z "${NFS_SERVER}" ]]; then error "缺少必传参数:--nfs-server "; fi if [[ -z "${SHARE_DIR}" ]]; then error "缺少必传参数:--share-dirs "; 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}" } # ===================== 前置检查(增加超时和详细输出)===================== pre_check() { 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 done success "✅ 所有依赖工具已安装" # 部署包可达性检查(增加超时10秒) info "正在检查部署包可达性:${NFS_TAR_URL}" if ! wget --spider --timeout=10 "${NFS_TAR_URL}" &> /dev/null; then error "部署包不可访问!请检查:1) 网络是否能通该地址 2) 包是否存在 3) 防火墙是否放行" fi success "✅ 部署包可达性检查通过" } # ===================== 下载解压(增加进度和错误提示)===================== download_and_extract() { 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 "部署包下载失败!可能原因:网络超时、地址错误、包不存在" fi success "✅ 部署包下载完成(保存到:${tmp_tar})" info "步骤4/7:解压部署包到 ${TARGET_DIR}" mkdir -p "${TARGET_DIR}" || error "创建目标目录失败:${TARGET_DIR}(权限不足?)" if ! tar -zxf "${tmp_tar}" -C "${TARGET_DIR}"; then error "解压失败!可能原因:压缩包损坏、权限不足" fi # 校验核心文件 local deploy_dir="${TARGET_DIR}/nfs-subdir-external-provisioner/deploy" local required_files=("rbac.yaml" "class.yaml" "deployment.yaml") for file in "${required_files[@]}"; do if ! [[ -f "${deploy_dir}/${file}" ]]; then error "解压后缺失核心文件:${deploy_dir}/${file}(压缩包损坏?)" fi done success "✅ 解压完成,部署文件路径:${deploy_dir}" } # ===================== 替换配置(增加文件存在性检查)===================== 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 # 替换环境变量(显示替换前后的对比) info "env替换前:NFS_SERVER=10.3.243.101,SHARE_DIR=/ifs/kubernetes" 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 "替换共享目录失败(文件权限不足?)" fi # 替换环境变量(显示替换前后的对比) 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 # 验证替换结果 if ! grep -q "value: ${NFS_SERVER}" "${dep_file}" || ! grep -q "value: ${SHARE_DIR}" "${dep_file}"; then error "配置替换验证失败(可能是文件格式异常)" fi success "✅ 配置替换完成" } # ===================== 部署(每步都打印命令,失败显示详情)===================== deploy() { info "步骤6/7:开始部署(命名空间:${NAMESPACE})" local deploy_dir="${TARGET_DIR}/nfs-subdir-external-provisioner/deploy" # 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} 查看详情" fi success "✅ RBAC权限部署完成" # 2. 部署存储类 info "正在部署存储类..." if ! kubectl apply -f "${deploy_dir}/class.yaml" -n "${NAMESPACE}"; then error "存储类部署失败!执行命令:kubectl apply -f ${deploy_dir}/class.yaml -n ${NAMESPACE} 查看详情" fi success "✅ 存储类部署完成" # 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} 查看详情" fi success "✅ Provisioner部署完成" # 4. 部署测试资源(失败不中断) info "正在部署测试资源..." if kubectl apply -f "${deploy_dir}/test-claim.yaml" -f "${deploy_dir}/test-pod.yaml" -n "${NAMESPACE}"; then success "✅ 测试资源部署完成" else echo -e "\033[33m[WARNING] ⚠️ 测试资源部署警告(不影响核心功能)\033[0m" fi info "部署流程完成,等待5秒后查看状态..." sleep 5 } # ===================== 打印结果(简化但清晰)===================== 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})" else echo -e " 存储类:\033[31m❌ 未创建\033[0m" fi # 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" else echo -e " Provisioner Pod:\033[31m❌ 未找到\033[0m(kubectl get pods -n ${NAMESPACE} -l ${POD_LABEL})" fi echo -e "===================================================" } # ===================== 常用命令(极简)===================== print_maintenance() { info "常用维护命令" cat << EOF 1. 查看存储类:kubectl get sc 2. 查看Pod状态:kubectl get pods -n ${NAMESPACE} -l ${POD_LABEL} 3. 查看日志:kubectl logs -f -n ${NAMESPACE} 4. 卸载:kubectl delete -f ${TARGET_DIR}/nfs-subdir-external-provisioner/deploy -n ${NAMESPACE} EOF } # ===================== 主流程 ===================== main() { echo -e "\033[32m===================================================\033[0m" echo -e "\033[32mNFS存储类快速部署脚本(带调试版)\033[0m" echo -e "\033[32m===================================================\033[0m" echo -e "执行时间:$(date +'%Y-%m-%d %H:%M:%S')" # 按步骤执行,每步都有明确输出 parse_args "$@" pre_check download_and_extract replace_config deploy print_result print_maintenance # 清理临时文件 rm -f /tmp/nfs.tgz success "🎉 所有流程执行完毕!" } # 脚本入口 main "$@"