一个备份、去除、新增k8s的node标签脚本
#!/bin/bash# 可自定义的标签键(默认为app.room)
LABEL_KEY=${LABEL_KEY:-"app.room"}# 功能说明:
# backup <backup_file> : 备份所有节点标签到文件
# remove <node1> [<node2>..]: 移除指定节点标签
# set <backup_file> <node1> [<node2>..] : 从备份文件恢复指定节点标签
# restore <backup_file> : 从备份文件恢复所有节点标签
# cleanall : 清理所有节点上的指定标签# 检查kubectl是否存在
check_kubectl() {if ! command -v kubectl &> /dev/null; thenecho "错误:未找到kubectl命令,请确保已安装并配置"exit 1fi
}# 显示当前使用的标签键
show_label_key() {echo "当前使用的标签键: $LABEL_KEY"echo "提示:您可以通过环境变量覆盖默认标签键,例如:"echo " export LABEL_KEY=custom.label; ./script.sh backup labels.txt"
}escape_special_chars() {local str="$1"# 使用 sed 命令对特殊字符进行转义# 以下是一些常见的特殊字符:# $ * ? [ ^ ( ) { } | & < > ~ # @ ! + = % : " ' \ / ; , . 空格local escaped_str=$(echo "$str" | sed -e 's/[$*?\[^(){}|&<>\~#@!+=%:;,.\/\ \]/\\&/g')echo "$escaped_str"
}# 获取节点标签值(使用kubectl内置功能)
get_node_label_value() {local node="$1"escape_label_key=$(escape_special_chars "$LABEL_KEY")# 使用--show-labels获取标签,然后提取特定标签值kubectl get node "$node" -o jsonpath="{.metadata.labels.$escape_label_key}" 2>/dev/null
}# 备份标签到文件
backup_labels() {local backup_file="$1"show_label_keyecho "正在备份节点标签到: $backup_file"# 清空备份文件> "$backup_file"# 获取所有节点local nodes=($(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'))local total_nodes=${#nodes[@]}local count=0for node in "${nodes[@]}"; dolocal label_value=$(get_node_label_value "$node")echo "$node $label_value" >> "$backup_file"((count++))echo -ne "已备份: $count/$total_nodes 个节点\r"doneecho -e "\n备份完成! 共备份 $total_nodes 个节点"
}# 移除节点标签
remove_labels() {shift # 跳过"remove"参数if [ $# -eq 0 ]; thenecho "错误:请指定要移除标签的节点名称"exit 1fishow_label_keyfor node in "$@"; doecho "正在移除节点 $node 的 $LABEL_KEY 标签..."kubectl label nodes "$node" "$LABEL_KEY"- >/dev/null 2>&1# 验证标签是否移除local current_value=$(get_node_label_value "$node")if [ -n "$current_value" ]; thenecho "警告: 节点 $node 标签移除失败! 当前值: $current_value"elseecho "成功: 节点 $node 标签已移除"fidone
}# 从备份文件恢复指定节点标签
restore_specific_nodes() {local backup_file="$1"shift # 跳过文件名参数if [ $# -eq 0 ]; thenecho "错误:请指定要恢复标签的节点名称"exit 1fiif [ ! -f "$backup_file" ]; thenecho "错误:备份文件 $backup_file 不存在"exit 1fishow_label_keydeclare -A label_mapwhile read -r node label; dolabel_map["$node"]=$labeldone < "$backup_file"for node in "$@"; doif [[ -n label_map["$node"] ]]; thenlocal label_value="${label_map[$node]}"if [ -z "$label_value" ]; thenecho "节点 $node 在备份中没有标签,执行移除操作..."kubectl label nodes "$node" "$LABEL_KEY"- >/dev/null 2>&1# 验证移除结果local current_value=$(get_node_label_value "$node")if [ -z "$current_value" ]; thenecho "成功: 节点 $node 标签已移除"elseecho "警告: 节点 $node 标签移除失败! 当前值: $current_value"fielseecho "正在为节点 $node 设置标签: $LABEL_KEY=$label_value"kubectl label nodes "$node" "$LABEL_KEY=$label_value" --overwrite >/dev/null# 验证设置结果local current_value=$(get_node_label_value "$node")if [ "$current_value" = "$label_value" ]; thenecho "成功: 节点 $node 标签已设置为 $label_value"elseecho "警告: 节点 $node 标签设置失败! 当前值: $current_value"fifielseecho "警告: 节点 $node 在备份文件中不存在"fidone
}# 完全恢复所有节点标签
full_restore() {local backup_file="$1"if [ ! -f "$backup_file" ]; thenecho "错误:备份文件 $backup_file 不存在"exit 1fishow_label_keyecho "正在从 $backup_file 恢复所有节点标签..."local total_lines=$(wc -l < "$backup_file")local count=0while read -r node label; doif [ -n "$label" ]; thenkubectl label nodes "$node" "$LABEL_KEY=$label" --overwrite >/dev/nullelsekubectl label nodes "$node" "$LABEL_KEY"- >/dev/null 2>&1fi((count++))echo -ne "已恢复: $count/$total_lines 个节点\r"done < "$backup_file"echo -e "\n恢复完成! 已处理 $total_lines 个节点"
}# 清理所有节点上的指定标签
clean_all_labels() {show_label_keyecho "警告: 即将清理所有节点上的 $LABEL_KEY 标签!"read -p "确认要继续吗? (y/N) " confirmif [[ "$confirm" != "y" && "$confirm" != "Y" ]]; thenecho "操作已取消"exit 0fi# 获取所有节点名称local nodes=($(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'))local total_nodes=${#nodes[@]}local count=0echo "开始清理 $total_nodes 个节点上的标签..."for node in "${nodes[@]}"; dokubectl label nodes "$node" "$LABEL_KEY"- >/dev/null 2>&1((count++))echo -ne "已处理: $count/$total_nodes 个节点\r"doneecho -e "\n清理完成! 所有节点上的 $LABEL_KEY 标签已被移除"# 验证清理结果echo "验证清理结果:"for node in "${nodes[@]}"; dolocal current_value=$(get_node_label_value "$node")if [ -n "$current_value" ]; thenecho "$node: 标签状态: $current_value (未清理)"elseecho "$node: 标签状态: <空> (已清理)"fidone
}# 主程序
check_kubectlcase "$1" inbackup)if [ -z "$2" ]; thenecho "用法: $0 backup <备份文件>"exit 1fibackup_labels "$2";;remove)remove_labels "$@";;set)if [ -z "$2" ] || [ -z "$3" ]; thenecho "用法: $0 set <备份文件> <节点1> [节点2...]"exit 1fishiftrestore_specific_nodes "$@";;restore)if [ -z "$2" ]; thenecho "用法: $0 restore <备份文件>"exit 1fifull_restore "$2";;cleanall)clean_all_labels;;*)echo "Kubernetes 节点标签管理工具"show_label_keyecho "用法:"echo " $0 backup <e份文件> 备份所有节点标签"echo " $0 remove <节点1> [节点2..] 移除指定节点标签"echo " $0 set <备份文件> <节点1> [节点2..] 从备份恢复指定节点标签"echo " $0 restore <备份文件> 从备份恢复所有节点标签"echo " $0 cleanall 清理所有节点上的指定标签"echo ""echo "环境变量:"echo " LABEL_KEY: 设置自定义标签键(默认: app.room)"exit 1;;
esac
使用示例:
- 备份标签: ./label_manager.sh backup env_labels.txt
- 去除所有标签:./label_manager.sh cleanall
- 恢复指定节点标签值:./label_manager.sh set env_labels.txt [主机1] [主机2]
- 去除指定节点标签值:./label_manager.sh remove [主机1] [主机2]
- 从备份文件中恢复所有节点标签值:./label_manager.sh restore env_labels.txt