parent
53fba0596c
commit
7ba004eab8
|
|
@ -1,405 +1,214 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
# 去掉set -e,避免一步失败直接退出,改为手动控制退出
|
||||
set -uo pipefail
|
||||
|
||||
# ===================== 全局常量定义(压缩包地址写死)=====================
|
||||
# 颜色输出常量
|
||||
RED="\033[31m"
|
||||
GREEN="\033[32m"
|
||||
YELLOW="\033[33m"
|
||||
BLUE="\033[34m"
|
||||
RESET="\033[0m"
|
||||
|
||||
# 固定配置(压缩包地址写死,无需命令行指定)
|
||||
# ===================== 核心配置 =====================
|
||||
NFS_TAR_URL="http://116.205.97.109/scripts/nfs-subdir-external-provisioner.tgz"
|
||||
TARGET_DIR="/opt/k8s-install-conf"
|
||||
NFS_DEPLOY_DIR="${TARGET_DIR}/nfs-subdir-external-provisioner"
|
||||
DEPLOY_FILE_PATH="${NFS_DEPLOY_DIR}/deploy/deployment.yaml"
|
||||
DOWNLOAD_TEMP_PATH="/tmp/nfs-subdir-external-provisioner.tgz"
|
||||
|
||||
# 命令行参数变量(仅保留必选参数)
|
||||
NAMESPACE="default"
|
||||
POD_LABEL="app=nfs-client-provisioner"
|
||||
SC_NAME="nfs-client"
|
||||
NFS_SERVER=""
|
||||
SHARE_DIR=""
|
||||
|
||||
# ===================== 函数封装 - 日志输出 =====================
|
||||
info() {
|
||||
echo -e "[${BLUE}INFO${RESET}] $1"
|
||||
}
|
||||
# ===================== 日志输出(增加步骤编号)=====================
|
||||
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; }
|
||||
|
||||
success() {
|
||||
echo -e "[${GREEN}SUCCESS${RESET}] $1"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "[${YELLOW}WARNING${RESET}] $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "[${RED}ERROR${RESET}] $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 参数解析 =====================
|
||||
# ===================== 参数解析(增加调试)=====================
|
||||
parse_args() {
|
||||
info "开始解析命令行参数..."
|
||||
# 仅支持必选参数和帮助
|
||||
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)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
error "不支持的参数:$1,使用--help查看帮助"
|
||||
;;
|
||||
--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查看用法" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 必传参数校验
|
||||
if [[ -z "${NFS_SERVER}" || -z "${SHARE_DIR}" ]]; then
|
||||
error "必传参数缺失!请指定 --nfs-server <NFS服务器IP> 和 --share-dirs <共享目录>"
|
||||
fi
|
||||
|
||||
# NFS服务器IP格式校验
|
||||
if ! [[ "${NFS_SERVER}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
error "NFS服务器IP格式非法:${NFS_SERVER}(请输入合法IPv4地址)"
|
||||
fi
|
||||
|
||||
# 共享目录格式校验(必须是绝对路径)
|
||||
if ! [[ "${SHARE_DIR}" =~ ^/ ]]; then
|
||||
error "共享目录必须是绝对路径:${SHARE_DIR}(示例:/data/nfs/share)"
|
||||
fi
|
||||
|
||||
success "参数解析完成:"
|
||||
echo -e " NFS服务器IP:${GREEN}${NFS_SERVER}${RESET}"
|
||||
echo -e " NFS共享目录:${GREEN}${SHARE_DIR}${RESET}"
|
||||
echo -e " 部署包地址(固定):${GREEN}${NFS_TAR_URL}${RESET}"
|
||||
# 校验参数(明确提示缺失项)
|
||||
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}"
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 用法说明 =====================
|
||||
print_usage() {
|
||||
cat << EOF
|
||||
==================================================
|
||||
NFS存储类自动化部署脚本(企业级专业版)
|
||||
==================================================
|
||||
功能:自动下载/解压部署文件、替换NFS配置、按顺序部署组件、验证结果
|
||||
用法:$0 --nfs-server <NFS_IP> --share-dirs <SHARE_DIR>
|
||||
参数说明:
|
||||
--nfs-server 必选 NFS服务器IPv4地址(示例:192.168.1.100)
|
||||
--share-dirs 必选 NFS共享目录(绝对路径,示例:/data/nfs/k8s)
|
||||
--help 可选 查看帮助信息
|
||||
部署包固定地址:${NFS_TAR_URL}
|
||||
示例:
|
||||
$0 --nfs-server 192.168.1.100 --share-dirs /data/nfs/k8s
|
||||
$0 --nfs-server 10.0.0.200 --share-dirs /ifs/k8s-prod
|
||||
==================================================
|
||||
EOF
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 前置环境检查 =====================
|
||||
# ===================== 前置检查(增加超时和详细输出)=====================
|
||||
pre_check() {
|
||||
info "开始前置环境检查..."
|
||||
info "步骤2/7:前置环境检查"
|
||||
# 权限检查
|
||||
if [[ "$(id -u)" -ne 0 ]]; then error "请用root用户执行(sudo -i 切换)"; fi
|
||||
success "✅ 权限检查通过"
|
||||
|
||||
# 1. 权限检查(必须root)
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
error "请使用root用户执行脚本(sudo -i 切换后重试)"
|
||||
fi
|
||||
# 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集群连接正常"
|
||||
|
||||
# 2. kubectl检查
|
||||
if ! command -v kubectl &> /dev/null; then
|
||||
error "未安装kubectl命令,请先配置Kubernetes客户端环境"
|
||||
fi
|
||||
|
||||
# 3. 集群连接检查
|
||||
if ! kubectl cluster-info &> /dev/null; then
|
||||
error "kubectl无法连接Kubernetes集群,请检查kubeconfig配置或集群状态"
|
||||
fi
|
||||
|
||||
# 4. 依赖工具检查(wget/tar/sed)
|
||||
local dependencies=("wget" "tar" "sed")
|
||||
for tool in "${dependencies[@]}"; do
|
||||
if ! command -v "${tool}" &> /dev/null; then
|
||||
warning "未找到${tool},尝试自动安装..."
|
||||
if [[ -f /etc/debian_version ]]; then
|
||||
apt update -qq && apt install -y -qq "${tool}" || error "Debian系系统安装${tool}失败"
|
||||
elif [[ -f /etc/redhat-release ]]; then
|
||||
yum install -y -q "${tool}" || error "RHEL系系统安装${tool}失败"
|
||||
else
|
||||
error "不支持的系统,无法自动安装${tool},请手动安装后重试"
|
||||
fi
|
||||
fi
|
||||
# 依赖工具检查
|
||||
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 "✅ 所有依赖工具已安装"
|
||||
|
||||
# 5. 压缩包可达性检查(固定地址)
|
||||
info "检查部署包可达性:${NFS_TAR_URL}"
|
||||
if ! wget --spider "${NFS_TAR_URL}" &> /dev/null; then
|
||||
error "部署包地址不可访问!请检查:1) 地址是否正确 2) 服务器网络是否通畅 3) 文件是否存在"
|
||||
# 部署包可达性检查(增加超时10秒)
|
||||
info "正在检查部署包可达性:${NFS_TAR_URL}"
|
||||
if ! wget --spider --timeout=10 "${NFS_TAR_URL}" &> /dev/null; then
|
||||
error "部署包不可访问!请检查:1) 网络是否能通该地址 2) 包是否存在 3) 防火墙是否放行"
|
||||
fi
|
||||
|
||||
success "前置环境检查通过"
|
||||
success "✅ 部署包可达性检查通过"
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 下载与解压 =====================
|
||||
# ===================== 下载解压(增加进度和错误提示)=====================
|
||||
download_and_extract() {
|
||||
info "开始下载并解压部署包..."
|
||||
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})"
|
||||
|
||||
# 1. 创建目标目录
|
||||
mkdir -p "${TARGET_DIR}" || error "创建目标目录失败:${TARGET_DIR}"
|
||||
|
||||
# 2. 下载压缩包(固定地址)
|
||||
info "从固定地址下载:${NFS_TAR_URL}"
|
||||
wget -q --show-progress -O "${DOWNLOAD_TEMP_PATH}" "${NFS_TAR_URL}" || {
|
||||
rm -f "${DOWNLOAD_TEMP_PATH}"
|
||||
error "部署包下载失败!请检查网络或文件地址"
|
||||
}
|
||||
|
||||
# 3. 压缩包完整性校验(文件大小≥1KB)
|
||||
if [[ ! -f "${DOWNLOAD_TEMP_PATH}" || $(stat -c %s "${DOWNLOAD_TEMP_PATH}") -lt 1024 ]]; then
|
||||
rm -f "${DOWNLOAD_TEMP_PATH}"
|
||||
error "下载的压缩包损坏或为空"
|
||||
info "步骤4/7:解压部署包到 ${TARGET_DIR}"
|
||||
mkdir -p "${TARGET_DIR}" || error "创建目标目录失败:${TARGET_DIR}(权限不足?)"
|
||||
if ! tar -zxf "${tmp_tar}" -C "${TARGET_DIR}"; then
|
||||
error "解压失败!可能原因:压缩包损坏、权限不足"
|
||||
fi
|
||||
|
||||
# 4. 解压文件(覆盖已有目录,保留原文件权限)
|
||||
info "解压到目标目录:${TARGET_DIR}"
|
||||
tar -zxf "${DOWNLOAD_TEMP_PATH}" -C "${TARGET_DIR}" --preserve-permissions || {
|
||||
rm -f "${DOWNLOAD_TEMP_PATH}"
|
||||
error "解压压缩包失败"
|
||||
}
|
||||
|
||||
# 5. 解压后文件校验(核心文件必须存在)
|
||||
local required_files=("class.yaml" "rbac.yaml" "deployment.yaml" "test-claim.yaml" "test-pod.yaml")
|
||||
# 校验核心文件
|
||||
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
|
||||
local file_path="${NFS_DEPLOY_DIR}/deploy/${file}"
|
||||
if [[ ! -f "${file_path}" ]]; then
|
||||
rm -f "${DOWNLOAD_TEMP_PATH}"
|
||||
error "解压后缺失核心文件:${file_path}"
|
||||
if ! [[ -f "${deploy_dir}/${file}" ]]; then
|
||||
error "解压后缺失核心文件:${deploy_dir}/${file}(压缩包损坏?)"
|
||||
fi
|
||||
done
|
||||
|
||||
success "下载解压完成,部署文件路径:${NFS_DEPLOY_DIR}/deploy"
|
||||
success "✅ 解压完成,部署文件路径:${deploy_dir}"
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 替换NFS配置 =====================
|
||||
replace_nfs_config() {
|
||||
info "开始替换deployment.yaml中的NFS配置..."
|
||||
# ===================== 替换配置(增加文件存在性检查)=====================
|
||||
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
|
||||
|
||||
# 检查deployment.yaml是否存在
|
||||
if [[ ! -f "${DEPLOY_FILE_PATH}" ]]; then
|
||||
error "未找到配置文件:${DEPLOY_FILE_PATH}"
|
||||
# 替换环境变量(显示替换前后的对比)
|
||||
info "替换前: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
|
||||
|
||||
# 备份原配置文件(避免替换失败)
|
||||
local backup_file="${DEPLOY_FILE_PATH}.bak.$(date +%Y%m%d%H%M%S)"
|
||||
cp -f "${DEPLOY_FILE_PATH}" "${backup_file}" || error "备份原配置文件失败"
|
||||
info "已备份原配置文件:${backup_file}"
|
||||
|
||||
# 替换默认NFS_SERVER(原默认值:10.3.243.101)
|
||||
sed -i.bak "s#10.3.243.101#${NFS_SERVER}#g" "${DEPLOY_FILE_PATH}" || {
|
||||
mv -f "${backup_file}" "${DEPLOY_FILE_PATH}" # 替换失败回滚
|
||||
error "替换NFS_SERVER失败,已回滚原配置"
|
||||
}
|
||||
|
||||
# 替换默认共享目录(原默认值:/ifs/kubernetes)
|
||||
sed -i.bak "s#/ifs/kubernetes#${SHARE_DIR}#g" "${DEPLOY_FILE_PATH}" || {
|
||||
mv -f "${backup_file}" "${DEPLOY_FILE_PATH}" # 替换失败回滚
|
||||
error "替换共享目录失败,已回滚原配置"
|
||||
}
|
||||
|
||||
# 清理sed备份文件
|
||||
rm -f "${DEPLOY_FILE_PATH}.bak"
|
||||
|
||||
# 验证替换结果
|
||||
if ! grep -q "${NFS_SERVER}" "${DEPLOY_FILE_PATH}" || ! grep -q "${SHARE_DIR}" "${DEPLOY_FILE_PATH}"; then
|
||||
mv -f "${backup_file}" "${DEPLOY_FILE_PATH}"
|
||||
error "配置替换验证失败,已回滚原配置"
|
||||
if ! grep -q "value: ${NFS_SERVER}" "${dep_file}" || ! grep -q "value: ${SHARE_DIR}" "${dep_file}"; then
|
||||
error "配置替换验证失败(可能是文件格式异常)"
|
||||
fi
|
||||
|
||||
success "NFS配置替换完成:"
|
||||
echo -e " 原NFS服务器:${YELLOW}10.3.243.101${RESET} → 新地址:${GREEN}${NFS_SERVER}${RESET}"
|
||||
echo -e " 原共享目录:${YELLOW}/ifs/kubernetes${RESET} → 新目录:${GREEN}${SHARE_DIR}${RESET}"
|
||||
success "✅ 配置替换完成"
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 部署核心组件 =====================
|
||||
deploy_core_components() {
|
||||
info "开始部署NFS存储类核心组件..."
|
||||
local deploy_dir="${NFS_DEPLOY_DIR}/deploy"
|
||||
cd "${deploy_dir}" || error "进入部署目录失败:${deploy_dir}"
|
||||
# ===================== 部署(每步都打印命令,失败显示详情)=====================
|
||||
deploy() {
|
||||
info "步骤6/7:开始部署(命名空间:${NAMESPACE})"
|
||||
local deploy_dir="${TARGET_DIR}/nfs-subdir-external-provisioner/deploy"
|
||||
|
||||
# 按顺序部署(依赖关系:RBAC → 存储类 → Provisioner)
|
||||
local deploy_order=("rbac.yaml" "class.yaml" "deployment.yaml")
|
||||
for file in "${deploy_order[@]}"; do
|
||||
info "部署 ${file}..."
|
||||
kubectl apply -f "${file}" || error "${file} 部署失败"
|
||||
done
|
||||
# 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权限部署完成"
|
||||
|
||||
# 等待Provisioner启动(最多等待30秒)
|
||||
info "核心组件部署完成,等待Provisioner Pod启动(最多30秒)..."
|
||||
local wait_seconds=0
|
||||
while true; do
|
||||
local pod_status=$(kubectl get pods -l app=nfs-subdir-external-provisioner -o jsonpath='{.items[0].status.phase}' 2>/dev/null)
|
||||
if [[ "${pod_status}" == "Running" ]]; then
|
||||
break
|
||||
fi
|
||||
if [[ ${wait_seconds} -ge 30 ]]; then
|
||||
warning "Provisioner Pod未在30秒内启动,继续部署测试资源(后续需手动检查)"
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
wait_seconds=$((wait_seconds + 5))
|
||||
done
|
||||
# 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 "✅ 存储类部署完成"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 部署测试资源 =====================
|
||||
deploy_test_resources() {
|
||||
info "开始部署测试资源(PVC+Pod)..."
|
||||
local deploy_dir="${NFS_DEPLOY_DIR}/deploy"
|
||||
|
||||
# 部署测试PVC
|
||||
if ! kubectl apply -f "${deploy_dir}/test-claim.yaml"; then
|
||||
warning "测试PVC部署失败,不影响核心功能(可后续手动排查)"
|
||||
# ===================== 打印结果(简化但清晰)=====================
|
||||
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
|
||||
info "测试PVC(test-claim)部署成功,等待绑定..."
|
||||
sleep 5
|
||||
echo -e " 存储类:\033[31m❌ 未创建\033[0m"
|
||||
fi
|
||||
|
||||
# 部署测试Pod
|
||||
if ! kubectl apply -f "${deploy_dir}/test-pod.yaml"; then
|
||||
warning "测试Pod部署失败,不影响核心功能(可后续手动排查)"
|
||||
# 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
|
||||
info "测试Pod(test-pod)部署成功,等待启动..."
|
||||
sleep 5
|
||||
echo -e " Provisioner Pod:\033[31m❌ 未找到\033[0m(kubectl get pods -n ${NAMESPACE} -l ${POD_LABEL})"
|
||||
fi
|
||||
|
||||
success "测试资源部署流程完成"
|
||||
echo -e "==================================================="
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 部署验证 =====================
|
||||
verify_deployment() {
|
||||
info "开始部署结果验证(核心指标)..."
|
||||
local verify_status="SUCCESS"
|
||||
|
||||
# 1. 验证存储类
|
||||
info "1. 存储类验证:"
|
||||
if kubectl get sc nfs-client &> /dev/null; then
|
||||
echo -e " ✅ nfs-client存储类已创建"
|
||||
else
|
||||
echo -e " ❌ nfs-client存储类未创建"
|
||||
verify_status="FAILED"
|
||||
fi
|
||||
|
||||
# 2. 验证Provisioner Pod
|
||||
info "2. Provisioner Pod验证:"
|
||||
local provisioner_pod=$(kubectl get pods -l app=nfs-subdir-external-provisioner -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [[ -z "${provisioner_pod}" ]]; then
|
||||
echo -e " ❌ 未找到Provisioner Pod"
|
||||
verify_status="FAILED"
|
||||
else
|
||||
local pod_status=$(kubectl get pod "${provisioner_pod}" -o jsonpath='{.status.phase}' 2>/dev/null)
|
||||
if [[ "${pod_status}" == "Running" ]]; then
|
||||
echo -e " ✅ Pod名称:${provisioner_pod},状态:${GREEN}Running${RESET}"
|
||||
else
|
||||
echo -e " ⚠️ Pod名称:${provisioner_pod},状态:${YELLOW}${pod_status}${RESET}(期望Running)"
|
||||
verify_status="PARTIAL_SUCCESS"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 3. 验证测试PVC绑定
|
||||
info "3. 测试PVC验证:"
|
||||
if kubectl get pvc test-claim -o jsonpath='{.status.phase}' 2>/dev/null | grep -q "Bound"; then
|
||||
echo -e " ✅ 测试PVC(test-claim)绑定成功"
|
||||
else
|
||||
echo -e " ⚠️ 测试PVC未绑定(可能是NFS服务器连接失败或权限问题)"
|
||||
fi
|
||||
|
||||
# 4. 验证测试Pod状态
|
||||
info "4. 测试Pod验证:"
|
||||
if kubectl get pod test-pod -o jsonpath='{.status.phase}' 2>/dev/null | grep -q "Running"; then
|
||||
echo -e " ✅ 测试Pod(test-pod)运行正常"
|
||||
else
|
||||
echo -e " ⚠️ 测试Pod未正常运行(可通过kubectl logs test-pod排查)"
|
||||
fi
|
||||
|
||||
# 输出最终验证结果
|
||||
echo -e "\n=================================================="
|
||||
if [[ "${verify_status}" == "SUCCESS" ]]; then
|
||||
success "NFS存储类部署完全成功!"
|
||||
elif [[ "${verify_status}" == "PARTIAL_SUCCESS" ]]; then
|
||||
warning "NFS存储类核心功能部署成功,但部分组件状态异常(不影响基本使用)"
|
||||
else
|
||||
error "NFS存储类部署失败!请根据上述验证结果排查问题"
|
||||
fi
|
||||
echo -e "=================================================="
|
||||
}
|
||||
|
||||
# ===================== 函数封装 - 打印维护命令 =====================
|
||||
print_maintenance_commands() {
|
||||
info "输出常用维护命令(按场景分类)..."
|
||||
# ===================== 常用命令(极简)=====================
|
||||
print_maintenance() {
|
||||
info "常用维护命令"
|
||||
cat << EOF
|
||||
${BLUE}### 一、状态监控命令 ###${RESET}
|
||||
1. 查看存储类列表:kubectl get sc
|
||||
2. 查看NFS存储类详情:kubectl describe sc nfs-client
|
||||
3. 查看Provisioner Pod状态:kubectl get pods -l app=nfs-subdir-external-provisioner
|
||||
4. 查看Provisioner实时日志:kubectl logs -f \$(kubectl get pods -l app=nfs-subdir-external-provisioner -o jsonpath='{.items[0].metadata.name}')
|
||||
5. 查看所有NFS类型PVC:kubectl get pvc -l storageClassName=nfs-client
|
||||
6. 查看NFS自动创建的PV:kubectl get pv -l storageClassName=nfs-client
|
||||
|
||||
${BLUE}### 二、资源操作命令 ###${RESET}
|
||||
1. 删除测试资源(生产环境推荐):kubectl delete pod test-pod && kubectl delete pvc test-claim
|
||||
2. 重启Provisioner:kubectl rollout restart deployment nfs-subdir-external-provisioner
|
||||
3. 重新部署核心组件:cd ${NFS_DEPLOY_DIR}/deploy && kubectl apply -f rbac.yaml -f class.yaml -f deployment.yaml
|
||||
4. 完全卸载NFS存储类:
|
||||
kubectl delete pod test-pod --ignore-not-found
|
||||
kubectl delete pvc test-claim --ignore-not-found
|
||||
kubectl delete pv -l storageClassName=nfs-client --ignore-not-found
|
||||
kubectl delete sc nfs-client --ignore-not-found
|
||||
kubectl delete deployment nfs-subdir-external-provisioner --ignore-not-found
|
||||
kubectl delete -f ${NFS_DEPLOY_DIR}/deploy/rbac.yaml --ignore-not-found
|
||||
|
||||
${BLUE}### 三、问题排查命令 ###${RESET}
|
||||
1. 检查Provisioner Pod详情(启动失败):kubectl describe pods -l app=nfs-subdir-external-provisioner
|
||||
2. 排查PVC绑定失败:kubectl describe pvc <PVC_NAME>
|
||||
3. 测试NFS服务器连通性:mount -t nfs ${NFS_SERVER}:${SHARE_DIR} /tmp/test-nfs-mount(测试后umount /tmp/test-nfs-mount)
|
||||
4. 查看NFS服务器共享配置:showmount -e ${NFS_SERVER}
|
||||
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}
|
||||
EOF
|
||||
}
|
||||
|
||||
# ===================== 主函数(流程控制) =====================
|
||||
# ===================== 主流程 =====================
|
||||
main() {
|
||||
echo -e "${GREEN}==================================================${RESET}"
|
||||
echo -e "${GREEN}NFS存储类自动化部署脚本(企业级专业版)${RESET}"
|
||||
echo -e "${GREEN}==================================================${RESET}"
|
||||
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')"
|
||||
echo -e "脚本版本:v1.0.1"
|
||||
echo -e "部署包地址:${NFS_TAR_URL}"
|
||||
echo -e "${GREEN}==================================================${RESET}\n"
|
||||
|
||||
# 流程执行顺序
|
||||
# 按步骤执行,每步都有明确输出
|
||||
parse_args "$@"
|
||||
pre_check
|
||||
download_and_extract
|
||||
replace_nfs_config
|
||||
deploy_core_components
|
||||
deploy_test_resources
|
||||
verify_deployment
|
||||
print_maintenance_commands
|
||||
replace_config
|
||||
deploy
|
||||
print_result
|
||||
print_maintenance
|
||||
|
||||
# 清理临时文件
|
||||
info "清理临时文件:${DOWNLOAD_TEMP_PATH}"
|
||||
rm -f "${DOWNLOAD_TEMP_PATH}"
|
||||
|
||||
echo -e "\n${GREEN}==================================================${RESET}"
|
||||
success "部署流程全部完成!"
|
||||
echo -e "${GREEN}==================================================${RESET}"
|
||||
rm -f /tmp/nfs.tgz
|
||||
success "🎉 所有流程执行完毕!"
|
||||
}
|
||||
|
||||
# ===================== 脚本入口 =====================
|
||||
# 脚本入口
|
||||
main "$@"
|
||||
Loading…
Reference in New Issue