k8s 中使用 etcd 快照恢复集群数据

sunls24 于 2021-03-25 发布

一、Etcd简介

Etcd是Kubernetes集群中的一个十分重要的组件,用于保存集群所有的网络配置和对象的状态信息。 整个kubernetes系统中一共有两个服务需要用到etcd用来协同和存储配置,分别是:

注意:flannel操作etcd使用的是v2的API,而kubernetes操作etcd使用的v3的API。

二、安装etcdctl

1.下载文件

此处使用的版本为v3.4.15 地址:https://github.com/etcd-io/etcd/releases/download/v3.4.15/etcd-v3.4.15-linux-amd64.tar

2.解压文件

tar -xvf etcd-v3.4.15-linux-amd64.tar
cp etcd-v3.4.15-linux-amd64/etcdctl /usr/local/bin/
// 检查版本
[root@node01 ~]# etcdctl version
etcdctl version: 3.4.15
API version: 3.4

3.设置环境变量

当操作kubernetes时,需设置环境变量 ETCDCTL_API=3

export ETCDCTL_API=3

# 或者在`/etc/profile`文件中添加环境变量
vi /etc/profile
...
export ETCDCTL_API=3
...
source /etc/profile

# 或者在命令执行前加 ETCDCTL_API=3
ETCDCTL_API=3 etcdctl --endpoints=$ENDPOINTS member list

三、常用命令

1.证书参数

如果etcd设置了证书访问,则需要添加证书相关参数:

etcdctl --endpoints=$ENDPOINTS --cacert=<ca-file> --cert=<cert-file> --key=<key-file>  <command>

在master主机上命令如下:

etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt \
--key /etc/kubernetes/pki/etcd/server.key \
--cert /etc/kubernetes/pki/etcd/server.crt \
get / --prefix --keys-only

前三行为固定值,可以设置别名,避免每次都要输入证书参数。

alias etcdctl='etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt --key /etc/kubernetes/pki/etcd/server.key --cert /etc/kubernetes/pki/etcd/server.crt'

2.查找

// 按key查找
etcdctl get foo
// 基于相同前缀查找
etcdctl get foo --prefix
// 列出所有的key
etcdctl get / --prefix --keys-only

3.修改

// 增加
etcdctl put key "value"
// 删除
etcdctl del key
etcdctl del key --prefix

四、正文

1.环境准备

1个master(172.16.99.31)节点,2个node节点,新建一个命名空间dev,并在dev和default下创建deployment

[root@master01 ~]# kubectl create -f default-nginx.yaml
deployment.apps/default-nginx created
[root@master01 ~]# kubectl create -f dev-nginx.yaml
deployment.apps/dev-nginx created

2.查看pod状态

Snipaste_2021-03-18_13-39-03.png

3.生成etcd快照

生成快照命令

ETCDCTL_API=3 etcdctl \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--key /etc/kubernetes/pki/etcd/server.key \
--cert /etc/kubernetes/pki/etcd/server.crt \
snapshot save /root/kubeback/snapshot.db

由于已经配置过别名和环境变量,所以直接执行以下命令:

etcdctl snapshot save /root/kubeback/snapshot.db

Snipaste_2021-03-18_14-12-16.png

4.删除所有deployment

Snipaste_2021-03-18_11-28-48.png 查看pod是否被删除 Snipaste_2021-03-18_14-14-15.png

5.停止etcd进程

将etcd的yaml文件移动到别的目录即可,k8s会自动停止etcd相关的进程和pod。 当停止etcd时,正在运行的pod不受影响。

mv /etc/kubernetes/manifests/etcd.yaml /root/kubeback/

此时kubectl命令执行会提示 Unable to connect to the server: net/http: TLS handshake timeoutSnipaste_2021-03-18_14-18-27.png 查看etcd进程是否停止 Snipaste_2021-03-18_14-20-01.png

6.移除etcd数据

mv /var/lib/etcd /var/lib/etcd.bak

如果这里不移除等下恢复快照时会提示文件夹已存在。

7.恢复数据

单master集群执行以下命令恢复快照:

etcdctl snapshot restore /root/kubeback/snapshot.db --data-dir=/var/lib/etcd

Snipaste_2021-03-18_14-39-18.png 多master集群(未验证): 需要将snapshot.db拷贝到另外的master节点上,分别在各个master节点上恢复快照。

[root@etcd1 ~]# etcdctl snapshot restore snapshot.db --name etcd1  --initial-cluster etcd1=http://x.x.x.x1:2380,etcd2=http://x.x.x.x2:2380,etcd3=http://x.x.x.x3:2380 --initial-advertise-peer-urls http://x.x.x.x1:2380 --data-dir /var/lib/etcd
[root@etcd2 ~]# etcdctl snapshot restore snapshot.db --name etcd2  --initial-cluster etcd1=http://x.x.x.x1:2380,etcd2=http://x.x.x.x2:2380,etcd3=http://x.x.x.x3:2380 --initial-advertise-peer-urls http://x.x.x.x2:2380 --data-dir /var/lib/etcd
[root@etcd3 ~]# etcdctl snapshot restore snapshot.db --name etcd3  --initial-cluster etcd1=http://x.x.x.x1:2380,etcd2=http://x.x.x.x2:2380,etcd3=http://x.x.x.x3:2380 --initial-advertise-peer-urls http://x.x.x.x3:2380 --data-dir /var/lib/etcd

8.恢复etcd

将etcd.yaml移动到原本的位置,等待k8s恢复状态。

 mv /root/kubeback/etcd.yaml /etc/kubernetes/manifests/

此时可能需要等待较长时间,kubectl命令会提示拒绝连接。

The connection to the server 172.16.99.31:6443 was refused - did you specify the right host or port?

9.检查pod

两个命名空间的pod均已恢复为备份时的状态。 Snipaste_2021-03-18_14-48-17.png

五、查看etcd元数据

1.etcdctl

通过etcdctl的get命令可以获取etcd的数据,但是etcd中存储的并不是json的原文,而是protocol buffer序列化后的数据,可读性很差。 Snipaste_2021-03-18_17-51-10.png

2.Etcd helper

使用Etcd helper可以查看etcd中完整的json数据

下载编译

Github地址:https://github.com/p0lyn0mial/etcdhelper

git clone https://github.com/p0lyn0mial/etcdhelper.git
cd etcdhelper
set GOARCH=amd64
set GOOS=linux
go build .

使用

设置证书参数

查看etcd数据

设置别名简化操作

alias etcdhelper='/root/etcdhelper --cacert /etc/kubernetes/pki/etcd/ca.crt --key /etc/kubernetes/pki/etcd/server.key --cert /etc/kubernetes/pki/etcd/server.crt'

将编译好的二进制文件上传至服务器,执行

etcdhelper get /registry/pods/dev/dev-nginx-7848d4b86f-clkb8

Snipaste_2021-03-18_18-03-43.png