全部的 K8S学习笔记总目录,请点击查看。
etcd是k8s的核心组件之一,主要用于存储k8s集群的所有数据,包括集群的配置信息、集群状态、集群资源等。etcd是一个分布式的、高可用的、一致性的、高性能的键值存储系统,是k8s集群的数据存储中心。
ETCD命令行工具
拷贝etcdctl命令行工具(附加启动etcd命令):
二进制方式
1 | ETCD_VER=v3.4.27 |
启动etcd命令(对之后的说明没有影响):
1 | # start a local etcd server |
docker 方式
1 | docker pull gcr.io/etcd-development/etcd:v3.4.27 |
启动etcd命令(对之后的说明没有影响):
1 | rm -rf /tmp/etcd-data.tmp && mkdir -p /tmp/etcd-data.tmp && \ |
ETCD常用操作
查看etcd集群的成员节点
1 | $ export ETCDCTL_API=3 |
查看etcd集群节点状态
1 | $ etcdctl endpoint status -w table |
设置key值
1 | $ etcdctl put test 1 |
查看所有key值
1 | $ etcdctl get / --prefix --keys-only |
查看具体的key对应的数据
1 | $ etcdctl get /registry/pods/test/myblog-84985b5b66-jp9gg |
list-watch
1 | $ etcdctl watch /test/ --prefix |
快照与恢复(重要!)
添加定时任务做数据快照
1 | $ etcdctl snapshot save `hostname`-etcd_`date +%Y%m%d%H%M`.db |
恢复快照:
停止etcd和apiserver(防止新数据写入)
移走当前数据目录
1
$ mv /var/lib/etcd/ /tmp
恢复快照
1
$ etcdctl snapshot restore `hostname`-etcd_`date +%Y%m%d%H%M`.db --data-dir=/var/lib/etcd/
集群恢复
https://github.com/etcd-io/etcd/blob/release-3.3/Documentation/op-guide/recovery.md
namespace删除问题
很多情况下,会出现namespace删除卡住的问题,此时可以通过操作etcd来删除数据:
1 | # 查看namespace相关的数据 |
故障恢复
etcd集群故障恢复
因为etcd中存储着最重要的数据,所以etcd集群的故障恢复是最重要的。如果节点故障,无法正常启动则需要添加新节点进行恢复。
将etcd备份数据拷贝到新节点
1
$ scp /backup/etcd-202109031100.db root@new-etcd:/tmp/
将数据恢复到新节点
1
$ etcdctl snapshot restore /tmp/etcd-202109031100.db --data-dir=/var/lib/etcd/
新节点启动etcd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27$ name="etcd-new"
$ host="etcd-new-ip"
$ cluster="etcd1=http://etcd-new-ip:2380"
$ docker run -d --privileged=true \
-p 2379:2379 \
-p 2380:2380 \
-v /var/lib/etcd:/data/etcd \
--restart=always \
--name ${name} \
--net=host \
-v /etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd \
gcr.io/coreos/etcd:v3.5.0 \
/usr/local/bin/etcd \
--name ${name} \
--data-dir /data/etcd \
--listen-client-urls http://${host}:2379 \
--advertise-client-urls http://${host}:2379 \
--listen-peer-urls http://${host}:2380 \
--initial-advertise-peer-urls http://${host}:2380 \
--initial-cluster ${cluster} \
--initial-cluster-token tkn \
--initial-cluster-state new \
--force-new-cluster \
--log-level info \
--logger zap \
--log-outputs stderr虽然已经导入了数据,但是还是需要重新初始化集群,重新建立连接,所以需要加上
--force-new-cluster
参数。验证集群状态
1
2
3
4
5$ export ETCDCTL_API=3
$ export ETCD_ENDPOINTS="http://etcd-new-ip:2379"
$ etcdctl --endpoints=${ETCD_ENDPOINTS} -w table member list
$ etcdctl --endpoints=${ETCD_ENDPOINTS} -w table endpoint status
$ etcdctl --endpoints=${ETCD_ENDPOINTS} get / --prefix --keys-only
etcd集群增量恢复
如果etcd集群中的数据丢失了一部分,可以通过增量恢复的方式来恢复数据。比如有备份数据etcd-backup1.db
和备份数据etc-backup2.db
,两次备份数据相差1天,我们丢失了数据,可以只恢复这1天的数据。
etcdhelper源码下载
etcdhelper不提供二进制文件,需要自己编译,所以需要下载源码:
1
$ git clone https://github.com/openshift/origin.git
编译etcdhelper
1
2
3
4
5
6
7
8
9
10
11$ docker run -d --name go-builder golang:1.17 sleep 3600
$ docker cp origin-master go-builder:/go
$ docker exec -ti go-builder bash
# cd /go/orign-master
# go env -w GOPROXY=https://goproxy.cn,direct
# CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build tools/etcdhelper/etcdhelper.go
# exit
$ docker cp go-builder:/go/origin-master/etcdhelper .
$ cp etcdhelper /usr/local/bin/etcdhelper使用
etcdhelper使用方式和etcdctl类似,只是etcdhelper是对etcdctl的封装,可以批量操作,比如批量删除等。获取到的数据是json格式,可以直接查看。
1
2
3
4$ export ETCDCTL_API=3
$ export ETCD_ENDPOINTS="http://etcd-new-ip:2379"
$ etcdhelper -endpoints=${ETCD_ENDPOINTS} ls
$ etcdhelper -endpoints=${ETCD_ENDPOINTS} get /registry/pods/test/myblog-84985b5b66-jp9gg增量恢复
比如我们丢失了
etcd-backup1.db
和etcd-backup2.db
之间的数据,我们可以通过etcdhelper获取到这段时间的数据,然后再导入到etcd集群中。这里我们举例误删除了namespace为test下的所有资源情况。首先我们找一台新机器,恢复
etcd-backup1.db
的数据,因为etcd-backup1.db
是完整的数据,包含被删除的数据。恢复方法参考上面的故障恢复。批量操作获取yaml文件
kubectl没有办法直接使用json格式的文件,因此需要将json格式的文件转换为yaml格式的文件,然后再使用kubectl apply命令。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19$ export ETCDCTL_API=3
$ export ETCD_ENDPOINTS="http://etcd-new-ip:2379"
$ etcdctl --endpoints=${ETCD_ENDPOINTS} get / --prefix --keys-only | grep test > keys.txt
# 使用脚本利用etcdhelper将key转换成为json文件
cat key_to_json.sh
#!/bin/bash
i=0
export ETCDCTL_API=3
export ETCD_ENDPOINTS=etcd-new-ip:2379
for line in `cat keys.txt`
do
etcdhelper -endpoint $ETCD_ENDPOINTS get $line > $i.json
# 第一行是资源类型和版本,不是json格式,需要删除
sed -i '1d' $i.json
let 'i+=1'
done运行脚本,将key转换成为json文件:
1
$ ./key_to_json.sh
将json文件转换成为yaml文件:
1
2# json to yaml,具体方法就不写了,内容还比较简单
$ python3 json_to_yaml.py批量导入操作
1
2
3
4
5
6
7
8
9
10
11$ cat apply.sh
#!/bin/bash
i=0
for line in `cat keys.txt`
do
kubectl apply -f $i.yaml
let 'i+=1'
done
$ ./apply.sh