本文永久链接: https://www.xtplayer.cn/etcd/etcd-optimize/

注意: 以下操作中所指的 K8S 集群,均是 rancher 或者 rke 创建的集群。

存储空间配额

--quota-backend-bytes

存储空间配额可以理解为 ETCD 数据库大小,默认限制 2G(推荐最大 8G)。当数据写入耗尽存储空间时,ETCD 会引发整个集群范围的警告,该警告将会导致集群切换为维护模式,维护模式 仅接受键值读取和删除,不支持写入。

所以,在创建集群时候建议修改配额大小。但是这个配额值不宜过设置大,建议在主机内存的 60% - 70%

手动释放配额空间

如果在 ETCD 服务日志中看到类似以下的日志,那么说明 ETCD 配额空间可能已经满了,需要手动去清理并释放空间。

Error:  rpc error: code = 8 desc = etcdserver: mvcc: database space exceeded
  1. 执行以下命令查看配额空间具体使用信息

    # 在 ETCD 主机上执行以下命令
    docker exec -ti etcd sh -c 'ETCDCTL_API=3 etcdctl --write-out=table endpoint status'

    # 信息输出
    rancher@alihost-01:~$ docker exec -ti etcd sh -c 'ETCDCTL_API=3 etcdctl --write-out=table endpoint status'
    +----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
    | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
    +----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
    | https://192.168.1.224:2379 | 16e3472080d104d4 | 3.4.3 | 1040 MB | true | false | 50 | 612649586 | 612649586 | |
    +----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
  2. 通过以下操作命令来手动释放配额空间

    # 登录 ETCD 主机,然后登录 ETCD 容器
    docker exec -ti etcd sh
    # 获取当前的修订版本
    rev=$(ETCDCTL_API=3 etcdctl --endpoints=:2379 endpoint status --write-out="json" | egrep -o '"revision":[0-9]*' | egrep -o '[0-9].*')
    # 压缩所有旧的修订
    ETCDCTL_API=3 etcdctl compact $rev
    # 碎片整理,释放空间
    ETCDCTL_API=3 etcdctl defrag
    # 解除警报(每个 ETCD 实例都要执行)
    ETCDCTL_API=3 etcdctl alarm disarm

历史版本清理

--auto-compaction-mode
--auto-compaction-retention

ETCD 会存储多版本数据,随着写入的主键增加,历史版本将会越来越多,并且 ETCD 默认不会自动清理历史数据。数据达到 --quota-backend-bytes 设置的配额值时就无法写入数据,必须要压缩并清理历史数据才能继续写入。

所以,为了避免配额空间耗尽的问题,在创建集群时候建议默认开启 历史版本清理 功能。

  • 3.3.0 之前的版本

    3.3.0 之前的版本,只能按周期 periodic 来压缩。比如设置 --auto-compaction-retention=72h,那么就会每 72 小时进行一次数据压缩。

  • 3.3.0 之后的版本

    比如在 v3.3.0, v3.3.1 和 v3.3.2 中,可以通过 --auto-compaction-mode 设置压缩模式,可以选择 revision 或者 periodic 来压缩数据,默认为 periodic

Raft 日志保留

--snapshot-count 指定有多少条事务(transaction)被提交时,触发快照保存到磁盘。在存盘之前,Raft 条目将一直保存在内存中。从 v3.2 版本开始,--snapshot-count 条数从 10000 改为 100000,因此这将占用很大一部分内存资源。

如果节点总内存资源不多,或者是单 etcd 实例运行,则可以把 --snapshot-count 适当的缩减,比如设置为 --snapshot-count=50000

快照备份

ETCD 具有快照备份功能,建议生产环境中开启 ETCD 自动备份功能。通过 rancher 创建的集群中,默认开启自动备份功能。对于 rke 创建的集群,需要在配置文件中添加对应的配置。

services:
etcd:
# 开启自动备份
## rke 版本小于 0.2.x 或 rancher 版本小于 v2.2.0 时使用
snapshot: true
creation: 5m0s
retention: 24h
## rke 版本大于等于 0.2.x 或 rancher 版本大于等于 v2.2.0 时使用(两段配置二选一)
backup_config:
enabled: true # 设置 true 启用 ETCD 自动备份,设置 false 禁用;
interval_hours: 12 # 快照创建间隔时间,不加此参数,默认 5 分钟;
retention: 6 # etcd 备份保留份数;

RKE ETCD 参考配置

services:
etcd:
# 开启自动备份
## rke 版本小于 0.2.x 或 rancher 版本小于 v2.2.0 时使用
snapshot: true
creation: 5m0s
retention: 24h
## rke 版本大于等于 0.2.x 或 rancher 版本大于等于 v2.2.0 时使用(两段配置二选一)
backup_config:
enabled: true # 设置 true 启用 ETCD 自动备份,设置 false 禁用;
interval_hours: 12 # 快照创建间隔时间,不加此参数,默认 5 分钟;
retention: 6 # etcd 备份保留份数;
extra_env:
# 扩展参数 https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/configuration.md
extra_args:
heartbeat-interval: '500' # 心跳检查间隔,ETCD 默认 100 毫秒,网络质量不好的环境,适当增加这个值
election-timeout: '5000' # 选举超时,ETCD 默认 1000 毫秒,网络质量不好的环境,适当增加这个值
auto-compaction-mode: periodic
auto-compaction-retention: 60m
# 修改空间配额为$((6*1024*1024*1024)),默认 2G,最大 8G
quota-backend-bytes: '6442450944'
snapshot-count: 50000 # 触发快照写入磁盘的提交事务数。默认值: "100000",在写入磁盘前事务保存在内存中,如果节点内存紧张,可以减少这个值。
max-request-bytes: 10485760 # 服务器接受的最大客户端请求大小(以字节为单位),默认 1.5M,建议增加大小,比如设置为 10M。
log-level: info # supports debug, info, warn, error, panic, or fatal.
debug: false
enable-pprof: false # Enable runtime profiling data via HTTP server. Address is at client URL + "/debug/pprof/", default: false.
extra_binds:
- "/etc/localtime:/etc/localtime"