管理k8s的资源类型(PV/PVC)的脚本

bash 复制代码
#!/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; then
        error "kubectl 未安装或不在 PATH 中"
        exit 1
    fi
    
    # 检查集群连接
    if ! kubectl cluster-info &> /dev/null; then
        error "无法连接到 Kubernetes 集群"
        exit 1
    fi
}

# 获取 PV 列表
get_pv_list() {
    kubectl get pv --no-headers 2>/dev/null | while read line; do
        if [ -n "$line" ]; then
            echo "$line"
        fi
    done
}

# 获取 PVC 列表(所有命名空间)
get_pvc_list() {
    kubectl get pvc --all-namespaces --no-headers 2>/dev/null | while read line; do
        if [ -n "$line" ]; then
            echo "$line"
        fi
    done
}

# 显示并选择 PV
select_and_delete_pv() {
    local pvs=()
    local pv_count=0
    
    # 获取 PV 列表到数组
    while IFS= read -r line; do
        if [ -n "$line" ]; then
            pvs+=("$line")
        fi
    done < <(get_pv_list)
    
    pv_count=${#pvs[@]}
    
    if [ $pv_count -eq 0 ]; then
        warn "没有找到 PV"
        return
    fi
    
    echo -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[@]}"; do
        IFS=' ' 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"
    done
    
    while true; do
        echo
        echo -e "${YELLOW}选择操作:${NC}"
        echo "  1-${pv_count} : 删除对应的 PV"
        echo "  a : 删除所有 PV"
        echo "  r : 刷新列表"
        echo "  b : 返回上级菜单"
        echo "  q : 退出程序"
        
        read -r -p "请输入选择: " choice
        
        case "$choice" in
            [qQ])
                log "退出程序"
                exit 0
                ;;
            [bB])
                return
                ;;
            [rR])
                select_and_delete_pv
                return
                ;;
            [aA])
                warn "即将删除所有 PV!此操作不可逆!"
                read -r -p "确认删除所有 PV? (输入 'YES' 确认): " confirm
                if [ "$confirm" = "YES" ]; then
                    for pv_line in "${pvs[@]}"; do
                        pv_name=$(echo "$pv_line" | awk '{print $1}')
                        log "删除 PV: $pv_name"
                        kubectl delete pv "$pv_name"
                    done
                    log "所有 PV 删除操作已完成"
                else
                    log "取消删除所有 PV"
                fi
                ;;
            *)
                if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$pv_count" ]; then
                    pv_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): " confirm
                    if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
                        log "删除 PV: $pv_name"
                        kubectl delete pv "$pv_name"
                        if [ $? -eq 0 ]; then
                            log "✓ 成功删除 PV: $pv_name"
                        else
                            error "✗ 删除 PV 失败: $pv_name"
                        fi
                    else
                        log "取消删除 PV: $pv_name"
                    fi
                else
                    error "无效的选择,请输入 1-${pv_count} 之间的数字,或 a/r/b/q"
                fi
                ;;
        esac
    done
}

# 显示并选择 PVC
select_and_delete_pvc() {
    local pvcs=()
    local pvc_count=0
    
    # 获取 PVC 列表到数组
    while IFS= read -r line; do
        if [ -n "$line" ]; then
            pvcs+=("$line")
        fi
    done < <(get_pvc_list)
    
    pvc_count=${#pvcs[@]}
    
    if [ $pvc_count -eq 0 ]; then
        warn "没有找到 PVC"
        return
    fi
    
    echo -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[@]}"; do
        IFS=' ' 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"
    done
    
    while true; do
        echo
        echo -e "${YELLOW}选择操作:${NC}"
        echo "  1-${pvc_count} : 删除对应的 PVC"
        echo "  a : 删除所有 PVC"
        echo "  r : 刷新列表"
        echo "  b : 返回上级菜单"
        echo "  q : 退出程序"
        
        read -r -p "请输入选择: " choice
        
        case "$choice" in
            [qQ])
                log "退出程序"
                exit 0
                ;;
            [bB])
                return
                ;;
            [rR])
                select_and_delete_pvc
                return
                ;;
            [aA])
                warn "即将删除所有 PVC!此操作不可逆!"
                read -r -p "确认删除所有 PVC? (输入 'YES' 确认): " confirm
                if [ "$confirm" = "YES" ]; then
                    for pvc_line in "${pvcs[@]}"; do
                        pvc_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"
                    done
                    log "所有 PVC 删除操作已完成"
                else
                    log "取消删除所有 PVC"
                fi
                ;;
            *)
                if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$pvc_count" ]; then
                    pvc_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): " confirm
                    if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
                        log "删除 PVC: $pvc_namespace/$pvc_name"
                        kubectl delete pvc "$pvc_name" -n "$pvc_namespace"
                        if [ $? -eq 0 ]; then
                            log "✓ 成功删除 PVC: $pvc_namespace/$pvc_name"
                        else
                            error "✗ 删除 PVC 失败: $pvc_namespace/$pvc_name"
                        fi
                    else
                        log "取消删除 PVC: $pvc_namespace/$pvc_name"
                    fi
                else
                    error "无效的选择,请输入 1-${pvc_count} 之间的数字,或 a/r/b/q"
                fi
                ;;
        esac
    done
}

