这个问题其实比较有意思,同事早上用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