etcd cluster 备份恢复实践

数据在手,天下我有。

。。。不善言语,不知道写点儿什么好,那就来点儿操作记录吧。

备份

创建 etcd cluster

创建 3 个 member 的 etcd cluster

如下 yaml 文件创建的 etcd 集群 


apiVersion: v1
kind: Service
metadata:
  name: etcd-headless
  labels:
    component: etcd-headless
spec:
  clusterIP: None
  ports:
  - port: 2379
    name: client
  - port: 2380
    name: peer
  selector:
    component: etcd
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: etcd
  labels:
    component: etcd
spec:
  selector:
    matchLabels:
      component: etcd
  serviceName: etcd-headless
  replicas: 3
  template:
    metadata:
      labels:
        component: etcd
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: component
                operator: In
                values: ["etcd"]
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: etcd
        securityContext:
          privileged: true
          capabilities:
            add:
            - IPC_LOCK
        image: quay.io/coreos/etcd:v3.5.0
        imagePullPolicy: IfNotPresent
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: NETWORK_HOST
          value: "0.0.0.0"
        - name: ETCD_CLUSTER
          value: "etcd-0=http://etcd-0.etcd-headless:2380,etcd-1=http://etcd-1.etcd-headless:2380,etcd-2=http://etcd-2.etcd-headless:2380"
        command: ["sh", "-c", "etcd -name $POD_NAME -data-dir /var/lib/etcd -advertise-client-urls http://$POD_NAME.etcd-headless:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-advertise-peer-urls http://$POD_NAME.etcd-headless:2380 -initial-cluster-token etcd-cluster -initial-cluster $ETCD_CLUSTER -initial-cluster-state new"]
        resources:
          requests:
            memory: "2048Mi"
            cpu: "1000m"
        ports:
        - containerPort: 2379
          name: service-port
        - containerPort: 2380
          name: peer-port
        livenessProbe:
          tcpSocket:
            port: service-port
          initialDelaySeconds: 20
          periodSeconds: 10
        volumeMounts:
        - name: data
          mountPath: /var/lib/etcd
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      storageClassName: rook-cephfs
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 32Gi
root@node1:/# kubectl -n restore apply -f etcd-cluster-sts.yaml
service/etcd-headless created
statefulset.apps/etcd created
root@node1:/# kubectl -n restore get pods
NAME     READY   STATUS              RESTARTS   AGE
etcd-0   1/1     Running             0          15s
etcd-1   0/1     ContainerCreating   0          10s

检查集群状态

root@node1:/# kubectl -n restore get pods
NAME     READY   STATUS    RESTARTS   AGE
etcd-0   1/1     Running   0          54s
etcd-1   1/1     Running   0          49s
etcd-2   1/1     Running   0          38s
root@node1:/# kubectl -n restore exec -it etcd-0  -- etcdctl member list -w table
+------------------+---------+--------+----------------------------------+----------------------------------+------------+
|        ID        | STATUS  |  NAME  |            PEER ADDRS            |           CLIENT ADDRS           | IS LEARNER |
+------------------+---------+--------+----------------------------------+----------------------------------+------------+
| 3f54ac025181a433 | started | etcd-1 | http://etcd-1.etcd-headless:2380 | http://etcd-1.etcd-headless:2379 |      false |
| 7c5422fe4922f16f | started | etcd-2 | http://etcd-2.etcd-headless:2380 | http://etcd-2.etcd-headless:2379 |      false |
| e4ad7553eba80d25 | started | etcd-0 | http://etcd-0.etcd-headless:2380 | http://etcd-0.etcd-headless:2379 |      false |
+------------------+---------+--------+----------------------------------+----------------------------------+------------+
root@node1:/# kubectl -n restore exec -it etcd-0  -- etcdctl --endpoints="http://etcd-1.etcd-headless:2379,http://etcd-2.etcd-headless:2379,http://etcd-0.etcd-headless:2379" endpoint health -w table
+----------------------------------+--------+------------+-------+
|             ENDPOINT             | HEALTH |    TOOK    | ERROR |
+----------------------------------+--------+------------+-------+
| http://etcd-0.etcd-headless:2379 |   true | 4.038685ms |       |
| http://etcd-1.etcd-headless:2379 |   true | 4.582809ms |       |
| http://etcd-2.etcd-headless:2379 |   true | 4.543312ms |       |
+----------------------------------+--------+------------+-------+
rroot@node1:/# kubectl -n restore exec -it etcd-0  -- etcdctl --endpoints="http://etcd-1.etcd-headless:2379,http://etcd-2.etcd-headless:2379,http://etcd-0.etcd-headless:2379" endpoint status -w table
+----------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|             ENDPOINT             |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://etcd-1.etcd-headless:2379 | 3f54ac025181a433 |   3.5.0 |   25 kB |     false |      false |         2 |         11 |                 11 |        |
| http://etcd-2.etcd-headless:2379 | 7c5422fe4922f16f |   3.5.0 |   20 kB |     false |      false |         2 |         11 |                 11 |        |
| http://etcd-0.etcd-headless:2379 | e4ad7553eba80d25 |   3.5.0 |   20 kB |      true |      false |         2 |         11 |                 11 |        |
+----------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

 来些伪数据

