内核管理
内核
内核是操作系统的核心核心,它是最早启动、权限最高、一直驻留在内存里的程序。通俗的讲,它就像是工厂的厂长兼大管家,负责以下任务:
- 管硬件:它手里握着工厂所有设备(CPU、内存、硬盘、网卡)的钥匙。
- 管软件:所有普通工人(应用程序,如 Nginx、MySQL、你的 Shell)想用机器干活,都必须先向厂长打报告(系统调用),厂长批准了才能用。
- 特点:它必须非常精简、稳定。如果厂长倒下了(Kernel Panic),整个工厂就立刻停工瘫痪。
文件形式: 通常是 /boot/vmlinuz-xxx,这是一个把很多核心功能压缩在一起的静态文件。
官网:https://www.kernel.org/
常见管理命令:
# 查看当前系统正在使用的内核版本
uname -r
# 显示内核相关的所有信息
uname -a内核模块
内核模块是可以根据需求,动态加载到内核里运行的代码片段。通俗的讲,内核模块就像是厂长临时请来的特种外包工。
- 按需聘用:工厂突然买了一台非常冷门的新机器(比如海光网卡),厂长自己不会操作,也没必要为了这一台机器专门去学(这会让厂长变得臃肿)。于是,厂长就临时喊来一个懂这台机器的专家(加载 .ko 模块)来操作。
- 即插即用:活干完了,或者机器换了,这个专家就可以走人(卸载模块),不需要关闭整个工厂。
- 特点:灵活、节省资源。
- 如果不使用内核模块按需加载,就必须把全世界成千上万种硬件(显卡、网卡、声卡)的驱动全部写死在 Kernel 里。Kernel 会变成几百 GB 大,启动慢得要命,而且极其占内存。)
- 使用 Modules 后:Kernel 只保留最核心的功能(调度 CPU、管理内存)。Kernel 只有几兆大,启动飞快。需要用什么硬件,就临时加载对应的 .ko 模块即可。
文件形式: 通常是 .ko 文件(Kernel Object),存放在 /lib/modules/xxx/ 目录下。
编译内核模块
注意事项:
- 在其他主机编译内核,然后拷贝 .ko 文件到当前主机,需要确保两台主机内核版本一致。
- 如果 Kernel 是 6.6.0-28 版本,它就只能通过 6.6.0-28 版本的接口和 Modules 交流。
- 如果拿一个为 6.6.0-132 编译的 Module 强行塞给 .28 的 Kernel,Kernel 听不懂它的指令,直接拒绝(报错 Invalid module format)。
下面以海光网卡为例,演示如何编译内核模块:
# 解压压缩包
tar -xvzf XGbEDriver-xxx.tar.gz
# 进入源码目录
cd XGbEDriver/driver/xgbe/
# 编译模块
make
# 安装模块
make install
# 该模块会被安装到 /lib/modules/<KERNEL_VER>/updates/drivers/net/ethernet/amd/xgbe/amd-xgbe.ko目录下将编译好的模块加载到内核:
# 如果是将模块拷贝到了其他机器的 /lib/modules/<KERNEL_VER>/updates/xxx 目录下,需要更新模块依赖关系文件
depmod -a
# 加载模块
modprobe amd-xgbe
# 查看模块是否加载成功
lsmod | grep amd-xgbe内核模块相关管理工具
# 显示由核心已经装载的内核模块,显示的内容来自于:/proc/modules 文件
# 输出内容依次为 模块名称、大小、使用次数、被哪些模块所依赖
lsmod
# 管理内核模块、显示模块详细的描述信息,配置文件:/etc/modprobe.conf、/etc/modprobe.d/*.conf
modinfo
# 装载或卸载内核模块
modprobe
# 内核模块依赖关系文件及系统信息映射文件的生成工具
depmod
# 可以安装模块,需要指定模块文件路径,不能自动解决依赖模块
insmod
# 卸载模块
rmmod内核模块参数管理
查看某个模块支持哪些参数:
modinfo -p amd-xgbe.ko
临时修改:
modprobe amd-xgbe debug=1
永久修改:
- 写在 /etc/modprobe.d/amd-xgbe.conf 里(内容:options amd-xgbe debug=1)。
内核参数
常用内核参数
net.* (网络相关)
# 是否禁ping,0为默认值 即允许ping 、1表示禁止ping
net.ipv4.icmp_echo_ignore_all
# 是否允许应用程序可以监听本地不存在的IP,0不允许、1允许,应用场景有keepalived等
net.ipv4.ip_nonlocal_bind
# 是否开启IP转发,0不开启、1开启,做容器宿主机或路由器时必须设为 1,否则容器上不了网。
net.ipv4.ip_forward
# 是否开启TIME-WAIT状态的端口重用,0不开启、1开启,高并发必备。允许将TIME-WAIT sockets重新用于新的TCP连接。
# 如果不开启,高并发时服务器会因为端口耗尽而无法建立新连接。
net.ipv4.tcp_tw_reuse
# 表示系统同时保持TIME_WAIT状态的最大数量,用于Nginx/Redis 调优等场景,数量过少会导致用户连接超时。
net.core.somaxconn
# 表示TCP keepalive(保活)定时器开始发送探测报文之前的空闲时间。默认值是7200秒(2小时)。如为了快速发现死链,通常会改小(如 600秒)。
net.ipv4.tcp_keepalive_time
# 向外连接的端口范围,如果不调大,作为服务端(如 Nginx 反向代理)发起连接时端口很快就不够用了。
net.ipv4.ip_local_port_rangevm.* (虚拟内存相关)
# 表示系统在内存使用到多少百分比时开始使用swap,默认值是 60。
vm.swappiness
# 表示系统是否允许超量申请内存,0表示不允许、1表示允许。
# 建议设置为 1,否则会导致应用程序因为内存不足而崩溃。
vm.overcommit_memory
# 表示系统最多可以创建的映射内存区域数量,默认值是 65536。
# 如运行多个容器,每个容器都有自己的内存映射区域,数量会增加。
# Elasticsearch 启动必改。ES 需要大量的内存映射区,默认值太小(65530),必须调大(如 262144),否则 ES 直接起不来。
vm.max_map_count
# 表示系统在内存使用到多少百分比时开始写入swap,默认值是 30。
vm.dirty_ratiokernel.* (内核核心相关)
# 表示系统最多可以创建的进程ID号,默认值是 32768。
# 如运行多个容器,每个容器都有自己的进程ID,数量会增加。
kernel.pid_max
# 表示系统的主机名,默认值是 localhost。
kernel.hostname
# 表示系统在发生panic(系统崩溃)时是否自动重启,默认值是 0,表示不自动重启。
kernel.panicfs.* (文件系统相关)
# 表示系统在文件系统中最多可以创建的文件数量.
fs.file-max修改内核参数
临时修改:
sysctl -w kernel.hostname=centos8
永久修改:
# 可在主配置文件或子配置文件中修改
/etc/sysctl.conf # 主配置文件
/etc/sysctl.d/*.conf # 子配置文件,以.conf结尾
# 使配置文件立即生效,如修改的是主配置文件则后面无需加配置文件路径
sysctl -p [/path/to/conf_file] 查看当前所有已生效的内核参数:
sysctl -a