容器能调内核参数吗?哪些参数只影响自己、哪些根本不让设?这篇逐项实测 --sysctl 的规则,并确认虚拟机里的值没有被改动。
虚拟机里的当前值:net.ipv4.ip_forward=1 ; net.core.somaxconn=4096 ; net.ipv4.ip_local_port_range=55000 65535 ; kernel.shmmax=18446744073692774399 默认容器里的值:net.ipv4.ip_forward=1 ; net.core.somaxconn=4096 ; net.ipv4.ip_local_port_range=32768 60999 ; kernel.shmmax=18446744073692774399 --sysctl net.ipv4.ip_forward=1 net.core.somaxconn=1024 net.ipv4.ip_local_port_range="40000 40100" kernel.shmmax=1048576:退出码 0;容器里 net.ipv4.ip_forward=1 ; net.core.somaxconn=1024 ; net.ipv4.ip_local_port_range=40000 40100 ; kernel.shmmax=1048576 同一时刻虚拟机里的值(不应变):net.ipv4.ip_forward=1 ; net.core.somaxconn=4096 ; net.ipv4.ip_local_port_range=55000 65535 ; kernel.shmmax=18446744073692774399
网络(net.*)和 IPC(kernel.shm*、kernel.msg*、kernel.sem、fs.mqueue.*)是各命名空间自己的,--sysctl 只改容器里的值,虚拟机的值不动。容器的网络命名空间默认值也和虚拟机不同(端口范围 32768 60999 对 55000 65535)。
--sysctl vm.swappiness=10:退出码 125;invalid argument "vm.swappiness=10" for "--sysctl" flag: sysctl 'vm.swappiness=10' is not allowed --sysctl kernel.panic=1:退出码 125;invalid argument "kernel.panic=1" for "--sysctl" flag: sysctl 'kernel.panic=1' is not allowed --sysctl fs.file-max=100000:退出码 125;invalid argument "fs.file-max=100000" for "--sysctl" flag: sysctl 'fs.file-max=100000' is not allowed --sysctl kernel.pid_max=65536:退出码 125;invalid argument "kernel.pid_max=65536" for "--sysctl" flag: sysctl 'kernel.pid_max=65536' is not allowed
vm.swappiness、kernel.panic、fs.file-max、kernel.pid_max 不是命名空间级的,docker 直接拒绝(我只试了这四个,没有穷举白名单)。
--network host + net.ipv4.ip_forward:退出码 125;sysctl "net.ipv4.ip_forward" not allowed in host network namespace --ipc host + kernel.shmmax:退出码 125;sysctl "kernel.shmmax" is not allowed in the hosts ipc namespace --network none + net.core.somaxconn:退出码 0;512
用了 --network host 或 --ipc host,容器和虚拟机共用命名空间,改了就会改到虚拟机的,所以同样被拒绝。
默认容器里:写 ip_forward 退出码 1 ; 写 swappiness 退出码 1 ; ro ; sh: can't create /proc/sys/net/ipv4/ip_forward: Read-only file system ; sh: can't create /proc/sys/vm/swappiness: Read-only file system
/proc/sys 在容器里是只读的(c44 里 --privileged 才会变成可写),想调参数必须在启动时声明。