管理k8s的资源类型(PV/PVC)的脚本
#!/bin/bash# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color# 日志函数
log() {echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
}error() {echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] 错误: $1${NC}"
}warn() {echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] 警告: $1${NC}"
}info() {echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
}# 检查 kubectl
check_kubectl() {if ! command -v kubectl &> /dev/null; thenerror "kubectl 未安装或不在 PATH 中"exit 1fi# 检查集群连接if ! kubectl cluster-info &> /dev/null; thenerror "无法连接到 Kubernetes 集群"exit 1fi
}# 获取 PV 列表
get_pv_list() {kubectl get pv --no-headers 2>/dev/null | while read line; doif [ -n "$line" ]; thenecho "$line"fidone
}# 获取 PVC 列表(所有命名空间)
get_pvc_list() {kubectl get pvc --all-namespaces --no-headers 2>/dev/null | while read line; doif [ -n "$line" ]; thenecho "$line"fidone
}# 显示并选择 PV
select_and_delete_pv() {local pvs=()local pv_count=0# 获取 PV 列表到数组while IFS= read -r line; doif [ -n "$line" ]; thenpvs+=("$line")fidone < <(get_pv_list)pv_count=${#pvs[@]}if [ $pv_count -eq 0 ]; thenwarn "没有找到 PV"returnfiecho -e "\n${CYAN}=== 可用的 PV 列表 ===${NC}"printf "%-3s %-20s %-10s %-10s %-15s %-12s %s\n" "ID" "NAME" "CAPACITY" "ACCESS" "RECLAIM" "STATUS" "CLAIM"echo "----------------------------------------------------------------------------------------"for i in "${!pvs[@]}"; doIFS=' ' read -r name capacity access_mode reclaim_policy status claim <<< "${pvs[$i]}"printf "%-3d %-20s %-10s %-10s %-15s %-12s %s\n" \$((i+1)) "$name" "$capacity" "$access_mode" "$reclaim_policy" "$status" "$claim"donewhile true; doechoecho -e "${YELLOW}选择操作:${NC}"echo " 1-${pv_count} : 删除对应的 PV"echo " a : 删除所有 PV"echo " r : 刷新列表"echo " b : 返回上级菜单"echo " q : 退出程序"read -r -p "请输入选择: " choicecase "$choice" in[qQ])log "退出程序"exit 0;;[bB])return;;[rR])select_and_delete_pvreturn;;[aA])warn "即将删除所有 PV!此操作不可逆!"read -r -p "确认删除所有 PV? (输入 'YES' 确认): " confirmif [ "$confirm" = "YES" ]; thenfor pv_line in "${pvs[@]}"; dopv_name=$(echo "$pv_line" | awk '{print $1}')log "删除 PV: $pv_name"kubectl delete pv "$pv_name"donelog "所有 PV 删除操作已完成"elselog "取消删除所有 PV"fi;;*)if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$pv_count" ]; thenpv_line="${pvs[$((choice-1))]}"pv_name=$(echo "$pv_line" | awk '{print $1}')pv_status=$(echo "$pv_line" | awk '{print $5}')echo -e "${YELLOW}选择的 PV 信息:${NC}"echo " 名称: $pv_name"echo " 状态: $pv_status"echo " 完整信息: $pv_line"read -r -p "确认删除这个 PV? (y/N): " confirmif [[ "$confirm" == "y" || "$confirm" == "Y" ]]; thenlog "删除 PV: $pv_name"kubectl delete pv "$pv_name"if [ $? -eq 0 ]; thenlog "✓ 成功删除 PV: $pv_name"elseerror "✗ 删除 PV 失败: $pv_name"fielselog "取消删除 PV: $pv_name"fielseerror "无效的选择,请输入 1-${pv_count} 之间的数字,或 a/r/b/q"fi;;esacdone
}# 显示并选择 PVC
select_and_delete_pvc() {local pvcs=()local pvc_count=0# 获取 PVC 列表到数组while IFS= read -r line; doif [ -n "$line" ]; thenpvcs+=("$line")fidone < <(get_pvc_list)pvc_count=${#pvcs[@]}if [ $pvc_count -eq 0 ]; thenwarn "没有找到 PVC"returnfiecho -e "\n${PURPLE}=== 可用的 PVC 列表 (所有命名空间) ===${NC}"printf "%-3s %-15s %-20s %-10s %-12s %-15s %s\n" "ID" "NAMESPACE" "NAME" "STATUS" "VOLUME" "CAPACITY" "ACCESS"echo "------------------------------------------------------------------------------------------------"for i in "${!pvcs[@]}"; doIFS=' ' read -r namespace name status volume capacity access_mode <<< "${pvcs[$i]}"printf "%-3d %-15s %-20s %-10s %-12s %-15s %s\n" \$((i+1)) "$namespace" "$name" "$status" "$volume" "$capacity" "$access_mode"donewhile true; doechoecho -e "${YELLOW}选择操作:${NC}"echo " 1-${pvc_count} : 删除对应的 PVC"echo " a : 删除所有 PVC"echo " r : 刷新列表"echo " b : 返回上级菜单"echo " q : 退出程序"read -r -p "请输入选择: " choicecase "$choice" in[qQ])log "退出程序"exit 0;;[bB])return;;[rR])select_and_delete_pvcreturn;;[aA])warn "即将删除所有 PVC!此操作不可逆!"read -r -p "确认删除所有 PVC? (输入 'YES' 确认): " confirmif [ "$confirm" = "YES" ]; thenfor pvc_line in "${pvcs[@]}"; dopvc_namespace=$(echo "$pvc_line" | awk '{print $1}')pvc_name=$(echo "$pvc_line" | awk '{print $2}')log "删除 PVC: $pvc_namespace/$pvc_name"kubectl delete pvc "$pvc_name" -n "$pvc_namespace"donelog "所有 PVC 删除操作已完成"elselog "取消删除所有 PVC"fi;;*)if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$pvc_count" ]; thenpvc_line="${pvcs[$((choice-1))]}"pvc_namespace=$(echo "$pvc_line" | awk '{print $1}')pvc_name=$(echo "$pvc_line" | awk '{print $2}')pvc_status=$(echo "$pvc_line" | awk '{print $3}')pvc_volume=$(echo "$pvc_line" | awk '{print $4}')echo -e "${YELLOW}选择的 PVC 信息:${NC}"echo " 命名空间: $pvc_namespace"echo " 名称: $pvc_name"echo " 状态: $pvc_status"echo " 关联 Volume: $pvc_volume"echo " 完整信息: $pvc_line"read -r -p "确认删除这个 PVC? (y/N): " confirmif [[ "$confirm" == "y" || "$confirm" == "Y" ]]; thenlog "删除 PVC: $pvc_namespace/$pvc_name"kubectl delete pvc "$pvc_name" -n "$pvc_namespace"if [ $? -eq 0 ]; thenlog "✓ 成功删除 PVC: $pvc_namespace/$pvc_name"elseerror "✗ 删除 PVC 失败: $pvc_namespace/$pvc_name"fielselog "取消删除 PVC: $pvc_namespace/$pvc_name"fielseerror "无效的选择,请输入 1-${pvc_count} 之间的数字,或 a/r/b/q"fi;;esacdone
}# 主菜单
main_menu() {while true; doecho -e "\n${BLUE}=== Kubernetes PV/PVC 管理工具 ===${NC}"echo -e "${CYAN}请选择操作类型:${NC}"echo " 1. 管理 PV (PersistentVolume)"echo " 2. 管理 PVC (PersistentVolumeClaim)"echo " 3. 查看集群存储状态"echo " q. 退出程序"read -r -p "请输入选择 (1-3 或 q): " main_choicecase "$main_choice" in1)select_and_delete_pv;;2)select_and_delete_pvc;;3)echo -e "\n${GREEN}=== 集群存储状态 ===${NC}"echo -e "${YELLOW}--- PV 状态 ---${NC}"kubectl get pv 2>/dev/null || error "获取 PV 状态失败"echo -e "\n${YELLOW}--- PVC 状态 (所有命名空间) ---${NC}"kubectl get pvc --all-namespaces 2>/dev/null || error "获取 PVC 状态失败";;[qQ])log "退出程序"exit 0;;*)error "无效的选择,请输入 1-3 或 q";;esacdone
}# 脚本开始
check_kubectl
log "连接到 Kubernetes 集群成功"
main_menu
如果有格式不正确
方法一:使用 dos2unix 转换(推荐)
安装 dos2unix
yum install -y dos2unix
使用 wget 下载
# 对于 CentOS 7
wget http://mirror.centos.org/centos/7/os/x86_64/Packages/dos2unix-7.4.0-1.el7.x86_64.rpm# 对于 CentOS 8
wget http://mirror.centos.org/centos/8/BaseOS/x86_64/os/Packages/dos2unix-7.4.2-1.el8.x86_64.rpm# 对于 Rocky/AlmaLinux 8
wget https://download.rockylinux.org/pub/rocky/8/BaseOS/x86_64/os/Packages/d/dos2unix-7.4.2-1.el8.x86_64.rpm
转换文件格式
dos2unix k8s-pv-pvc-manager.sh

