这个问题其实比较有意思,同事早上用k9s修改Deployment的时候误删了一个deployment,这下麻烦了。那其实自己也有过类似操作,迁移的时候误删过influxdb,最后考古才弄回来,也误删过一个ns的secret,都是大麻烦!
其实系统是有velero备份的,但是从那里面去弄出单独一个ns的deploy进行恢复,怎么也来不及,那幸好有每日资源备份,直接拿过来重建即可。分享一下脚本,那注意一下,因为主节点的etcd也是非常要命的东西,也必须备一下,防止主节点脑裂,到时候可以用备份进行恢复。
1#!/bin/bash
2
3export KUBECONFIG=/root/.kube/config
4export PATH=/usr/local/bin:$PATH
5
6# K8s 资源备份脚本
7# 目标:遍历所有命名空间,将 Deployment, Secret, Ingress, 和 Service 导出为 YAML 文件。
8
9# 设置输出目录
10OUTPUT_DIR="/root/k8s_deployments_backup/$(date +%Y%m%d)"
11# 要备份的资源类型及其对应的 kubectl 别名
12# 注意:Secret 资源会备份所有类型,包括自动生成的 Service Account Tokens。
13RESOURCE_TYPES=("deployments" "secrets" "ingresses" "services")
14
15# 确保脚本在遇到错误时立即退出
16set -e
17
18echo "--- 正在创建输出目录: $OUTPUT_DIR ---"
19mkdir -p "$OUTPUT_DIR"
20
21# ----------------------------------------------------
22# 核心函数:备份指定类型的资源
23# 参数: $1 = 资源类型 (如 deployment), $2 = 命名空间, $3 = 输出目录
24# ----------------------------------------------------
25backup_resource() {
26 local TYPE=$1
27 local NAMESPACE=$2
28 local DIR=$3
29
30 # 获取当前命名空间中所有该类型资源的名称
31 # 使用 2>/dev/null 隐藏找不到资源时的错误信息
32 local RESOURCES=$(kubectl get "$TYPE" -n "$NAMESPACE" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null)
33
34 if [ -z "$RESOURCES" ]; then
35 echo " [信息] 命名空间 $NAMESPACE 中未找到 $TYPE。"
36 return
37 fi
38
39 echo " -> 找到 ${#RESOURCES[@]} 个 $TYPE,正在导出..."
40
41 # 遍历每个资源并保存 YAML
42 for RESOURCE in $RESOURCES; do
43 # 文件名格式: namespace-resource_type-resourcename.yaml
44 local FILE_NAME="${NAMESPACE}-${TYPE}-${RESOURCE}.yaml"
45 local FILE_PATH="$DIR/$FILE_NAME"
46
47 # 使用 kubectl get 获取 YAML,并通过管道和 sed 清理元数据字段
48 kubectl get "$TYPE" "$RESOURCE" -n "$NAMESPACE" -o yaml --ignore-not-found |
49 # 清理元数据字段,使 YAML 更干净,便于重新应用
50 sed '/^ creationTimestamp:/d' |
51 sed '/^ resourceVersion:/d' |
52 sed '/^ uid:/d' |
53 sed '/^ selfLink:/d' |
54 sed '/^ status:/d' \
55 > "$FILE_PATH"
56
57 # 检查 Secret 是否为 Service Account Token,如果是,则发出警告
58 if [ "$TYPE" == "secrets" ] && grep -q 'kubernetes.io/service-account.name' "$FILE_PATH"; then
59 echo " [警告] Secret $RESOURCE 是 Service Account Token,通常不需要备份。"
60 fi
61 done
62}
63
64# 1. 获取所有命名空间 (Namespace)
65NAMESPACES=$(kubectl get ns -o jsonpath='{.items[*].metadata.name}')
66
67if [ -z "$NAMESPACES" ]; then
68 echo "错误:未找到任何命名空间。请检查 kubectl 配置和集群连接。"
69 exit 1
70fi
71
72echo "找到以下命名空间: $NAMESPACES"
73echo "----------------------------------------------------"
74
75# 2. 遍历每个命名空间和资源类型
76for NAMESPACE in $NAMESPACES; do
77 echo "--- 处理命名空间: $NAMESPACE ---"
78
79 for TYPE in "${RESOURCE_TYPES[@]}"; do
80 backup_resource "$TYPE" "$NAMESPACE" "$OUTPUT_DIR"
81 done
82
83 echo "--- 命名空间 $NAMESPACE 处理完成 ---"
84done
85
86ETCDCTL_API=3 etcdctl \
87--endpoints=https://10.10.240.3:2379 \
88--cacert=/etc/ssl/etcd/ca.pem \
89--cert=/etc/ssl/etcd/etcd-client.pem \
90--key=/etc/ssl/etcd/etcd-client-key.pem \
91snapshot save $OUTPUT_DIR/etcd-`date +%Y%m%d`-snapshot.db
92
93echo "===================================================="
94echo "✅ 所有指定资源已成功备份到目录: $OUTPUT_DIR"
95echo "===================================================="
96
97exit 0