kubeadm安装的k8s集群涉及etcd数据库的参数优化

一.问题原因

搭建正常运行好几年的基于kubeadm安装的kubernetes集群,针对etcd数据库路陆续出现以下问题

  • etcd io经常报延迟过高, 会有leader频繁切换的情况
  • 执行命令发现延迟高, 延迟100-200ms以上, 已经换了ssd,还是100ms左右或以上;
  • Error: etcdserver: mvcc: database space exceeded,超过默认的2G限制
  • etcd集群运行直接挂掉了(晚上半夜12点),集中式存储关掉了写缓存,造成存储IO性能下降75%,etcd集群频繁重启进而造成数据库文件文件坏了,自动恢复不了的问题

二.问题分析

Kubernetes使用etcd来存储和持久化集群的关键信息,如果etcd存储失效,或是etcd集群响应慢,会影响Kubernetes集群操作,甚至导致Kubernetes集群不可用,etcd基于Raft共识算法实现,确保数据在集群多个节点间一致且可靠。这是K8s集群稳定运行的基础,避免了"脑裂"和数据不一致。

etcd支持高效的键值变化监听。这正是Kubernetes控制器模式的核心驱动力。控制器通过Watch API Server(背后是Watch etcd),实时感知集群状态变化并做出反应。用于实现K8s的节点心跳(Node Lease)和TTL功能,帮助检测不健康的节点或Pod。

etcd使用Raft共识算法实现选举和日志复制,领导者节点定期向追随者节点发送心跳,如果追随者节点在一段时间内没有收到领导者节点的心跳信息,追随者节点就会认为领导者节点已经失效,并发起选举。当etcd在进行选举的期间,会导致Kubernetes的api Server无法对etcd执行读写请求,进而会导致kubectl操作延迟或短暂失败,并且当前的pod的创建、删除、更新等操作无法执行,对当前正在运行的pod、网络、存储等没有影响。

etcd集群选举发生的直接原因为集群选举超时,即追随者节点在election-timeout时间内未收到领导者节点的心跳信息,并认为领导者节点失效而发生选举,因此,对于发生选举的考虑主要包括两方面

  • 如果领导者节点正常发送心跳包,追随者节点未能及时收到,一般来说与网络的延迟关联比较大,即因为网络丢包或其他因素,导致心跳包未能及时发送至追随者节点;
  • 如果领导者节点未能正常发出心跳包,或是追随者节点收到心跳包后处理超时,导致选举,一般来说与存储的延迟关联比较大,在etcd的核心设计中,处理心跳的逻辑与磁盘的持久化写入逻辑存在顺序依赖关系。基于etcd的一致性要求,需要确保数据一旦写入就不会丢失,因此磁盘的写入操作返回时必须成功,因此,etcd采用fsync的同步操作来执行磁盘写入操作,fsync是一个同步的阻塞操作,会直接将数据写入磁盘,因此,会导致etcd会对磁盘比较敏感。一旦磁盘写入慢,会导致心跳包的处理延迟,包括领导者节点向追随者节点发出心跳包,以及追随者节点处理收到的心跳包。

三.优化参数建议

etcd 作为 K8s 的核心数据库,其参数优化直接影响集群稳定性和性能。以下是 kubeadm 部署场景下最关键的优化参数(按作用分类)

1. 性能相关核心参数

参数名 作用 默认值(kubeadm) 推荐值(生产) 说明
--quota-backend-bytes etcd 单节点存储上限 2GB 8GB(≤8GB) 限制 etcd 数据库大小,超过会触发告警 / 写失败;K8s 集群越大需越高,但不建议超过 8GB(否则影响性能)
--max-request-bytes 单请求最大字节数 1.5MB 10MB 支持更大的资源对象(如大 ConfigMap/Secret),避免请求被拒绝
--auto-compaction-mode 压缩模式 none periodic 可选periodic(按时间)或revision(按版本),生产优先 periodic
--auto-compaction-retention 压缩保留时间 0(不压缩) 1h(或 1000 revision) 定期压缩 etcd 历史数据,减少磁盘占用;时间越短磁盘占用越少,但需保留足够回滚版本
--snapshot-count 触发快照的事务数 100000 500000 事务数达到阈值时生成快照;值越大快照越少,但崩溃恢复时间越长