# 主菜单
main_menu() {
    while true; do
        echo -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_choice
        
        case "$main_choice" in
            1)
                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"
                ;;
        esac
    done
}

# 脚本开始
check_kubectl
log "连接到 Kubernetes 集群成功"
main_menu

如果有格式不正确

方法一:使用 dos2unix 转换(推荐)

安装 dos2unix

bash 复制代码
yum install -y dos2unix
bash 复制代码
使用 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

转换文件格式

bash 复制代码
dos2unix k8s-pv-pvc-manager.sh

重新运行

bash 复制代码
chmod +x k8s-pv-pvc-manager.sh
./k8s-pv-pvc-manager.sh

方法二:使用 sed 命令删除 CR 字符

bash 复制代码
# 删除 CR 字符
sed -i 's/\r$//' k8s-pv-pvc-manager.sh

重新运行

bash 复制代码
chmod +x k8s-pv-pvc-manager.sh
./k8s-pv-pvc-manager.sh

方法三:使用 vim 转换

用 vim 打开文件

bash 复制代码
vim k8s-pv-pvc-manager.sh

在 vim 中执行以下命令:

bash 复制代码
# :set ff=unix
# :wq

重新运行

bash 复制代码
chmod +x k8s-pv-pvc-manager.sh
./k8s-pv-pvc-manager.sh

方法四:重新创建脚本

如果上述方法都不行,可以直接重新创建脚本:

bash 复制代码
# 删除原文件
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; then
        error "kubectl 未安装或不在 PATH 中"
        exit 1
    fi
    
    # 检查集群连接
    if ! kubectl cluster-info &> /dev/null; then
        error "无法连接到 Kubernetes 集群"
        exit 1
    fi
}

# 获取 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; do
        if [ -n "$line" ]; then
            pvs+=("$line")
        fi
    done < <(get_pv_list)
    
    pv_count=${#pvs[@]}
    
    if [ $pv_count -eq 0 ]; then
        warn "没有找到 PV"
        return
    fi
    
    echo -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[@]}"; do
        IFS=' ' 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"
    done
    
    while true; do
        echo
        echo -e "${YELLOW}选择操作:${NC}"
        echo "  1-${pv_count} : 删除对应的 PV"
        echo "  a : 删除所有 PV"
        echo "  r : 刷新列表"
        echo "  b : 返回上级菜单"
        echo "  q : 退出程序"
        
        read -r -p "请输入选择: " choice
        
        case "$choice" in
            [qQ])
                log "退出程序"
                exit 0
                ;;
            [bB])
                return
                ;;
            [rR])
                select_and_delete_pv
                return
                ;;
            [aA])
                warn "即将删除所有 PV!此操作不可逆!"
                read -r -p "确认删除所有 PV? (输入 'YES' 确认): " confirm
                if [ "$confirm" = "YES" ]; then
                    for pv_line in "${pvs[@]}"; do
                        pv_name=$(echo "$pv_line" | awk '{print $1}')
                        log "删除 PV: $pv_name"
                        kubectl delete pv "$pv_name"
                    done
                    log "所有 PV 删除操作已完成"
                else
                    log "取消删除所有 PV"
                fi
                ;;
            *)
                if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$pv_count" ]; then
                    pv_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): " confirm
                    if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
                        log "删除 PV: $pv_name"
                        kubectl delete pv "$pv_name"
                        if [ $? -eq 0 ]; then
                            log "✓ 成功删除 PV: $pv_name"
                        else
                            error "✗ 删除 PV 失败: $pv_name"
                        fi
                    else
                        log "取消删除 PV: $pv_name"
                    fi
                else
                    error "无效的选择,请输入 1-${pv_count} 之间的数字,或 a/r/b/q"
                fi
                ;;
        esac
    done
}