root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl put foo bar
OK
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl put foo1 bar1
OK
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl put foo2 bar2
OK
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl put foo3 bar3
OK
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl put foo4 bar4
OK
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl put foo5 bar5
OK
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl get --prefix foo
foo
bar
foo1
bar1
foo2
bar2
foo3
bar3
foo4
bar4
foo5
bar5

备份

使用 etcdctl snapshot 命令备份并将备份的文件 copy 出来

root@node1:/# kubectl -n restore exec -it etcd-0  -- etcdctl --endpoints=http://127.0.0.1:2379  snapshot save /tmp/etcd-snapshot.db
{"level":"info","ts":1631784628.0328338,"caller":"snapshot/v3_snapshot.go:68","msg":"created temporary db file","path":"/tmp/etcd-snapshot.db.part"}
{"level":"info","ts":1631784628.0337093,"logger":"client","caller":"v3/maintenance.go:211","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":1631784628.0337427,"caller":"snapshot/v3_snapshot.go:76","msg":"fetching snapshot","endpoint":"http://127.0.0.1:2379"}
{"level":"info","ts":1631784628.0348232,"logger":"client","caller":"v3/maintenance.go:219","msg":"completed snapshot read; closing"}
{"level":"info","ts":1631784628.0354915,"caller":"snapshot/v3_snapshot.go:91","msg":"fetched snapshot","endpoint":"http://127.0.0.1:2379","size":"20 kB","took":"now"}
{"level":"info","ts":1631784628.0355432,"caller":"snapshot/v3_snapshot.go:100","msg":"saved","path":"/tmp/etcd-snapshot.db"}
Snapshot saved at /tmp/etcd-snapshot.db
root@node1:/# kubectl -n restore exec -it etcd-0  -- etcdctl --endpoints=http://127.0.0.1:2379  snapshot status /tmp/etcd-snapshot.db -w table
Deprecated: Use `etcdutl snapshot status` instead.

