前言
這兩天遇到一個
etcd
報錯問題,解決完順帶記錄一下
etcd
服務未設定自動壓縮參數(
auto-compact
)
etcd
預設不會自動
compact
,需要設定啟動參數,或者通過指令進行compact,如果變更頻繁建議設定,否則會導緻空間和記憶體的浪費以及錯誤。
Etcd v3
的預設的 backend quota 2GB,如果不
compact
,
boltdb
檔案大小超過這個限制後,就會報錯:
”Error: etcdserver: mvcc: database space exceeded”
,導緻資料無法寫入。
壓縮舊版本、碎片整理
注意!!!
重要資料先将etcd進行快照操作!
重要資料先将etcd進行快照操作!
重要資料先将etcd進行快照操作!
檢視節點狀态,可以看到
ERRORS
壓縮版本、清理碎片、移除告警(這一步需要對所有
etcd
節點進行操作)
rev=$(/usr/local/bin/etcdctl --endpoints=127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key endpoint status --write-out="json" | egrep -o '"revision":[0-9]*' | egrep -o '[0-9].*')
# 壓縮版本
ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key compact $rev
# 清理碎片
ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key defrag
# 移除告警
ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key alarm disarm
上面的操作隻能保證叢集
apply
資料進去,但是如果
mvcc
還是持續增長的話,還是會有問題的,如果你是二進制部署的etcd,那加擴容參數較為簡單,隻需要加入下面參數即可,後面的值可以根據自己的需求調整
--quota-backend-bytes=8000000000
如果你的
etcd
是使用
pod
起的,就稍微麻煩一些
擴容Pod起的etcd(當叢集處于mvcc: database space exceeded壓縮後狀态)
因為此時你對叢集的
etcd
進行了壓縮、碎片清理,此時
etcd
叢集需要同步資料,也就是意味着你此時的
k8叢集
可能是異常,有一種極端的情況就是,等你等到
etcd
同步完成了,剛好
etcd
的
mvcc
又告警了,此時你對Pod的操作連
apply
、
delete
都沒辦法進行。
那麼就需要在
etcd
恢複期間,對原有的
etcd
進行删除,直接強制删除原有的
Pod
删除之前先導出
Pod
的
yaml
kubectl get po etcd-xxx-01 -n kube-system -oyaml > etcd-xxx-01.yaml
再執行強制删除
kubectl delete pods etcd-xxx-01 -n kube-system --grace-period=0 --force
但是強制删除實際上隻是删除了
etcd
的記錄,此時
container
仍然還在機器上跑着,我們需要把
dokcer
也停掉
docker ps|grep etcd
docker stop containerid
然後如果你是靜态
Pod
起的,再
/etc/kubernetes/manifes
t下改
etcd.yaml
也可以,或者修改導出的
yaml
的也可以
依然是修改啟動的command,添加
--quota-backend-bytes=8000000000
然後
apply yaml
即可,此時Pod的狀态不會
Running
,而是會處于
Pending
。
重新開機
kubelet
以及使用
docker
指令重新開機
apiserver
。
擴容也是需要對
etcd
每個節點都進行這一步的操作