214 lines
9.2 KiB
Bash
214 lines
9.2 KiB
Bash
#!/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 <NFS_IP> --share-dirs <共享目录>"; exit 0 ;;
|
||
*) error "不支持参数:$1,使用--help查看用法" ;;
|
||
esac
|
||
done
|
||
# 校验参数(明确提示缺失项)
|
||
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}"
|
||
}
|
||
|
||
# ===================== 前置检查(增加超时和详细输出)=====================
|
||
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 "替换前: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
|
||
|
||
# 验证替换结果
|
||
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} <Pod名称>
|
||
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 "$@" |