+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 4b08d5e1 |        7 |         14 |      20 kB |
+----------+----------+------------+------------+
root@node1:/# kubectl -n restore cp etcd-0:/tmp/etcd-snapshot.db etcd-snapshot.db
tar: Removing leading `/' from member names
root@node1:/# ls -l etcd-snapshot.db
-rw-r--r-- 1 root root 20512 Sep 16 16:51 etcd-snapshot.db

摧毁集群

哈哈,开始干坏事情咯。按照自己喜欢的姿势去破环吧。记得把 pvc 一起删掉哟。

root@node1:/# kubectl -n restore delete -f etcd-cluster-sts.yaml
service "etcd-headless" deleted
statefulset.apps "etcd" deleted
root@node1:/# kubectl -n restore get pods
NAME     READY   STATUS        RESTARTS   AGE
etcd-0   1/1     Terminating   0          5m50s
etcd-1   1/1     Terminating   0          5m45s
etcd-2   1/1     Terminating   0          5m34s
root@node1:/# kubectl -n restore get pods
No resources found in restore namespace.
root@node1:/# kubectl -n restore get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-etcd-0   Bound    pvc-4890a3ff-8794-4181-bbb5-83b433a64ef2   32Gi       RWO            rook-cephfs    6m39s
data-etcd-1   Bound    pvc-82571561-688f-43d6-85ca-49ea6c7068ad   32Gi       RWO            rook-cephfs    6m34s
data-etcd-2   Bound    pvc-86981a8e-db4e-4b63-8d8a-850e98a19aa9   32Gi       RWO            rook-cephfs    6m23s
root@node1:/# kubectl -n restore delete pvc --all
persistentvolumeclaim "data-etcd-0" deleted
persistentvolumeclaim "data-etcd-1" deleted
persistentvolumeclaim "data-etcd-2" deleted
root@node1:/# kubectl -n restore get pvc
No resources found in restore namespace.

恢复

新建集群

通过上面的方式新建,全新集群,没有数据。

root@node1:/# kubectl -n restore apply -f etcd-cluster-sts.yaml
service/etcd-headless created
statefulset.apps/etcd created
...
...
...
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl get --prefix foo
root@node1:/#

停止集群

把 replicas 改为 0 即可

root@node1:/# kubectl -n restore patch statefulsets.apps etcd -p  '{"spec":{"replicas":0}}'
statefulset.apps/etcd patched
...
...
...
root@node1:/# kubectl -n restore get pods
No resources found in restore namespace.
root@node1:/# kubectl -n restore get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-etcd-0   Bound    pvc-6cd53023-8fcf-4602-b7a3-d69239f78016   32Gi       RWO            rook-cephfs    3m24s
data-etcd-1   Bound    pvc-86853c83-88a6-465d-9cfd-37877a2ab2ac   32Gi       RWO            rook-cephfs    3m4s
data-etcd-2   Bound    pvc-519249f9-027c-4179-9812-9b6fce9ff77a   32Gi       RWO            rook-cephfs    2m53s

创建恢复数据的pod
 

不要忘记把上面的 pvc 挂载进去。

apiVersion: v1
kind: Pod
metadata:
  name: restore-pod
  labels:
    app: restore-etcd
spec:
  containers:
  - name: restore
    image: quay.io/coreos/etcd:v3.5.0
    command: ['sh', '-c', 'sleep inf']
    volumeMounts:
    - mountPath: "/var/lib/etcd0"
      name: etcd-0
    - mountPath: "/var/lib/etcd1"
      name: etcd-1
    - mountPath: "/var/lib/etcd2"
      name: etcd-2
  volumes:
    - name: etcd-0
      persistentVolumeClaim:
        claimName: data-etcd-0
    - name: etcd-1
      persistentVolumeClaim:
        claimName: data-etcd-1
    - name: etcd-2
      persistentVolumeClaim:
        claimName: data-etcd-2
root@node1:/# kubectl -n restore apply -f restore.yaml
pod/restore-pod created
root@node1:/# kubectl -n restore get pods
NAME          READY   STATUS    RESTARTS   AGE
restore-pod   1/1     Running   0          39s

开始恢复

root@node1:/# kubectl -n restore cp etcd-snapshot.db restore-pod:/tmp/
root@node1:/# kubectl -n restore exec -it restore-pod -- etcdctl snapshot status /tmp/etcd-snapshot.db -w table
Deprecated: Use `etcdutl snapshot status` instead.

+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 4b08d5e1 |        7 |         14 |      20 kB |
+----------+----------+------------+------------+
root@node1:/# kubectl -n restore exec -it restore-pod -- sh
# echo 127.0.0.1 etcd-0.etcd-headless >>/etc/hosts
# echo 127.0.0.1 etcd-1.etcd-headless >>/etc/hosts
# echo 127.0.0.1 etcd-2.etcd-headless >>/etc/hosts
# cat /etc/hosts
# Kubernetes-managed hosts file.
...
127.0.0.1 etcd-0.etcd-headless
127.0.0.1 etcd-1.etcd-headless
127.0.0.1 etcd-2.etcd-headless
### 清空 pvc 中的数据
# rm -rf /var/lib/etcd0/* /var/lib/etcd1/* /var/lib/etcd2/*
# etcdctl snapshot restore /tmp/etcd-snapshot.db \
  --name etcd-0 \
  --initial-cluster etcd-0=http://etcd-0.etcd-headless:2380,etcd-1=http://etcd-1.etcd-headless:2380,etcd-2=http://etcd-2.etcd-headless:2380 \
  --initial-advertise-peer-urls http://etcd-0.etcd-headless:2380
# etcdctl snapshot restore /tmp/etcd-snapshot.db \
  --name etcd-1 \
  --initial-cluster etcd-0=http://etcd-0.etcd-headless:2380,etcd-1=http://etcd-1.etcd-headless:2380,etcd-2=http://etcd-2.etcd-headless:2380 \
  --initial-advertise-peer-urls http://etcd-1.etcd-headless:2380
# etcdctl snapshot restore /tmp/etcd-snapshot.db \
  --name etcd-2 \
  --initial-cluster etcd-0=http://etcd-0.etcd-headless:2380,etcd-1=http://etcd-1.etcd-headless:2380,etcd-2=http://etcd-2.etcd-headless:2380 \
  --initial-advertise-peer-urls http://etcd-2.etcd-headless:2380
# mv etcd-0.etcd/member /var/lib/etcd0
# mv etcd-1.etcd/member /var/lib/etcd1
# mv etcd-2.etcd/member /var/lib/etcd2
# exit
root@node1:/# kubectl -n restore delete -f restore.yaml
pod "restore-pod" deleted

启动集群


root@node1:/# kubectl -n restore patch statefulsets.apps etcd -p  '{"spec":{"replicas":3}}'
statefulset.apps/etcd patched
root@node1:/# kubectl -n restore get pods
NAME     READY   STATUS              RESTARTS   AGE
etcd-0   1/1     Running             0          12s
etcd-1   0/1     ContainerCreating   0          4s
root@node1:/# kubectl -n restore get pods
NAME     READY   STATUS    RESTARTS   AGE
etcd-0   1/1     Running   0          32s
etcd-1   1/1     Running   0          24s
etcd-2   1/1     Running   0          7s
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl member list -w table
+------------------+---------+--------+----------------------------------+----------------------------------+------------+
|        ID        | STATUS  |  NAME  |            PEER ADDRS            |           CLIENT ADDRS           | IS LEARNER |
+------------------+---------+--------+----------------------------------+----------------------------------+------------+
| 3f54ac025181a433 | started | etcd-1 | http://etcd-1.etcd-headless:2380 | http://etcd-1.etcd-headless:2379 |      false |
| 7c5422fe4922f16f | started | etcd-2 | http://etcd-2.etcd-headless:2380 | http://etcd-2.etcd-headless:2379 |      false |
| e4ad7553eba80d25 | started | etcd-0 | http://etcd-0.etcd-headless:2380 | http://etcd-0.etcd-headless:2379 |      false |
+------------------+---------+--------+----------------------------------+----------------------------------+------------+
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl --endpoints="http://etcd-1.etcd-headless:2379,http://etcd-2.etcd-headless:2379,http://etcd-0.etcd-headless:2379" endpoint status -w table
+----------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|             ENDPOINT             |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://etcd-1.etcd-headless:2379 | 3f54ac025181a433 |   3.5.0 |   20 kB |     false |      false |         2 |          7 |                  7 |        |
| http://etcd-2.etcd-headless:2379 | 7c5422fe4922f16f |   3.5.0 |   20 kB |     false |      false |         2 |          7 |                  7 |        |
| http://etcd-0.etcd-headless:2379 | e4ad7553eba80d25 |   3.5.0 |   20 kB |      true |      false |         2 |          7 |                  7 |        |
+----------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl --endpoints="http://etcd-1.etcd-headless:2379,http://etcd-2.etcd-headless:2379,http://etcd-0.etcd-headless:2379" endpoint health -w table
+----------------------------------+--------+------------+-------+
|             ENDPOINT             | HEALTH |    TOOK    | ERROR |
+----------------------------------+--------+------------+-------+
| http://etcd-0.etcd-headless:2379 |   true | 3.659275ms |       |
| http://etcd-1.etcd-headless:2379 |   true |  3.89955ms |       |
| http://etcd-2.etcd-headless:2379 |   true | 3.797005ms |       |
+----------------------------------+--------+------------+-------+
root@node1:/# kubectl -n restore exec -it etcd-0 -- etcdctl get --prefix foo
foo
bar
foo1
bar1
foo2
bar2
foo3
bar3
foo4
bar4
foo5
bar5

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 对于k8s etcd备份恢复,可以按照以下步骤进行操作。首先,确保已经有了备份文件。可以使用以下命令检查备份文件是否存在:\[1\] 如果备份文件不存在,则需要重新执行备份命令并输入正确的备份文件时间。接下来,可以使用etcdctl命令进行备份恢复。根据备份文件的位置和名称,使用以下命令进行恢复:\[3\] ``` ETCDCTL_API=3 etcdctl snapshot restore /path/to/etcd-snapshot.db \ --data-dir /path/to/etcd-data-dir \ --initial-cluster <etcd-cluster-endpoints> \ --initial-cluster-token <cluster-token> \ --initial-advertise-peer-urls <peer-urls> ``` 其中,`/path/to/etcd-snapshot.db`是备份文件的路径和名称,`/path/to/etcd-data-dir`是etcd数据目录的路径,`<etcd-cluster-endpoints>`是etcd集群的节点地址,`<cluster-token>`是集群的令牌,`<peer-urls>`是etcd节点的URL。根据实际情况替换这些参数。执行命令后,etcd将使用备份文件恢复数据到指定的数据目录。 需要注意的是,恢复过程可能需要一些时间,具体时间取决于备份文件的大小和系统性能。恢复完成后,可以启动etcd集群并验证数据是否成功恢复。 请注意,备份恢复是一个敏感的操作,务必谨慎执行,并确保备份文件的完整性和可用性。在执行恢复操作之前,建议先进行测试和验证,以确保备份文件可用并且可以成功恢复数据。 希望以上信息对您有所帮助。如果还有其他问题,请随时提问。 #### 引用[.reference_title] - *1* [k8s etcd 备份恢复](https://blog.csdn.net/liudongyang123/article/details/124145618)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [KubernetesETCD集群备份恢复](https://blog.csdn.net/heian_99/article/details/123398209)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值