etcd自动备份以及恢复

发布于:2025-08-31 ⋅ 阅读:(28) ⋅ 点赞:(0)

目录

一、命令行备份

1. etcd备份

2. 数据恢复

3. 总结与流程梳理

错误一:Error: snapshot restore requires exactly one argument

错误二:-bash: etcdutl: 未找到命令

二、K8S自动备份

1. 构建备份工具镜像

1.1. 镜像文件准备

1.2. 编写备份环境初始化脚本

1.3. 编写Dockerfile

1.4. 构建镜像

1.5. 上传镜像

2. 编写ConfigMap

3. 编写CronJob

4. 开启备份任务

5. 查看cronjob状态

6. 检查备份


环境说明:

k8s三主三从高可用集群。

主机名 IP地址 说明
master1 192.168.48.11 master节点
master2 192.168.48.12 master节点
master3 192.168.48.13 master节点
node01 192.168.48.14 node节点
node02 192.168.48.15 node节点
node02 192.168.48.16 node节点
database 192.168.48.19 harbor仓库
192.168.48.10 VIP(虚拟IP)

安装配置信息如下表所示:

配置信息 备注
OS系统版本 openEuler-24.03
Docker版本 28.3.2
etcdctl版本 3.5.20
Kubernetes版本 1.32.7

一、命令行备份

1. etcd备份

确保所有master节点etcdctl命令可用。

master1执行:

scp -r  /usr/local/bin/etcdctl root@192.168.48.102:/usr/local/bin/
scp -r  /usr/local/bin/etcdctl root@192.168.48.103:/usr/local/bin/

所有节点执行:

cd ~
sudo mkdir -p /etcd/backup/
sudo  mkdir -p /etc/kubernetes/manifests.bak
#etcd备份的关键命令
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key snapshot save /etcd/backup/etcdbackup.db
​
ETCDCTL_API=3 etcdctl --write-out=table snapshot status /etcd/backup/etcdbackup.db

2. 数据恢复

停止etcd服务和K8s集群的相关组件 在恢复之前,需要停止etcd服务和K8s集群的相关组件(如apiserver、controller-manager、scheduler等)。由于etcd是通过静态Pod方式部署的,你可以通过重命名/etc/kubernetes/manifests/目录来停止所有由该目录下的YAML文件启动的服务。