2. 网络 / 连接相关参数

参数名 作用 默认值 推荐值 说明
--heartbeat-interval 节点间心跳间隔(ms) 100 200-500 心跳越频繁,集群故障检测越快,但网络开销越大;高延迟网络建议调大
--election-timeout 选举超时时间(ms) 1000 2000-5000 节点失联后触发选举的超时时间;需大于心跳间隔的 5 倍,高延迟网络调大
--client-concurrency 客户端并发请求数 256 1024 提高 etcd 处理客户端(kube-apiserver)并发请求的能力

3. 资源限制参数(容器层面)

参数 作用 推荐值 说明
cpu CPU 资源限制 2-4 核(请求)/4-8 核(限制) etcd 是 CPU 密集型,避免 CPU 抢占导致性能下降
memory 内存限制 2-4GB(请求)/4-8GB(限制) 内存不足会触发 OOM,etcd 缓存需足够内存
storage 磁盘 IO SSD(IOPS ≥ 1000) 机械硬盘会导致 etcd 写入延迟,生产必须用 SSD

4. 操作系统参数(建议,可选)

复制代码
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720

net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =30
net.ipv4.tcp_max_tw_buckets = 360000
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_fin_timeout = 15
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_conntrack_max = 65536
#net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535

net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
net.ipv6.conf.all.forwarding = 1


# 增大接收和发送缓冲区的最大和默认值
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
# 调整 TCP 接收和发送缓冲区的范围
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

本环境优化后的etcd的yaml文件如下(可参考)

复制代码
spec:
  containers:
  - name: etcd
    image: etcd:3.5.3-0  # 确保etcd版本≥3.5(推荐3.5+)
    command:
    - etcd
    - --advertise-client-urls=https://192.168.1.100:2379  # 替换为节点IP
    - --client-cert-auth=true
    - --data-dir=/var/lib/etcd
    - --initial-advertise-peer-urls=https://192.168.1.100:2380  # 替换为节点IP
    - --initial-cluster=master=https://192.168.1.100:2380  # 替换为节点名称+IP
    - --peer-cert-auth=true
    - --snapshot-count=500000  # 优化快照触发阈值
    - --auto-compaction-mode=periodic  # 开启定期压缩
    - --auto-compaction-retention=1h  # 保留1小时历史数据
    - --quota-backend-bytes=8589934592  # 8GB存储上限(8*1024*1024*1024)
    - --max-request-bytes=10485760  # 10MB单请求上限
    - --heartbeat-interval=200  # 心跳间隔200ms
    - --election-timeout=2000  # 选举超时2000ms
    - --client-concurrency=1024  # 提高并发请求数
    - --log-level=info  # 日志级别,避免debug日志占用资源
相关推荐
CC.GG2 小时前
【Qt】常用控件----QWidget属性
java·数据库·qt
大猫和小黄2 小时前
若依微服务Cloud中Quartz-Job模块适配OpenGauss数据库
数据库·微服务·opengauss·quartz·定时任务·若依·job
奔跑的小十一2 小时前
ShardingSphere-JDBC 开发手册
java·数据库
lkbhua莱克瓦242 小时前
基础-MySQL概述
java·开发语言·数据库·笔记·mysql
姓蔡小朋友2 小时前
MySQL增删查改、多表查询
数据库·mysql
Knight_AL3 小时前
Maven <dependencyManagement>:如何在多模块项目中集中管理依赖版本
java·数据库·maven
TAEHENGV3 小时前
导入导出模块 Cordova 与 OpenHarmony 混合开发实战
android·javascript·数据库
不剪发的Tony老师3 小时前
sqlectron:一款轻量级的SQL客户端
数据库·sql
酸菜牛肉汤面3 小时前
7、索引设计的原则
数据库