Kubernetes worknode 内核参数优化参考

个人在实际过程中踩坑后的Kubernetes worknode的内核参数调整,仅供参考

▶ cat /etc/security/limits.conf
*   hardnofile  65536
*   softnofile  65536
*   hardnproc   65536
*   softnproc   65536
▶ cat /etc/sysctl.d/99-kubernetes.conf 
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# 以下三个参数是 arp 缓存的 gc 阀值,相比默认值提高了,当内核维护的 arp 表过于庞大时候,可以考虑优化下,避免在某些场景下arp缓存溢出导致网络超时,参考:https://k8s.imroc.io/avoid/cases/arp-cache-overflow-causes-healthcheck-failed
# 存在于 ARP 高速缓存中的最少层数,如果少于这个数,垃圾收集器将不会运行。缺省值是 128 
net.ipv4.neigh.default.gc_thresh1 = 2048 
# 保存在 ARP 高速缓存中的最多的记录软限制。垃圾收集器在开始收集前,允许记录数超过这个数字 5 秒。缺省值是 512 
net.ipv4.neigh.default.gc_thresh2 = 4096 
# 保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是 1024 
net.ipv4.neigh.default.gc_thresh3 = 8192
# 该参数用于设定系统中最多允许存在多少tcp套接字不被关联到任何一个用户文件句柄上
net.ipv4.tcp_max_orphans = 32768
# 在 TIME_WAIT 数量等于 tcp_max_tw_buckets 时,不会有新的 TIME_WAIT 产生
net.ipv4.tcp_max_tw_buckets = 32768
net.ipv4.ip_forward = 1
# net.ipv4.tcp_tw_recycle 这个内核参数的作用是通过 PAWS 实现 TIME_WAIT 快速回收。在 PAWS 的理论基础上,如果内核保存 Per-Host 的最近接收时间戳,接收数据包时进行时间戳比对,就能避免 TIME_WAIT 意图解决的第二个问题:前一个连接的数据包在新连接中被当做有效数据包处理的情况。这样就没有必要维持 TIME_WAIT 状态 2 * MSL 的时间来等待数据包消失,仅需要等待足够的 RTO(超时重传),解决 ACK 丢失需要重传的情况,来达到快速回收TIME_WAIT状态连接的目的。但上述理论在多个客户端使用 NAT 访问服务器时会产生新的问题:同一个 NAT 背后的多个客户端时间戳是很难保持一致的( timestamp 机制使用的是系统启动相对时间),对于服务器来说,两台客户端主机各自建立的 TCP 连接表现为同一个对端 IP 的两个连接,按照 Per-Host 记录的最近接收时间戳会更新为两台客户端主机中时间戳较大的那个,而时间戳相对较小的客户端发出的所有数据包对服务器来说都是这台主机已过期的重复数据,因此会直接丢弃。这就是之前我描述的问题产生的根本原因,在公司的 NAT 防火墙内会有问题,而在防火墙外面就没有问题;设置 net.ipv4.tcp_tw_recycle=1 的服务器访问有问题,而没有进行内核参数优化的另一台服务器没有问题
net.ipv4.tcp_tw_recycle = 0
vm.swappiness = 0
# vm.overcommit_memory内存分配策略 
# 0:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。 
# 1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何
# 2:表示内核允许分配超过所有物理内存和交换空间总和的内存
vm.overcommit_memory = 1
# 等于0时,表示当内存耗尽时,内核会触发OOM killer杀掉最耗内存的进程
vm.panic_on_oom = 0
# 最大文件句柄
vm.max_map_count = 262144
# 表示同一用户同时最大可以创建的 inotify 实例 (每个实例可以有很多 watch) 
fs.inotify.max_user_instances = 8192
# 表示同一用户同时可以添加的watch数目(watch一般是针对目录,决定了同时同一用户可以监控的目录数量) 默认值 8192 在容器场景下偏小,在某些情况下可能会导致 inotify watch 数量耗尽,使得创建 Pod 不成功或者 kubelet 无法启动成功,将其优化到 524288
fs.inotify.max_user_watches = 1048576
# 系统级别文件句柄设置
fs.file-max = 52706963
fs.nr_open = 52706963
net.ipv6.conf.all.disable_ipv6 = 1
# 查看established连接状态最多保留几天,默认是432000秒,就是5天
net.netfilter.nf_conntrack_tcp_timeout_established = 7200
# 此参数表示是否允许服务绑定一个本机不存在的IP地址
net.ipv4.ip_nonlocal_bind = 1
# 保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是 1024 
net.ipv4.neigh.default.gc_thresh3 = 8192
# 最大跟踪连接数,默认 nf_conntrack_buckets * 4
net.nf_conntrack_max = 1048576
# 允许的最大跟踪连接条目,是在内核内存中 netfilter 可以同时处理的“任务”(连接跟踪条目
net.netfilter.nf_conntrack_max = 2310720
# tcp_max_syn_backlog是指定所能接受SYN同步包的最大客户端数量,即半连接上限,默认值是128,即SYN_REVD状态的连接数
net.ipv4.tcp_max_syn_backlog = 8096
# 哈希表大小(只读)(64位系统、8G内存默认 65536,16G翻倍,如此类推)net.netfilter.nf_conntrack_buckets 不能直接改(报错)需要修改模块的设置:echo 65536 > /sys/module/nf_conntrack/parameters/hashsize
net.netfilter.nf_conntrack_buckets = 65536
# 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
net.core.netdev_max_backlog = 10000
# 表示socket监听(listen)的backlog上限,也就是就是socket的监听队列(accept queue),当一个tcp连接尚未被处理或建立时(半连接状态),会保存在这个监听队列,默认为 128,在高并发场景下偏小,优化到 32768。参考 https://imroc.io/posts/kubernetes-overflow-and-drop/
net.core.somaxconn = 32768
# PID 与线程限制
kernel.pid_max=65535
kernel.threads-max=65535

参考文献
https://k8s.imroc.io/best-pra...

你可能感兴趣的:(kubernetes,linux运维)