# 显示并选择 PVC
select_and_delete_pvc() {
    local pvcs=()
    local pvc_count=0
    
    # 获取 PVC 列表到数组
    while IFS= read -r line; do
        if [ -n "$line" ]; then
            pvcs+=("$line")
        fi
    done < <(get_pvc_list)
    
    pvc_count=${#pvcs[@]}
    
    if [ $pvc_count -eq 0 ]; then
        warn "没有找到 PVC"
        return
    fi
    
    echo -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[@]}"; do
        IFS=' ' 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"
    done
    
    while true; do
        echo
        echo -e "${YELLOW}选择操作:${NC}"
        echo "  1-${pvc_count} : 删除对应的 PVC"
        echo "  a : 删除所有 PVC"
        echo "  r : 刷新列表"
        echo "  b : 返回上级菜单"
        echo "  q : 退出程序"
        
        read -r -p "请输入选择: " choice
        
        case "$choice" in
            [qQ])
                log "退出程序"
                exit 0
                ;;
            [bB])
                return
                ;;
            [rR])
                select_and_delete_pvc
                return
                ;;
            [aA])
                warn "即将删除所有 PVC!此操作不可逆!"
                read -r -p "确认删除所有 PVC? (输入 'YES' 确认): " confirm
                if [ "$confirm" = "YES" ]; then
                    for pvc_line in "${pvcs[@]}"; do
                        pvc_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"
                    done
                    log "所有 PVC 删除操作已完成"
                else
                    log "取消删除所有 PVC"
                fi
                ;;
            *)
                if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$pvc_count" ]; then
                    pvc_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): " confirm
                    if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
                        log "删除 PVC: $pvc_namespace/$pvc_name"
                        kubectl delete pvc "$pvc_name" -n "$pvc_namespace"
                        if [ $? -eq 0 ]; then
                            log "✓ 成功删除 PVC: $pvc_namespace/$pvc_name"
                        else
                            error "✗ 删除 PVC 失败: $pvc_namespace/$pvc_name"
                        fi
                    else
                        log "取消删除 PVC: $pvc_namespace/$pvc_name"
                    fi
                else
                    error "无效的选择,请输入 1-${pvc_count} 之间的数字,或 a/r/b/q"
                fi
                ;;
        esac
    done
}

# 主菜单
main_menu() {
    while true; do
        echo -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_choice
        
        case "$main_choice" in
            1)
                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"
                ;;
        esac
    done
}

# 脚本开始
check_kubectl
log "连接到 Kubernetes 集群成功"
main_menu
EOF

# 设置执行权限并运行
chmod +x k8s-pv-pvc-manager.sh
./k8s-pv-pvc-manager.sh
相关推荐
白小云<3 小时前
docker容器
运维·docker·容器
java_logo4 小时前
Docker 部署银河麒麟(Kylin Linux)全流程教程
linux·运维·阿里云·docker·容器·kylin
莫陌尛.4 小时前
Docker安装MongoDO
运维·docker·容器
chinesegf4 小时前
Docker篇2-用python运行项目和docker运行冲突问题
python·docker·容器
人间打气筒(Ada)4 小时前
yum安装k8s集群----基于centos7.9
java·容器·kubernetes
云动雨颤5 小时前
Docker容器使用指南:从概念到命令实操
运维·docker·容器
凯子坚持 c6 小时前
Docker镜像仓库的深度解析与实战指南
运维·docker·容器
小任今晚几点睡7 小时前
kubernetes的微服务
微服务·容器·kubernetes