这个问题其实比较有意思,同事早上用k9s修改Deployment的时候误删了一个deployment,这下麻烦了。那其实自己也有过类似操作,迁移的时候误删过influxdb,最后考古才弄回来,也误删过一个ns的secret,都是大麻烦!
其实系统是有velero备份的,但是从那里面去弄出单独一个ns的deploy进行恢复,怎么也来不及,那幸好有每日资源备份,直接拿过来重建即可。分享一下脚本,那注意一下,因为主节点的etcd也是非常要命的东西,也必须备一下,防止主节点脑裂,到时候可以用备份进行恢复。
#!/bin/bash export KUBECONFIG=/root/.kube/config export PATH=/usr/local/bin:$PATH # K8s 资源备份脚本 # 目标:遍历所有命名空间,将 Deployment, Secret, Ingress, 和 Service 导出为 YAML 文件。 # 设置输出目录 OUTPUT_DIR="/root/k8s_deployments_backup/$(date +%Y%m%d)" # 要备份的资源类型及其对应的 kubectl 别名 # 注意:Secret 资源会备份所有类型,包括自动生成的 Service Account Tokens。 RESOURCE_TYPES=("deployments" "secrets" "ingresses" "services") # 确保脚本在遇到错误时立即退出 set -e echo "--- 正在创建输出目录: $OUTPUT_DIR ---" mkdir -p "$OUTPUT_DIR" # ---------------------------------------------------- # 核心函数:备份指定类型的资源 # 参数: $1 = 资源类型 (如 deployment), $2 = 命名空间, $3 = 输出目录 # ---------------------------------------------------- backup_resource() { local TYPE=$1 local NAMESPACE=$2 local DIR=$3 # 获取当前命名空间中所有该类型资源的名称 # 使用 2>/dev/null 隐藏找不到资源时的错误信息 local RESOURCES=$(kubectl get "$TYPE" -n "$NAMESPACE" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null) if [ -z "$RESOURCES" ]; then echo " [信息] 命名空间 $NAMESPACE 中未找到 $TYPE。" return fi echo " -> 找到 ${#RESOURCES[@]} 个 $TYPE,正在导出..." # 遍历每个资源并保存 YAML for RESOURCE in $RESOURCES; do # 文件名格式: namespace-resource_type-resourcename.yaml local FILE_NAME="${NAMESPACE}-${TYPE}-${RESOURCE}.yaml" local FILE_PATH="$DIR/$FILE_NAME" # 使用 kubectl get 获取 YAML,并通过管道和 sed 清理元数据字段 kubectl get "$TYPE" "$RESOURCE" -n "$NAMESPACE" -o yaml --ignore-not-found | # 清理元数据字段,使 YAML 更干净,便于重新应用 sed '/^ creationTimestamp:/d' | sed '/^ resourceVersion:/d' | sed '/^ uid:/d' | sed '/^ selfLink:/d' | sed '/^ status:/d' \ > "$FILE_PATH" # 检查 Secret 是否为 Service Account Token,如果是,则发出警告 if [ "$TYPE" == "secrets" ] && grep -q 'kubernetes.io/service-account.name' "$FILE_PATH"; then echo " [警告] Secret $RESOURCE 是 Service Account Token,通常不需要备份。" fi done } # 1. 获取所有命名空间 (Namespace) NAMESPACES=$(kubectl get ns -o jsonpath='{.items[*].metadata.name}') if [ -z "$NAMESPACES" ]; then echo "错误:未找到任何命名空间。请检查 kubectl 配置和集群连接。" exit 1 fi echo "找到以下命名空间: $NAMESPACES" echo "----------------------------------------------------" # 2. 遍历每个命名空间和资源类型 for NAMESPACE in $NAMESPACES; do echo "--- 处理命名空间: $NAMESPACE ---" for TYPE in "${RESOURCE_TYPES[@]}"; do backup_resource "$TYPE" "$NAMESPACE" "$OUTPUT_DIR" done echo "--- 命名空间 $NAMESPACE 处理完成 ---" done ETCDCTL_API=3 etcdctl \ --endpoints=https://10.10.240.3:2379 \ --cacert=/etc/ssl/etcd/ca.pem \ --cert=/etc/ssl/etcd/etcd-client.pem \ --key=/etc/ssl/etcd/etcd-client-key.pem \ snapshot save $OUTPUT_DIR/etcd-`date +%Y%m%d`-snapshot.db echo "====================================================" echo "✅ 所有指定资源已成功备份到目录: $OUTPUT_DIR" echo "====================================================" exit 0