CentOS升级内核与容器运行时内核参数的关系


背景

还是最近一些诡异的问题
想能够根因分析一下.
所以继续总结和验证

CentOS7升级内核

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
查看可以升级的内核

yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
2024.6 的展示结果为:
可安装的软件包
elrepo-release.noarch                   7.0-6.el7.elrepo            elrepo-kernel
kernel-lt.x86_64                        5.4.277-1.el7.elrepo        elrepo-kernel
kernel-lt-devel.x86_64                  5.4.277-1.el7.elrepo        elrepo-kernel
kernel-lt-doc.noarch                    5.4.277-1.el7.elrepo        elrepo-kernel
kernel-lt-headers.x86_64                5.4.277-1.el7.elrepo        elrepo-kernel
kernel-lt-tools.x86_64                  5.4.277-1.el7.elrepo        elrepo-kernel
kernel-lt-tools-libs.x86_64             5.4.277-1.el7.elrepo        elrepo-kernel
kernel-lt-tools-libs-devel.x86_64       5.4.277-1.el7.elrepo        elrepo-kernel
kernel-ml.x86_64                        6.9.4-1.el7.elrepo          elrepo-kernel
kernel-ml-devel.x86_64                  6.9.4-1.el7.elrepo          elrepo-kernel
kernel-ml-doc.noarch                    6.9.4-1.el7.elrepo          elrepo-kernel
kernel-ml-headers.x86_64                6.9.4-1.el7.elrepo          elrepo-kernel
kernel-ml-tools.x86_64                  6.9.4-1.el7.elrepo          elrepo-kernel
kernel-ml-tools-libs.x86_64             6.9.4-1.el7.elrepo          elrepo-kernel
kernel-ml-tools-libs-devel.x86_64       6.9.4-1.el7.elrepo          elrepo-kernel
perf.x86_64                             5.4.277-1.el7.elrepo        elrepo-kernel
python-perf.x86_64                      5.4.277-1.el7.elrepo        elrepo-kernel

yum --disablerepo="*"  --enablerepo=elrepo-kernel install kernel-lt.x86_64  -y
yum --disablerepo="*"  --enablerepo=elrepo-kernel install kernel-ml.x86_64  -y


ml 版本是 main line 的含义 主线一般是大家都在开发的不太稳定. 
lt 是超期支持的版本.  

如果是生产, 建议使用lt 如果是测试可以选择mt. 
grub2-set-default  0 && grub2-mkconfig -o /etc/grub2.cfg
grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"

CentOS7 可以手工更换不同内核. 
cat /boot/grub2/grub.cfg  | grep ^menuentry
grub2-set-default '4.19.12-1.el7.elrepo.x86_64'
grub2-editenv list

CentOS8 切换内核的方法:
# 查看当前
grubby --default-kernel
# 查看所有
grubby --info=ALL   |grep ^kernel
# 设置
grubby --set-default /boot/vmlinuz-4.19.0-80.11.2.el8_0.x86_64   

比如我这边的内核版本列表为:
kernel=/boot/vmlinuz-6.9.4-1.el7.elrepo.x86_64
kernel=/boot/vmlinuz-5.4.277-1.el7.elrepo.x86_64
kernel=/boot/vmlinuz-4.19.12-1.el7.elrepo.x86_64
kernel=/boot/vmlinuz-3.10.0-1160.el7.x86_64
查看部分内容:
sysctl -a |wc -l
docker run -it --rm grafana/grafana-image-renderer sysctl -a |wc -l

内核参数数量信息

内核版本

虚拟机

容器

差值

3.10

1303

878

425

4.19

1482

1038

444

5.4

1423

978

445

6.9

1436

959

477


对部分参数的验证

grep -ir net.ipv4.tcp_sack :
3.10.vm____.info:net.ipv4.tcp_sack = 1
4.19.docker.info:net.ipv4.tcp_sack = 1
4.19.vm____.info:net.ipv4.tcp_sack = 1
5.4.docker.info:net.ipv4.tcp_sack = 1
5.4.vm____.info:net.ipv4.tcp_sack = 1
6.9.docker.info:net.ipv4.tcp_sack = 1
6.9.vm____.info:net.ipv4.tcp_sack = 1

grep -ir net.ipv4.tcp_max_tw :
3.10.vm____.info:net.ipv4.tcp_max_tw_buckets = 5000
4.19.docker.info:net.ipv4.tcp_max_tw_buckets = 262144
4.19.vm____.info:net.ipv4.tcp_max_tw_buckets = 5000
5.4.docker.info:net.ipv4.tcp_max_tw_buckets = 262144
5.4.vm____.info:net.ipv4.tcp_max_tw_buckets = 5000
6.9.docker.info:net.ipv4.tcp_max_tw_buckets = 262144
6.9.vm____.info:net.ipv4.tcp_max_tw_buckets = 5000

grep -ir net.ipv4.ip_local_port : 
3.10.docker.info:net.ipv4.ip_local_port_range = 32768   60999
3.10.vm____.info:net.ipv4.ip_local_port_range = 9000        65500
4.19.docker.info:net.ipv4.ip_local_port_range = 32768   60999
4.19.vm____.info:net.ipv4.ip_local_port_range = 9000        65500
5.4.docker.info:net.ipv4.ip_local_port_range = 32768    60999
5.4.vm____.info:net.ipv4.ip_local_port_range = 9000 65500
6.9.docker.info:net.ipv4.ip_local_port_range = 32768    60999
6.9.vm____.info:net.ipv4.ip_local_port_range = 9000 65500

感悟

net.ipv4.tcp_max_tw_buckets
net.ipv4.tcp_sack
部分参数在 3.10 的版本没有传递到容器内, 的确是存在bug
容器自己运行不会将配置好的内核参数传递进容器内
需要自己进行指定. 

关于 
net.ipv4.tcp_max_tw_buckets 和 net.ipv4.ip_local_port_range
应该是跟厂商有关系. 
厂商编译的时候会选择一个特定的内核参数值
银河麒麟的 tw_bucket 就是 13万. 继承在openeuler

红帽就比较保守一些. 
所以内核有bug 内核还有自己的脾气性格.