etcd叢集備份和資料恢復
etcd是一個分散式k-v資料庫,在kubernetes中使用其管理叢集的元資料。這裡介紹etcd叢集資料的備份和資料恢復的方法和步驟。
快照定期備份
crontab定期執行備份指令碼,每半小時備份一次,本地、異地都備份(暫定:本地備份保留最近10個備份,異地保留一個月的備份)
#!/bin/bash # ETCDCTL_PATH='/usr/etcd/bin/etcdctl' ENDPOINTS='1.1.1.1:2379,1.1.1.2:2379,1.1.1.3:2379' BACKUP_DIR='/home/apps/backup' DATE=`date +%Y%m%d-%H%M%S` [ ! -d $BACKUP_DIR ] && mkdir -p $BACKUP_DIR export ETCDCTL_API=3;$ETCDCTL_PATH --endpoints=$ENDPOINTS snapshot save $BACKUP_DIR/snapshot-$DATE\.db cd $BACKUP_DIR;ls -lt $BACKUP_DIR|awk '{if(NR>11){print "rm -rf "$9}}'|sh
映象叢集備份
提前準備部署好映象叢集
實時全量資料同步
nohup etcdctl make-mirror <destination> &> /apps/logs/etcdmirror.log &
/apps/logs/etcdmirror.log會儲存已經同步的key數量,每30s列印一次
定期資料同步
crontab定期資料同步,為避免資料遭到誤刪除清空造成災難性影響,可恢復上一個同步週期之前的資料
#!/bin/bash # ETCDCTL_PATH='/apps/svr/etcd/bin/etcdctl' ENDPOINTS='1.1.1.1:2379,1.1.1.2:2379,1.1.1.3:2379' DEST_ENDPOINT='1.1.1.1:2389' CMD="$ETCDCTL_PATH make-mirror --endpoints=$ENDPOINTS $DEST_ENDPOINT" BaseName=$(basename $BASH_SOURCE) export ETCDCTL_API=3 $CMD & echo $! > /tmp/$BaseName\.pid sleep 90 kill `cat /tmp/$BaseName\.pid`
etcd叢集恢復
etcd叢集與zk叢集相似,建議採用基數裝置來搭建叢集,可用性為(N-1)/2,假設叢集數量N是3臺裝置,可最多可故障1臺裝置,而不影響叢集使用。
leader故障
當leader故障時,etcd叢集會自動選擇一個新leader,由於失敗檢測模型是基於超時的(heartbeat-interval),因此選舉新leader需要大約選舉超時。
在leader選舉期間,叢集不能處理任何寫入操作。在選舉期間傳送的寫入請求排隊等待處理,直到選出新的leader。
已經發送給old leader但尚未提交的文字可能會丟失。新leader有權重寫old leader的任何未提交的條目。從使用者的角度來看,一些寫入請求可能會超時,但是,沒有提交的寫入會丟失。
- 檢視現時叢集情況
[root@ETCD-CLUSTER-001 bin]# export ETCDCTL_API=3;./etcdctl --write-out="table" --endpoints='10.201.46.112:2379,10.201.46.113:2379,10.201.46.114:2379' endpoint status
+--------------------+------------------+---------+---------+-----------+-----------+------------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+--------------------+------------------+---------+---------+-----------+-----------+------------+
| 10.201.46.112:2379 | fd86741fb271523a | 3.1.10 | 25 kB | false | 2 | 10 |
| 10.201.46.113:2379 | fe2dd3624258de7 | 3.1.10 | 25 kB | false | 2 | 10 |
| 10.201.46.114:2379 | c649fd5192da5ca1 | 3.1.10 | 25 kB | true | 2 | 10 |
+--------------------+------------------+---------+---------+-----------+-----------+------------+
[root@ETCD-CLUSTER-001 bin]# export ETCDCTL_API=3;./etcdctl put hello nihao
OK
- 停止leader
- 檢視日誌,在第3個選舉週期的時候已經選舉了新的leader
- 叢集可以正常工作
[root@ETCD-CLUSTER-001 bin]# export ETCDCTL_API=3;./etcdctl get hello nihao
hello
nihao
follower故障
- 檢視現時叢集情況
- 停掉一臺followe
[root@ETCD-CLUSTER-003 ~]# sh /apps/sh/etcd.sh stop
Stopping etcd: [ OK ]
- 叢集正常工作
[root@ETCD-CLUSTER-001 bin]# export ETCDCTL_API=3;./etcdctl get hello nihao
hello
nihao
叢集故障恢復
為了從災難性故障中恢復,etcd v3提供了快照和恢復功能,以便在沒有v3金鑰資料丟失的情況下重新建立群集.
要恢復叢集,只需要一個快照“db”檔案。叢集恢復將etcdctl snapshot restore建立新的etcd資料目錄; 所有成員應該使用相同的快照進行恢復。恢復會覆蓋某些快照元資料(特別是成員ID和群集ID); 該成員失去了其以前的身份。此元資料覆蓋可防止新成員無意中加入現有群集。因此,為了從快照啟動叢集,還原必須啟動新的邏輯叢集。
在還原時可以選擇驗證快照完整性。如果使用快照etcdctl snapshot save,它將具有通過檢查的完整性雜湊etcdctl snapshot restore。如果快照是從資料目錄複製的(配置檔案中的data-dir),則不存在完整性雜湊,並且只能使用恢復--skip-hash-check。
儲存快照鍵空間
[root@ETCD-CLUSTER-001 bin]# export ETCDCTL_API=3;./etcdctl --endpoints='10.201.46.112:2379,10.201.46.113:2379,10.201.46.114:2379' snapshot save ~/.snapshot.db
Snapshot saved at /root/.snapshot.db
恢復快照資訊
每臺機器上執行,
$ etcdctl snapshot restore snapshot.db \
--name ETCD-CLUSTER-001 \
--initial-cluster ETCD-CLUSTER-001=http://10.201.46.112:2380,ETCD-CLUSTER-002=http://10.201.46.113:2380,ETCD-CLUSTER-003=http://10.201.46.114:2380 \
--initial-advertise-peer-urls http://10.201.46.112:2380
$ etcdctl snapshot restore snapshot.db \
--name ETCD-CLUSTER-002 \
--initial-cluster ETCD-CLUSTER-001=http://10.201.46.112:2380,ETCD-CLUSTER-002=http://10.201.46.113:2380,ETCD-CLUSTER-003=http://10.201.46.114:2380 \
--initial-advertise-peer-urls http://10.201.46.113:2380
$ etcdctl snapshot restore snapshot.db \
--name ETCD-CLUSTER-003 \
--initial-cluster ETCD-CLUSTER-001=http://10.201.46.112:2380,ETCD-CLUSTER-002=http://10.201.46.113:2380,ETCD-CLUSTER-003=http://10.201.46.114:2380 \
--initial-advertise-peer-urls http://10.201.46.114:2380
啟動etcd機器
sudo sh /apps/sh/etcd.sh start
叢集維護
剔除、新增成員
- 檢視現有成員
[root@ETCD-CLUSTER-001 etcd-v3.2.17-linux-amd64]# export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl --write-out="table" --endpoints='1.1.1.1:2379,1.1.1.2:2379,1.1.1.3:2379' member list
+------------------+---------+------------------+---------------------------+-----------------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS |
+------------------+---------+------------------+---------------------------+-----------------------+
| 28c987fd1ef634f8 | started | ETCD-CLUSTER-003 | http://1.1.1.3:2380 | http://localhost:2379 |
| 635b8eabdf3280ef | started | ETCD-CLUSTER-002 | http://1.1.1.2:2380 | http://localhost:2379 |
| e9a434659e36d3bc | started | ETCD-CLUSTER-001 | http://1.1.1.1:2380 | http://localhost:2379 |
+------------------+---------+------------------+---------------------------+-----------------------+
- 剔除成員
[root@ETCD-CLUSTER-001 etcd-v3.2.17-linux-amd64]# export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl --endpoints='1.1.1.1:2379,1.1.1.2:2379,1.1.1.3:2379' member remove e9a434659e36d3bc
Member e9a434659e36d3bc removed from cluster 7055108fef63cdab
[root@ETCD-CLUSTER-001 etcd-v3.2.17-linux-amd64]# export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl --write-out="table" --endpoints='1.1.1.1:2379,1.1.1.2:2379,1.1.1.3:2379' member list
+------------------+---------+------------------+---------------------------+-----------------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS |
+------------------+---------+------------------+---------------------------+-----------------------+
| 28c987fd1ef634f8 | started | ETCD-CLUSTER-003 | http://1.1.1.3:2380 | http://localhost:2379 |
| 635b8eabdf3280ef | started | ETCD-CLUSTER-002 | http://1.1.1.2:2380 | http://localhost:2379 |
+------------------+---------+------------------+---------------------------+-----------------------+
新增成員至叢集
注意步驟順序
[root@ETCD-CLUSTER-001 ]# export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl --endpoints='1.1.1.2:2379,1.1.1.3:2379' member add ETCD-CLUSTER-001 --peer-urls=http://1.1.1.1:2380
Member 433fd69a958b8432 added to cluster 7055108fef63cdab
ETCD_NAME="ETCD-CLUSTER-001"
ETCD_INITIAL_CLUSTER="ETCD-CLUSTER-003=http://1.1.1.3:2380,ETCD-CLUSTER-001=http://1.1.1.1:2380,ETCD-CLUSTER-002=http://1.1.1.2:2380"
ETCD_INITIAL_CLUSTER_STATE="existing"
[root@ETCD-CLUSTER-001 ]# export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl --write-out="table" --endpoints='1.1.1.2:2379,1.1.1.3:2379' member list
+------------------+-----------+------------------+---------------------------+-----------------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS |
+------------------+-----------+------------------+---------------------------+-----------------------+
| 28c987fd1ef634f8 | started | ETCD-CLUSTER-003 | http://1.1.1.3:2380 | http://localhost:2379 |
| 433fd69a958b8432 | unstarted | | http://1.1.1.1:2380 | |
| 635b8eabdf3280ef | started | ETCD-CLUSTER-002 | http://1.1.1.2:2380 | http://localhost:2379 |
+------------------+-----------+------------------+---------------------------+-----------------------+
刪除新增成員舊資料目錄,並且啟動新增成員etcd服務,加入叢集時要改下配置檔案,把初始化叢集狀態由new改成existing
[root@ETCD-CLUSTER-001 ~]# vim /apps/conf/etcd/etcd.conf
initial-cluster-state: "existing"
[root@ETCD-CLUSTER-001 ~]# export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl --write-out="table" --endpoints='1.1.1.2:2379,1.1.1.3:2379' member list
+------------------+---------+------------------+---------------------------+-----------------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS |
+------------------+---------+------------------+---------------------------+-----------------------+
| 28c987fd1ef634f8 | started | ETCD-CLUSTER-003 | http://1.1.1.3:2380 | http://localhost:2379 |
| 433fd69a958b8432 | started | ETCD-CLUSTER-001 | http://1.1.1.1:2380 | http://localhost:2379 |
| 635b8eabdf3280ef | started | ETCD-CLUSTER-002 | http://1.1.1.2:2380 | http://localhost:2379 |
+------------------+---------+------------------+---------------------------+-----------------------+
[root@ETCD-CLUSTER-001 ~]# export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl --write-out="table" --endpoints='1.1.1.1:2379,1.1.1.2:2379,1.1.1.3:2379' endpoint status
+--------------------+------------------+---------+---------+-----------+-----------+------------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+--------------------+------------------+---------+---------+-----------+-----------+------------+
| 1.1.1.1:2379 | 433fd69a958b8432 | 3.1.10 | 98 kB | false | 3 | 13 |
| 1.1.1.2:2379 | 635b8eabdf3280ef | 3.1.10 | 98 kB | false | 3 | 13 |
| 1.1.1.3:2379 | 28c987fd1ef634f8 | 3.1.10 | 98 kB | true | 3 | 13 |
+--------------------+------------------+---------+---------+-----------+-----------+------------+
etcd v2資料遷移到v3版本
# 遷移前,需要逐臺服務停止
sh /apps/sh/etcd.sh stop
# 遷移資料,資料目錄根據實際填寫
export ETCDCTL_API=3
etcdctl --endpoints=$ENDPOINT migrate --data-dir="default.etcd" --wal-dir="default.etcd/member/wal"
# 逐臺服務啟動
sh /apps/sh/etcd.sh start
# 檢查確認資料已經遷移
export ETCDCTL_API=3;etcdctl --endpoints=$ENDPOINTS get /foo
快照條目數量調整
--snapshot-count:指定有多少事務(transaction)被提交時,觸發擷取快照儲存到磁碟,在v3.2之前的版本,預設的引數是10000條,3.2之後調整為100000條
這個條目數量不能配置過高或者過低,過低會導致頻繁的io壓力,過高會導致佔用高記憶體以及會導致etcd GC過慢。建議設定為10W-20W條。
歷史資料壓縮
key空間長期的時候,如果沒有做壓縮清理,到達上限的閾值時,叢集會處於一個只能刪除和讀的狀態,無法進行寫操作。因此對叢集的歷史日誌做一個壓縮清理是很有必要。
資料壓縮並不是清理現有資料,只是對資料的歷史版本進行清理,清理後資料的歷史版本將不能訪問,但不會影響現有最新資料的訪問。
手動壓縮
使用客戶端工具進行清理
#壓縮清理revision為10之前的歷史資料
[apps@test ~]$ export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl compaction 10
compacted revision 10
#訪問revision10之前的資料會提示已經不存在
[apps@test ~]$ export ETCDCTL_API=3;/apps/svr/etcd/bin/etcdctl get aa --rev=9
Error: etcdserver: mvcc: required revision has been compacted
自動壓縮
使用--auto-compaction-retention=1,表示每小時進行一次資料壓縮。
碎片清理
進行compaction操作之後,舊的revision被壓縮,會產生內部的碎片,內部碎片是指空閒狀態的,能被後端使用但是仍然消耗儲存空間的磁碟空間。去碎片化實際上是將儲存空間還給檔案系統。
[apps@test ~]$ etcdctl defrag