重新运行
chmod +x k8s-pv-pvc-manager.sh
./k8s-pv-pvc-manager.sh
方法二:使用 sed 命令删除 CR 字符
# 删除 CR 字符
sed -i 's/\r$//' k8s-pv-pvc-manager.sh
重新运行
chmod +x k8s-pv-pvc-manager.sh
./k8s-pv-pvc-manager.sh
方法三:使用 vim 转换
用 vim 打开文件
vim k8s-pv-pvc-manager.sh
在 vim 中执行以下命令:
# :set ff=unix
# :wq
重新运行
chmod +x k8s-pv-pvc-manager.sh
./k8s-pv-pvc-manager.sh
方法四:重新创建脚本
如果上述方法都不行,可以直接重新创建脚本:
# 删除原文件
rm -f k8s-pv-pvc-manager.sh# 使用 cat 命令重新创建(确保在 Linux 环境中执行)
cat > k8s-pv-pvc-manager.sh << 'EOF'
#!/bin/bash# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color# 日志函数
log() {echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
}error() {echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] 错误: $1${NC}"
}warn() {echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] 警告: $1${NC}"
}info() {echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
}# 检查 kubectl
check_kubectl() {if ! command -v kubectl &> /dev/null; thenerror "kubectl 未安装或不在 PATH 中"exit 1fi# 检查集群连接if ! kubectl cluster-info &> /dev/null; thenerror "无法连接到 Kubernetes 集群"exit 1fi
}# 获取 PV 列表
get_pv_list() {kubectl get pv --no-headers 2>/dev/null
}# 获取 PVC 列表(所有命名空间)
get_pvc_list() {kubectl get pvc --all-namespaces --no-headers 2>/dev/null
}# 显示并选择 PV
select_and_delete_pv() {local pvs=()local pv_count=0# 获取 PV 列表到数组while IFS= read -r line; doif [ -n "$line" ]; thenpvs+=("$line")fidone < <(get_pv_list)pv_count=${#pvs[@]}if [ $pv_count -eq 0 ]; thenwarn "没有找到 PV"returnfiecho -e "\n${CYAN}=== 可用的 PV 列表 ===${NC}"printf "%-3s %-20s %-10s %-10s %-15s %-12s %s\n" "ID" "NAME" "CAPACITY" "ACCESS" "RECLAIM" "STATUS" "CLAIM"echo "----------------------------------------------------------------------------------------"for i in "${!pvs[@]}"; doIFS=' ' read -r name capacity access_mode reclaim_policy status claim <<< "${pvs[$i]}"printf "%-3d %-20s %-10s %-10s %-15s %-12s %s\n" \$((i+1)) "$name" "$capacity" "$access_mode" "$reclaim_policy" "$status" "$claim"donewhile true; doechoecho -e "${YELLOW}选择操作:${NC}"echo " 1-${pv_count} : 删除对应的 PV"echo " a : 删除所有 PV"echo " r : 刷新列表"echo " b : 返回上级菜单"echo " q : 退出程序"read -r -p "请输入选择: " choicecase "$choice" in[qQ])log "退出程序"exit 0;;[bB])return;;[rR])select_and_delete_pvreturn;;[aA])warn "即将删除所有 PV!此操作不可逆!"read -r -p "确认删除所有 PV? (输入 'YES' 确认): " confirmif [ "$confirm" = "YES" ]; thenfor pv_line in "${pvs[@]}"; dopv_name=$(echo "$pv_line" | awk '{print $1}')log "删除 PV: $pv_name"kubectl delete pv "$pv_name"donelog "所有 PV 删除操作已完成"elselog "取消删除所有 PV"fi;;*)if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$pv_count" ]; thenpv_line="${pvs[$((choice-1))]}"pv_name=$(echo "$pv_line" | awk '{print $1}')pv_status=$(echo "$pv_line" | awk '{print $5}')echo -e "${YELLOW}选择的 PV 信息:${NC}"echo " 名称: $pv_name"echo " 状态: $pv_status"echo " 完整信息: $pv_line"read -r -p "确认删除这个 PV? (y/N): " confirmif [[ "$confirm" == "y" || "$confirm" == "Y" ]]; thenlog "删除 PV: $pv_name"kubectl delete pv "$pv_name"if [ $? -eq 0 ]; thenlog "✓ 成功删除 PV: $pv_name"elseerror "✗ 删除 PV 失败: $pv_name"fielselog "取消删除 PV: $pv_name"fielseerror "无效的选择,请输入 1-${pv_count} 之间的数字,或 a/r/b/q"fi;;esacdone
}# 显示并选择 PVC
select_and_delete_pvc() {local pvcs=()local pvc_count=0# 获取 PVC 列表到数组while IFS= read -r line; doif [ -n "$line" ]; thenpvcs+=("$line")fidone < <(get_pvc_list)pvc_count=${#pvcs[@]}if [ $pvc_count -eq 0 ]; thenwarn "没有找到 PVC"returnfiecho -e "\n${PURPLE}=== 可用的 PVC 列表 (所有命名空间) ===${NC}"printf "%-3s %-15s %-20s %-10s %-12s %-15s %s\n" "ID" "NAMESPACE" "NAME" "STATUS" "VOLUME" "CAPACITY" "ACCESS"echo "------------------------------------------------------------------------------------------------"for i in "${!pvcs[@]}"; doIFS=' ' read -r namespace name status volume capacity access_mode <<< "${pvcs[$i]}"printf "%-3d %-15s %-20s %-10s %-12s %-15s %s\n" \$((i+1)) "$namespace" "$name" "$status" "$volume" "$capacity" "$access_mode"donewhile true; doechoecho -e "${YELLOW}选择操作:${NC}"echo " 1-${pvc_count} : 删除对应的 PVC"echo " a : 删除所有 PVC"echo " r : 刷新列表"echo " b : 返回上级菜单"echo " q : 退出程序"read -r -p "请输入选择: " choicecase "$choice" in[qQ])log "退出程序"exit 0;;[bB])return;;[rR])select_and_delete_pvcreturn;;[aA])warn "即将删除所有 PVC!此操作不可逆!"read -r -p "确认删除所有 PVC? (输入 'YES' 确认): " confirmif [ "$confirm" = "YES" ]; thenfor pvc_line in "${pvcs[@]}"; dopvc_namespace=$(echo "$pvc_line" | awk '{print $1}')pvc_name=$(echo "$pvc_line" | awk '{print $2}')log "删除 PVC: $pvc_namespace/$pvc_name"kubectl delete pvc "$pvc_name" -n "$pvc_namespace"donelog "所有 PVC 删除操作已完成"elselog "取消删除所有 PVC"fi;;*)if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$pvc_count" ]; thenpvc_line="${pvcs[$((choice-1))]}"pvc_namespace=$(echo "$pvc_line" | awk '{print $1}')pvc_name=$(echo "$pvc_line" | awk '{print $2}')pvc_status=$(echo "$pvc_line" | awk '{print $3}")pvc_volume=$(echo "$pvc_line" | awk '{print $4}")echo -e "${YELLOW}选择的 PVC 信息:${NC}"echo " 命名空间: $pvc_namespace"echo " 名称: $pvc_name"echo " 状态: $pvc_status"echo " 关联 Volume: $pvc_volume"echo " 完整信息: $pvc_line"read -r -p "确认删除这个 PVC? (y/N): " confirmif [[ "$confirm" == "y" || "$confirm" == "Y" ]]; thenlog "删除 PVC: $pvc_namespace/$pvc_name"kubectl delete pvc "$pvc_name" -n "$pvc_namespace"if [ $? -eq 0 ]; thenlog "✓ 成功删除 PVC: $pvc_namespace/$pvc_name"elseerror "✗ 删除 PVC 失败: $pvc_namespace/$pvc_name"fielselog "取消删除 PVC: $pvc_namespace/$pvc_name"fielseerror "无效的选择,请输入 1-${pvc_count} 之间的数字,或 a/r/b/q"fi;;esacdone
}# 主菜单
main_menu() {while true; doecho -e "\n${BLUE}=== Kubernetes PV/PVC 管理工具 ===${NC}"echo -e "${CYAN}请选择操作类型:${NC}"echo " 1. 管理 PV (PersistentVolume)"echo " 2. 管理 PVC (PersistentVolumeClaim)"echo " 3. 查看集群存储状态"echo " q. 退出程序"read -r -p "请输入选择 (1-3 或 q): " main_choicecase "$main_choice" in1)select_and_delete_pv;;2)select_and_delete_pvc;;3)echo -e "\n${GREEN}=== 集群存储状态 ===${NC}"echo -e "${YELLOW}--- PV 状态 ---${NC}"kubectl get pv 2>/dev/null || error "获取 PV 状态失败"echo -e "\n${YELLOW}--- PVC 状态 (所有命名空间) ---${NC}"kubectl get pvc --all-namespaces 2>/dev/null || error "获取 PVC 状态失败";;[qQ])log "退出程序"exit 0;;*)error "无效的选择,请输入 1-3 或 q";;esacdone
}# 脚本开始
check_kubectl
log "连接到 Kubernetes 集群成功"
main_menu
EOF# 设置执行权限并运行
chmod +x k8s-pv-pvc-manager.sh
./k8s-pv-pvc-manager.sh