mv /etc/kubernetes/manifests/*  /etc/kubernetes/manifests.bak

物理备份etcd:

这是为了避免我们的备份出错导致集群不可逆损伤。

mv /var/lib/etcd /var/lib/etcd.bck

etcd数据恢复关键命令:

ETCDCTL_API=3 etcdctl snapshot restore /etcd/backup/etcdbackup.db --name master1 --data-dir /var/lib/etcd --initial-cluster "master1=https://192.168.48.11:2380,master2=https://192.168.48.12:2380,master3=https://192.168.48.13:2380" --initial-cluster-token etcd-cluster-token --initial-advertise-peer-urls "https://192.168.48.11:2380"

我们来详细分解并解释这条完整的 etcd 恢复命令中每一个参数的意义和作用。

这条命令的核心目的是:使用一个备份的快照文件,在当前服务器上创建一个全新的 etcd 数据目录,并为加入一个的 etcd 集群做好初始化配置。


2.1. 参数详解

  1. ETCDCTL_API=3

  • 类型:环境变量

  • 含义:指定使用 etcdctl 工具的 v3 API

  • 为什么需要:etcdctl 为了兼容旧版本,需要明确指定使用哪个版本的 API。快照(snapshot)功能是 v3 API 引入的,所以必须设置为 3。

  1. etcdctl snapshot restore

  • 类型:主命令

  • 含义:这是 etcdctl 工具的子命令,用于从快照文件执行恢复操作。

  1. /etcd/backup/etcdbackup.db

  • 类型:位置参数

  • 含义:源快照文件的路径。这是你之前通过 etcdctl snapshot save 命令创建的备份文件的位置。

  • 说明:执行恢复操作前,必须确保这个文件存在于该路径下。

  1. --name master1

  • 类型:关键配置参数

  • 含义:指定当前节点在即将创建的新集群中的成员名称

  • 说明:这个名称必须与后面 --initial-cluster 参数列表中对应本节点 IP 的那个成员的名称一致。这里告诉系统:“我这台机器,在新集群里的名字叫 master1。”

  1. --data-dir /var/lib/etcd

  • 类型:关键配置参数

  • 含义:指定恢复操作生成的全新数据目录的路径。

  • 说明:恢复过程会创建一个全新的 etcd 数据目录。重要提示:你不能覆盖当前正在运行的 etcd 实例的数据目录。通常,你会先停止 etcd 服务,删除或移走旧的 /var/lib/etcd 目录,然后执行此命令来生成一个全新的、包含备份数据的数据目录。

  1. --initial-cluster "master1=https://192.168.48.11:2380,master2=https://192.168.48.12:2380,master3=https://192.168.48.13:2380"

  • 类型最关键的集群配置参数

  • 含义:定义新集群的初始成员列表。

  • 格式<成员名称1>=<peer-url1>, <成员名称2>=<peer-url2>, ...

  • 详细解释

    • master1=https://192.168.48.11:2380:名为 master1 的节点,其对等通信地址(Peer URL)https://192.168.48.11:2380

    • master2=...master3=...:定义了集群的另外两个节点。

    • 端口 2380:这是 etcd 节点间内部通信的专用端口(用于领导选举、数据同步、心跳等)。

  • 为什么需要:这个参数告诉正在恢复的节点:“你将要加入的这个新集群,总共有这三个成员,这是他们的名字和联系方式。”

  1. --initial-cluster-token etcd-cluster-token

  • 类型:安全配置参数

  • 含义:为新集群设置一个唯一的集群令牌。

  • 为什么需要:这个令牌用于防止新集群在初始启动时与网络中其他无关的 etcd 集群意外连接并形成同一个集群。执行恢复时,必须提供一个新的 token,因为这相当于创建一个全新的集群,而不是加入旧的。

  1. --initial-advertise-peer-urls "https://192.168.48.11:2380"

  • 类型:关键网络配置参数

  • 含义:指定本节点新集群中对外宣告的对等通信地址(Peer URL)

  • 详细解释

    • 对等通信地址用于 etcd 集群成员节点之间的通信(如心跳、数据同步、领导者选举)。

    • 这个地址必须能被集群中其他所有节点访问到。

    • 关键一致性:这个地址必须出现在上面的 --initial-cluster 参数列表中,与 --name 参数指定的名称相对应。在这个命令中,--namemaster1,所以在 --initial-cluster 列表中找 master1,它的 URL 也必须是 https://192.168.48.11:2380两者必须完全匹配,否则集群无法形成

这条命令在 master1 节点上执行后,会:

  1. 读取快照文件 /etcd/backup/etcdbackup.db 中的数据。

  2. /var/lib/etcd 目录下创建一个全新的数据结构。

  3. 将快照中的数据恢复到新目录中。

  4. 丢弃旧集群的所有成员信息和网络配置

  5. 根据你提供的参数,生成新集群的初始化配置:

    • 集群名叫 etcd-cluster-token

    • 集群有三个节点:master1, master2, master3。

    • 本节点(master1)告诉其他节点:“想和我进行内部管理通信,请用 https://192.168.48.11:2380 这个地址找我。”

执行流程:

  1. master1 (IP: 192.168.48.11) 上执行上面的命令。

  2. master2 (IP: 192.168.48.12) 上执行类似的命令,只需修改 --name--initial-advertise-peer-urls

    ETCDCTL_API=3 etcdctl snapshot restore /etcd/backup/etcdbackup.db --name master2 --data-dir /var/lib/etcd --initial-cluster "master1=https://192.168.48.11:2380,master2=https://192.168.48.12:2380,master3=https://192.168.48.13:2380" --initial-cluster-token etcd-cluster-token --initial-advertise-peer-urls "https://192.168.48.12:2380"
  3. master3 (IP: 192.168.48.103) 上执行:

    ETCDCTL_API=3 etcdctl snapshot restore /etcd/backup/etcdbackup.db --name master3 --data-dir /var/lib/etcd --initial-cluster "master1=https://192.168.48.11:2380,master2=https://192.168.48.12:2380,master3=https://192.168.48.13:2380" --initial-cluster-token etcd-cluster-token --initial-advertise-peer-urls "https://192.168.48.13:2380"

所有节点执行:

mv  /etc/kubernetes/manifests.bak/* /etc/kubernetes/manifests/
systemctl restart kubelet.service

到此,集群etcd恢复正常。

3. 总结与流程梳理

报错解决:

错误一:Error: snapshot restore requires exactly one argument

原因:这个错误是因为你的命令格式不正确。你在 --name 参数后面直接换行了,导致 etcdctl 认为 master1 是一个独立的参数,而不是 --name 的值。

错误写法(换行破坏了参数结构):

... --name 
master1 --data-dir ...

这被解析为:--name (没有值) + 参数 master1 + --data-dir ...

正确写法(确保参数和它的值在同一行,或者用 \ 转义换行符):

... --name master1 --data-dir ...

或者

... --name \
master1 --data-dir ...

错误二:-bash: etcdutl: 未找到命令

原因:你的系统上安装的 etcd 版本可能比较旧(可能是 3.4 之前),还没有提供 etcdutl 这个命令。etcdutletcdctl 的分拆是较新版本才引入的。


解决方案

使用旧的、但肯定可用的 etcdctl 命令,并确保正确的格式。

请在你的 master1 节点上执行以下完整的一行命令(不要换行):

ETCDCTL_API=3 etcdctl snapshot restore /etcd/backup/etcdbackup.db --name master1 --data-dir /var/lib/etcd --initial-cluster "master1=https://192.168.48.11:2380,master2=https://192.168.48.12:2380,master3=https://192.168.48.13:2380" --initial-cluster-token etcd-cluster-token --initial-advertise-peer-urls "https://192.168.48.11:2380"

我做的改进:

  1. 移除了错误的换行:确保 --name master1 是一个完整的单元。

  2. 给URL列表加上了引号:使用引号 "..." 将包含逗号的 --initial-cluster 参数值括起来,这是一个好习惯,可以避免 shell 解析错误。

执行流程:

  1. master1 (IP: 192.168.48.11) 上执行上面的命令。

  2. master2 (IP: 192.168.48.12) 上执行类似的命令,只需修改 --name--initial-advertise-peer-urls

    ETCDCTL_API=3 etcdctl snapshot restore /etcd/backup/etcdbackup.db --name master2 --data-dir /var/lib/etcd --initial-cluster "master1=https://192.168.48.11:2380,master2=https://192.168.48.12:2380,master3=https://192.168.48.13:2380" --initial-cluster-token etcd-cluster-token --initial-advertise-peer-urls "https://192.168.48.12:2380"
  3. master3 (IP: 192.168.48.13) 上执行:

    ETCDCTL_API=3 etcdctl snapshot restore /etcd/backup/etcdbackup.db --name master3 --data-dir /var/lib/etcd --initial-cluster "master1=https://192.168.48.11:2380,master2=https://192.168.48.12:2380,master3=https://192.168.48.13:2380" --initial-cluster-token etcd-cluster-token --initial-advertise-peer-urls "https://192.168.48.13:2380"

总结:忽略 etcdutl,坚持使用 etcdctl,并确保命令的格式正确(参数和值不被人为换行断开)。

二、K8S自动备份

不管是使用命令备份还是脚本备份,亦或是加入cronjob,我们都不能保证备份的时间节点下k8s集群正常。换句话说,我们有可能备份了故障的k8s集群,那如何解决这个问题呢?

答案是将备份任务交给K8S集群本身来做,这样,K8S只有在健康状态下才会执行备份任务。

1. 构建备份工具镜像

1.1. 镜像文件准备

cd ~
mkdir etcd-backup && cd etcd-backup
#可能是其他路径,下面以我的为例。
cp -p /usr/local/bin/etcdctl .
cp -p /usr/bin/kubectl .

1.2. 编写备份环境初始化脚本

所有master节点都要做。

cat > init-etcd-backup.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
​
# Create required hostPath directories
REQUIRED_DIRS=(
  "/data/etcd/backups" #备份存储的目录
)
​
echo "[1/2] Ensuring required directories exist..."
for d in "${REQUIRED_DIRS[@]}"; do
  if [ ! -d "$d" ]; then
    echo "Creating: $d"
    mkdir -p "$d"
  else
    echo "Exists:   $d"
  fi
  chown root:root "$d"
  chmod 755 "$d"
done
​
echo "[2/2] Labeling control-plane nodes for etcd backup..."
# Replace these names if your masters are named differently
kubectl label node master1 etcd-backup=master1 --overwrite
kubectl label node master2 etcd-backup=master2 --overwrite
kubectl label node master3 etcd-backup=master3 --overwrite
​
echo -e "\e[32mInitialization complete.\e[0m"
EOF

执行这个脚本

所有master节点都要做。

chmod +x init-etcd-backup.sh
sh init-etcd-backup.sh

1.3. 编写Dockerfile

FROM ubuntu:22.04
​
# 安装常用工具(不安装 etcd-client,避免与自带 etcdctl 冲突)
RUN apt-get update && \
    apt-get install -y curl wget vim unzip tar net-tools && \
    rm -rf /var/lib/apt/lists/*
​
# 如需要 kubectl,请保留;若不需要可删除以下两行以减小镜像
COPY kubectl /bin
RUN chmod +x /bin/kubectl
​
# 固定使用随项目提供的 etcdctl 二进制
COPY etcdctl /bin
RUN chmod +x /bin/etcdctl
​

1.4. 构建镜像

docker build -t etcd-backup:latest .

1.5. 上传镜像

打标签,推送到harbor仓库。

docker tag docker.io/library/etcd-backup:latest 192.168.48.19/etcd-backup/etcd-backup:latest
docker push 192.168.48.19/etcd-backup/etcd-backup:latest

2. 编写ConfigMap

vim etcd-backup-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: etcd-backup-config
  namespace: kube-system
data:
  backup_etcd.sh: |
    #!/bin/bash
    set -euo pipefail
​
    # 通过本机网络访问 etcd(CronJob 使用 hostNetwork)
    ENDPOINT="https://127.0.0.1:2379"
​
    # 证书路径(kubeadm 默认路径)
    ETCD_CA="/etc/kubernetes/pki/etcd/ca.crt"
    ETCD_CERT="/etc/kubernetes/pki/apiserver-etcd-client.crt"
    ETCD_KEY="/etc/kubernetes/pki/apiserver-etcd-client.key"
​
    # 日期
    current_date=$(date +"%Y_%m_%d_%H_%M_%S")
​
    # 备份目录
    mkdir -p /etcd/backup/
    chmod 755 /etcd/backup/
​
    SNAPSHOT="/etcd/backup/etcd-127.0.0.1-${current_date}.db"
    echo "开始备份到: ${SNAPSHOT}"
​
    etcdctl --endpoints="${ENDPOINT}" \
      --cacert="${ETCD_CA}" \
      --cert="${ETCD_CERT}" \
      --key="${ETCD_KEY}" \
      snapshot save "${SNAPSHOT}"
​
    echo "备份完成: ${SNAPSHOT}"
​
    # 清理超过3天的 .db 文件
    find /etcd/backup/ -type f -name '*.db' -mtime +3 -delete
​
    echo "清理完成,仅保留最近三天的快照"

3. 编写CronJob

由于我的是高可用k8s集群,我把master节点的内置etcd全备份了。理论上只要备份一个master节点的etcd就行,但是为了保险起见,我把所有maser节点的etcd都做了备份,所以我写了3个cronjob。内容都是差不多的,关键在于备份的时间要错开,避免并发。

master1备份的cronjob

vim etcd-backup-cronjob-master1.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: etcd-backup-master1
  namespace: kube-system
spec:
  schedule: "0 23 * * *"          # 每日23:00(UTC)
  concurrencyPolicy: Forbid       # 避免并发
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          hostNetwork: true
          dnsPolicy: ClusterFirstWithHostNet
          nodeSelector:
            etcd-backup: "master1"  # 绑定第1个master
          tolerations:
            - key: "node-role.kubernetes.io/control-plane"
              operator: "Exists"
              effect: "NoSchedule"
            - key: "node-role.kubernetes.io/master"
              operator: "Exists"
              effect: "NoSchedule"
          containers:
            - name: etcd-backup
              image: 192.168.48.19/etcd-backup/etcd-backup:latest
              imagePullPolicy: IfNotPresent
              securityContext:
                runAsUser: 0
                runAsNonRoot: false
                readOnlyRootFilesystem: true
                allowPrivilegeEscalation: false
                capabilities:
                  drop: ["ALL"]
              resources:
                requests:
                  cpu: "50m"
                  memory: "128Mi"
                limits:
                  cpu: "500m"
                  memory: "1Gi"
              env:
              - name: ETCDCTL_API
                value: "3"
              command: ['bash', '-c']
              args:
                - |
                  bash /usr/local/bin/backup_etcd.sh
              volumeMounts:
                - mountPath: /etc/localtime
                  name: localtime
                  readOnly: true
                - mountPath: /etc/kubernetes/pki
                  name: kube-pki
                  readOnly: true
                - mountPath: /etcd/backup         # 改为脚本用的目录
                  name: etcd-bak
                - mountPath: /usr/local/bin/backup_etcd.sh
                  name: backup-script
                  subPath: backup_etcd.sh
                  readOnly: true
          volumes:
            - hostPath:
                path: /etc/localtime
                type: ''
              name: localtime
            - hostPath:
                path: /etc/kubernetes/pki
                type: ''
              name: kube-pki
            - hostPath:
                path: /data/etcd/backups          # 宿主机保存目录
                type: ''
              name: etcd-bak
            - configMap:
                name: etcd-backup-config
              name: backup-script
          restartPolicy: OnFailure

master2备份的cronjob

vim etcd-backup-cronjob-master2.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: etcd-backup-master2
  namespace: kube-system
spec:
  schedule: "5 23 * * *"          # 每日23:05(UTC)
  concurrencyPolicy: Forbid       # 避免并发
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          hostNetwork: true
          dnsPolicy: ClusterFirstWithHostNet
          nodeSelector:
            etcd-backup: "master2"  # 绑定第2个master
          tolerations:
            - key: "node-role.kubernetes.io/control-plane"
              operator: "Exists"
              effect: "NoSchedule"
            - key: "node-role.kubernetes.io/master"
              operator: "Exists"
              effect: "NoSchedule"
          containers:
            - name: etcd-backup
              image: 192.168.48.19/etcd-backup/etcd-backup:latest
              imagePullPolicy: IfNotPresent
              securityContext:
                runAsUser: 0
                runAsNonRoot: false
                readOnlyRootFilesystem: true
                allowPrivilegeEscalation: false
                capabilities:
                  drop: ["ALL"]
              resources:
                requests:
                  cpu: "50m"
                  memory: "128Mi"
                limits:
                  cpu: "500m"
                  memory: "1Gi"
              env:
              - name: ETCDCTL_API
                value: "3"
              command: ['bash', '-c']
              args:
                - |
                  bash /usr/local/bin/backup_etcd.sh
              volumeMounts:
                - mountPath: /etc/localtime
                  name: localtime
                  readOnly: true
                - mountPath: /etc/kubernetes/pki
                  name: kube-pki
                  readOnly: true
                - mountPath: /etcd/backup         # 改为脚本用的目录
                  name: etcd-bak
                - mountPath: /usr/local/bin/backup_etcd.sh
                  name: backup-script
                  subPath: backup_etcd.sh
                  readOnly: true
          volumes:
            - hostPath:
                path: /etc/localtime
                type: ''
              name: localtime
            - hostPath:
                path: /etc/kubernetes/pki
                type: ''
              name: kube-pki
            - hostPath:
                path: /data/etcd/backups          # 宿主机保存目录
                type: ''
              name: etcd-bak
            - configMap:
                name: etcd-backup-config
              name: backup-script
          restartPolicy: OnFailure

master3备份的cronjob

vim etcd-backup-cronjob-master3.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: etcd-backup-master3
  namespace: kube-system
spec:
  schedule: "10 23 * * *"          # 每日23:10(UTC)
  concurrencyPolicy: Forbid       # 避免并发
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          hostNetwork: true
          dnsPolicy: ClusterFirstWithHostNet
          nodeSelector:
            etcd-backup: "master3"  # 绑定第3个master
          tolerations:
            - key: "node-role.kubernetes.io/control-plane"
              operator: "Exists"
              effect: "NoSchedule"
            - key: "node-role.kubernetes.io/master"
              operator: "Exists"
              effect: "NoSchedule"
          containers:
            - name: etcd-backup
              image: 192.168.48.19/etcd-backup/etcd-backup:latest
              imagePullPolicy: IfNotPresent
              securityContext:
                runAsUser: 0
                runAsNonRoot: false
                readOnlyRootFilesystem: true
                allowPrivilegeEscalation: false
                capabilities:
                  drop: ["ALL"]
              resources:
                requests:
                  cpu: "50m"
                  memory: "128Mi"
                limits:
                  cpu: "500m"
                  memory: "1Gi"
              env:
              - name: ETCDCTL_API
                value: "3"
              command: ['bash', '-c']
              args:
                - |
                  bash /usr/local/bin/backup_etcd.sh
              volumeMounts:
                - mountPath: /etc/localtime
                  name: localtime
                  readOnly: true
                - mountPath: /etc/kubernetes/pki
                  name: kube-pki
                  readOnly: true
                - mountPath: /etcd/backup         # 改为脚本用的目录
                  name: etcd-bak
                - mountPath: /usr/local/bin/backup_etcd.sh
                  name: backup-script
                  subPath: backup_etcd.sh
                  readOnly: true
          volumes:
            - hostPath:
                path: /etc/localtime
                type: ''
              name: localtime
            - hostPath:
                path: /etc/kubernetes/pki
                type: ''
              name: kube-pki
            - hostPath:
                path: /data/etcd/backups          # 宿主机保存目录
                type: ''
              name: etcd-bak
            - configMap:
                name: etcd-backup-config
              name: backup-script
          restartPolicy: OnFailure

现在目录下包含以下文件:

[root@master1 etcd-backup]# ls
Dockerfile                        etcd-backup-cronjob-master2.yaml  init-etcd-backup.sh
etcd-backup-config.yaml           etcd-backup-cronjob-master3.yaml  kubectl
etcd-backup-cronjob-master1.yaml  etcdctl

4. 开启备份任务

[root@master1 etcd-backup]# kubectl apply -f ./
configmap/etcd-backup-config created
cronjob.batch/etcd-backup-master1 created
cronjob.batch/etcd-backup-master2 created
cronjob.batch/etcd-backup-master3 created

5. 查看cronjob状态

[root@master1 etcd-backup]# kubectl get cronjobs.batch -n kube-system 
NAME                  SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
etcd-backup-master1   0 20 * * *    <none>     False     0        <none>          59s
etcd-backup-master2   5 20 * * *    <none>     False     0        <none>          59s
etcd-backup-master3   10 20 * * *   <none>     False     0        <none>          59s
​

我们可以马上执行这三个cronjob看看效果。

kubectl create job --from=cronjob/etcd-backup-master1 etcd-backup-manual-$(date +%s) -n kube-system
kubectl create job --from=cronjob/etcd-backup-master2 etcd-backup-manual-$(date +%s) -n kube-system
kubectl create job --from=cronjob/etcd-backup-master3 etcd-backup-manual-$(date +%s) -n kube-system

查看是否备份完毕。

[root@master1 etcd-backup]# kubectl get pod -n kube-system | grep etcd-backup-manual
etcd-backup-manual-1756482367-5hprb        0/1     Completed   0               29s
etcd-backup-manual-1756482375-7rgmv        0/1     Completed   0               21s
etcd-backup-manual-1756482381-smn2l        0/1     Completed   0               15s

显示Completed,说明备份成功了,到备份目录查看。

[root@master1 etcd-backup]# cd /data/etcd/backups/
[root@master1 backups]# ls
etcd-127.0.0.1-2025_08_26_19_40_08.db  etcd-127.0.0.1-2025_08_29_22_56_33.db
etcd-127.0.0.1-2025_08_27_09_51_40.db  etcd-127.0.0.1-2025_08_29_23_46_08.db

可以看到保留了三天以内的(其他两天是我之前备份的),和我们预想的一样。

6. 检查备份

在master节点查看备份是否可用

[root@master1 backups]# ETCDCTL_API=3 etcdctl --write-out=table snapshot status /data/etcd/backups/etcd-127.0.0.1-2025_08_29_23_46_08.db
Deprecated: Use `etcdutl snapshot status` instead.
​
+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| e30f1e5f |  1172570 |       2219 |      19 MB |
+----------+----------+------------+------------+
[root@master2 ~]# ETCDCTL_API=3 etcdctl --write-out=table snapshot status /data/etcd/backups/etcd-127.0.0.1-2025_08_29_23_46_15.db 
Deprecated: Use `etcdutl snapshot status` instead.
​
+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| cde97ef5 |  1172616 |       2267 |      20 MB |
+----------+----------+------------+------------+
[root@master3 ~]# ETCDCTL_API=3 etcdctl --write-out=table snapshot status /data/etcd/backups/etcd-127.0.0.1-2025_08_29_23_46_21.db 
Deprecated: Use `etcdutl snapshot status` instead.
​
+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| bbc38825 |  1172663 |       2311 |      18 MB |
+----------+----------+------------+------------+
​

到此,k8s自动备份就完成了。恢复方式和前文一样,这里就不再演示了。