Kubernetes:etcd容量管理(配额、压缩、碎片整理等)

在Kubernetes中,所有的API对象都通过kube-apiserver保存在etcd中。etcd有数据大小限制(配额),但还需注意一些其他事项,如历史数据和片段化大小在compaction之前的情况。本文总结了一些关于etcd容量管理的信息,所使用的etcd版本为3.2.24。

etcd的容量限制(配额)

etcd 默认设置了2GB的配额。一旦超过这个配额,etcd会进入警报状态,并且除非解除警报(解除武装),否则将无法向etcd写入数据。如果超过容量限制,将显示错误消息“mvcc: database space exceeded”。配额大小可以通过 –quota-backend-bytes选项指定最大为8GB。

包含在配额大小中的内容

配额大小将根据 etcd 使用的 BoltDB(etcd-io/bbolt)后端的物理大小来计算。由于该大小包括历史数据和由于碎片化引起的间隙,因此需要注意。

現在のデータ(キーと値)

Kubernetes の場合、API オブジェクトごとにキーができ、protocol buffer でエンコードされている

履歴データ

etcd の compaction のタイミングで指定した revision 以下の履歴は消える

断片化による隙間

etcd の defrag のタイミングで解消する

物理尺寸和逻辑尺寸

在etcd的数据大小中,有物理大小和逻辑大小两种。这些大小可以通过以下Prometheus的指标进行查看。

etcd_mvcc_db_total_size_in_bytes 断片化による隙間を含む、物理的な DB のサイズ

クォータの対象となるサイズ
defrag を行ったときのみサイズが減る

etcd_mvcc_db_total_size_in_use_in_bytes 断片化による隙間を含まない、論理的な DB のサイズ

compaction で履歴データを消したときにサイズが減る

看看实际操作

这个图表显示了通过kube-apiserver每秒修改一次1MB的ConfigMap并写入历史数据的时候的指标。由于是对同一个ConfigMap进行更新,所以从kube-apiserver的角度来看,应该只增加了大约1MB。但是可以看出etcd的数据量正在增加。

image.png

从上面的图表中可以看出,红色代表物理尺寸,绿色代表逻辑尺寸。上述图表显示以下操作。

    • ConfigMap の更新を開始すると etcd の論理サイズ(緑)、物理サイズ(赤)ともに増えていく

履歴データによってサイズが増えていく

論理サイズ(緑) は定期的にサイズが小さくなる

5分ごとに kube-apiserver によって compaction が走って履歴データが消えるため
一定以上データが消えていないのは、compaction の revision 指定の仕様 (後述)

一方物理サイズ(赤) は一度上がったサイズはそのまま

最後に手動で defrag を実行したタイミングで初めてサイズが下がる

以下是实际执行的操作。为了对etcd施加负载,请在尝试时小心注意。

# 1MB のダミーファイルを作成
$ dd if=/dev/urandom of=random.bin bs=1024 count=1024

# ダミーファイルを入れた ConfigMap を作成
$ kubectl create cm dummy-config --from-file random.bin

# 1秒ごとにパッチを当てて、履歴データを etcd に書いていく
$ while true; do
  kubectl patch configmap dummy-config \
  -p "{\"metadata\":{\"annotations\":{\"dummy-for-update\":\"`date +%s`\"}}}"
  sleep 1
done

# 適当なタイミングで止める

# defrag だけ手動実行
$ sudo ETCDCTL_API=3 etcdctl --endpoints=... defrag

历史数据和压缩

当发生更改操作时,etcd会保留旧数据并创建新数据。在内部,它会给每个数据分配一个称为revision的连续编号。当进行压缩操作时,会删除指定的revision之前的数据。

etcd拥有自动执行压缩的功能,但在Kubernetes中,默认操作是通过kube-apiserver的功能定期进行压缩。压缩间隔可以使用kube-apiserver的–etcd-compaction-interval参数进行指定,默认为5分钟。(kubernetes v1.14.0)

在 kube-apiserver 的压缩处理中,将上次执行压缩的修订版本记录在一个特殊的键“compactRevKey”中,在下次处理中执行该修订版本之前的压缩操作,然后重复这个过程。换句话说,默认情况下,会保留两个区间,即10分钟的历史数据。

数据间隙和碎片整理

根据 etcd 使用的 BoltDB (etcd-io/bbolt) 的规范,删除数据不会减小数据库的大小(参考: Question: Shrink BoltDB File? #423)。此外,数据库可能会发生碎片化,有时需要进行 defrag 操作。然而,在 defrag 过程中,写入或读取数据可能会失败,因此最好避免不必要的操作。

etcd 的碎片整理实现方式似乎是简单地创建一个新的 BoltDB 文件,并将所有数据写入其中,然后通过重命名进行切换。

    参考: https://github.com/etcd-io/etcd/blob/v3.3.12/mvcc/backend/backend.go#L293-L415

提示:了解API对象数量。

可以通过Prometheus的度量标准“kube-apiserver的etcd_object_counts”查看当前的Kubernetes API对象数。由于资源标签的存在,可以立即了解哪种资源的数量最多。虽然没有历史信息,但可以轻松地确认etcd中哪个对象最多。

使用以下命令按照资源数量从多到少进行排序。

$ kubectl get --raw /metrics | grep etcd_object_counts | sort -k2 -n
...
etcd_object_counts{resource="clusterroles.rbac.authorization.k8s.io"} 76
etcd_object_counts{resource="secrets"} 118
etcd_object_counts{resource="pods"} 162
etcd_object_counts{resource="events"} 647

Kubernetes中etcd配额的注意事项

需要注意的是Compaction之间的历史数据。

    • デフォルトだと約10分の履歴が保持される

 

    • 特にレプリカ数の大きな Deployment のローリングアップデートには注意

Pod ごとにオブジェクトが作られ、ローリングアップデートの最中に複数回アップデートされる

大きなファイルサイズのオブジェクト (ConfigMap, Secret) の更新にも注意

请注意Event对象。

    • Event オブジェクトには TTL (デフォルト 1時間) はあるものの、障害などで大量のイベントが発生する可能性がある

 

    Deployment のローリングアップデート時には Event が増えることも留意

总结

etcd有配额限制,其中Bolt DB的物理大小受到限制。物理大小包括了压缩前的历史记录和片段化。在Kubernetes中,kube-apiserver会定期(默认为5分钟)执行压缩操作,但由于保留了10分钟的历史记录,因此在进行大规模滚动更新等操作时需要注意。

广告
将在 10 秒后关闭
bannerAds