Kubernetes各组件参数配置优化建议
kubernetes虽然默认配置下已经足够可用满足常见的中小规模场景,但是若是将各组件参数、内核参数进行适当的调整,以达到更贴合使用场景的参数值,对集群运行的稳定性、故障切换能力等方面会有不小的提升。下面介绍一下各组件生产运行常做的一些参数调整。
Kubelet参数配置
kubelet在各个组件之中,作为唯一的分布在每个节点上的daemon控制程序,应该也是需要调整参数最多的组件了,从此前的flag形式的传参,到自1.11版本起的改用专属配置文件,充分说明了其配置调整是很常用的场景,下面举几个常见的配置项,如node状态汇报频率、pod最大数量、以及生产运行非常重要的pod驱逐、资源保留等。
旧版本kubelet配置
在1.11版本之前,kubelet通过命令flag的方式指定和调整参数,例如:
--node-status-update-frequency=5s
# 向apiserver刷新node状态的时间间隔,默认10s--serialize-image-pulls=false
# 是否串行拉取镜像,默认为true,false改为并行,提升拉取镜像速度--max-pods=200
# 单node运行的最大pod数量,默认110,注意调整不要超过pod CIDR的单个子网可用地址数量。--eviction-hard=memory.available<1024Mi,nodefs.available<10%
# 节点资源小于指定值时开启硬驱逐上吗的pod
资源保留配置
为防止pod使用过多的资源,从而挤占和影响了k8s控制组件(例如kubelet)、系统管理进程的正常运行,指定以下配置为这两者保留一部分的资源。与pod QOS 一样,资源保留的方式同样也是使用cgroup来做资源隔离保证。
--enforce-node-allocatable=pods,kube-reserved,system-reserved
# 开启针对这几者的cgroup资源管理。--kube-reserved-cgroup=/system.slice/kubelet.service
# 指定k8s组件保留资源对应的cgroup路径--system-reserved-cgroup=/system.slice
# 指定系统组件保留资源对应的cgroup路径- `–kube-reserved=cpu=1,memory=2Gi # 指定k8s组件保留1g/1c的资源
- `–system-reserved=cpu=1,memory=1Gi # 为系统运行保留1g/1c的资源
以上参数配置在kubelet systemd启动服务内,例如kubeadm安装的集群,kubelet启动服务一般在/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
路径内,配置环境变量的形式来修改启动配置,例如:
1 | # 增加一个变量 |
新版本kubelet配置
1.11及以后的版本,开始使用配置文件的形式指定kubelet配置,不再建议使用flag参数的形式。配置文件的路径在启动服务的文件里可以找到,如果使用的是kubeadm安装的,路径一般是/var/lib/kubelet/config.yaml
各版本可能有些许不同。参数其实还是与上方一致,只不过abc-def式写法变成了go更推荐的驼峰式写法,这里不再对参数作解释,直接贴出配置
1 | address: 0.0.0.0 |
看到网上有很多内容高度一致的文章将systemReserved和kubeReserved两者都同时开启了,其实官方不建议开启systemReserved,因为这可能会导致系统关键进程遭遇不可控的风险,说明如下:
Be extra careful while enforcing system-reserved
注:非常重要!kubelet并不会自动创建cgroup,因此,需要在启动服务前为其指定创建相应cgroup的命令,建议写入启动服务文件内,无论是传统指定flag方式,还是配置文件方式,都需要在启动服务文件内添加创建cgroup的命令,否则kubelet服务会启动失败
这里贴一个新版本的启动服务文件内容:
1 | ~# cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf |
修改完以上配置后,执行systemctl daemon-reload && systemctl restart kubelet
重启kubelet,若无意外,kubelet重启正常后,可检验cgroup是否如期创建指定的内存限制,如下刚好是2g,说明cgroup指定已成功:
1 | cat /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.limit_in_bytes |
当然,以上的kubelet配置修改需要重启kubelet,如果你需要直接在线更新kubelet配置的话,可以参考官方的的步骤进行修改配置:
Reconfiguring the Kubelet on a Live Node in your Cluster
Controller参数配置
controller常调整的参数是针对其驱逐功能的,即在node进入离线状态后,将node置为ConditionUnknown状态,并在持续一段时间后开始依一定的次序驱逐问题node上面pod到其他node上,以尽快恢复到声明数量的ready副本数。
--node-cidr-mask-size
# node上的pod cidr掩码位数,默认为24位,即最多253个可用地址,视地址空间和pod数量调整。--node-monitor-period
# 检查当前node健康状态的周期间隔,默认5s--node-monitor-grace-period
# 当前node超过了这个指定周期后,即视node为不健康,进入ConditionUnknown状态,默认40s--pod-eviction-timeout
# 当node进入notReady状态后,经过这个指定时间后,会开始驱逐node上的pod,默认5m--large-cluster-size-threshold
# 判断集群是否为大集群,默认为 50,即 50 个节点以上的集群为大集群。--unhealthy-zone-threshold
:# 故障节点数比例,默认为 55%--node-eviction-rate
# 开始对node进行驱逐操作的频率,默认0.1个/s,即每10s最多驱逐某一个node上的pod,避免当master出现问题时,会有批量的node出现异常,这时候如果一次性驱逐过多的node,对master造成额外的压力--secondary-node-eviction-rate
: # 当集群规模大于large-cluster-size-threshold个node时,视为大集群, 集群中只要有55%的node不健康, 就会认为master出现了故障, 会将驱逐速率从0.1降为0.001; 如果集群规模小于large-cluster-size-threshold个node, 集群中出现55%的node不健康,就会停止驱逐。
配置建议:
中大规模集群(500+ node)
大规模集群一般节点数较多,优势是可用性、抗风险能力强,劣势是组件之间的交互频繁,会给apiServer和etcd带来较大的压力,因此配置建议:
--node-monitor-period
适当增加--large-cluster-size-threshold
适当增加--unhealthy-zone-threshold
适当减小--pod-eviction-timeout
视服务可用性保障级别适当调整--node-eviction-rate
视服务可用性保障级别适当增加--secondary-node-eviction-rate
视服务可用性保障级别适当增加
小规模集群(100- node)
小规模集群一般节点数不多,因此副本数量一般也较小,对节点中断的容忍度和容忍时间较低,因此配置建议:
--node-monitor-period
不变或可适当减小--pod-eviction-timeout
大幅减小,如1m-2m,单节点故障尽快转移上面的pod--node-eviction-rate
建议减小,避免问题pod转移导致集群快速雪崩,预留防范处理时间
如果使用kubeadm部署的,修改yaml文件即可自动触发 apiserver/scheduler/controller这几个static pod的重启, 3者的yaml文件都位于:/etc/kubernetes/manifests/
下,修改保存pod即会自动重启加载新配置。
另注:默认驱逐pod的优先级
根据pod的QOS保证级别,优先驱逐调度保证保障质量高级别的pod最先恢复正常:
BestEffort > Burstable > Guaranteed
ApiServer参数配置
--max-mutating-requests-inflight
# 单位时间内的最大修改型请求数量,默认200--max-requests-inflight
# 单位时间内的最大非修改型(读)请求数量,默认400--watch-cache-sizes
# 各类resource的watch cache,默认100,资源数量较多时需要增加--feature-gates=VolumeSubpathEnvExpansion=true
# 开启alpha版的功能,默认alpha版功能是关闭的,可以通过这个参数指定来开启某些alpha状态的功能,关于各功能所处的alpha、beta、GA状态,请查询官方文档:
Scheduler参数配置
scheduler的配置项比较少,因为调度规则已经是很明确了,不过可以自定义预选和优选策略。
--kube-api-qps
# 请求apiserver的最大qps,默认50--policy-config-file
# json文件,不指定时使用默认的调度预选和优选策略,可以自定义指定,样例参考:scheduler-policy-config.json
调度策略分为预选和优选两个步骤,建议对其过程或源码有一定了解后,再做策略调整,调度过程可以参考我的源码笔记:
调度策略的调整要与自身的环境结合,默认的优选策略中,每一项计算纬度的权重默认几乎都是1,在我的环境中,比较重视资源平均利用率以及服务副本的高可用性,因此,将SelectorSpreadPriority
和BalancedResourceAllocation
调高。下面是我的json文件:
scheduler-policy-config.json
1 | { |
注意
指定policy配置启动scheduler后,会完全覆盖默认注册的所有调度策略,因此,即使是无需改动的策略纬度,必须完全显示的在policy json中写出来,如果不写出,scheduler重启后该项纬度不再使用。
配置完成后,修改scheduler的启动参数,指定此json文件,同时,最好将此文件使用configMap形式或其他形式持久化挂载。
内核参数配置
1 | fs.file-max=1000000 |