docker_sysctl
Sysctl 用于配置运行时的内核参数,正常情况下修改 /etc/sysctl.conf
. 然后执行 sysctl -p
就能够设置成功。
当使用 Docker 启动服务时,使用 sysctl -p 来配置 docker 的参数时会出现问题。比如
1 | sysctl: cannot stat /proc/sys/net/core/rmem_max: No such file or directory |
由于是配置的内核参数,如果容器修改了内核的参数,还是需要宿主机支持才行,直接修改是不支持的。 Docker的base image做的很精简,甚至都没有init进程,原本在OS启动时执行生效系统变量的过程(sysctl -p)也给省略了,导致这些系统变量依旧保留着kernel默认值。
在 Docker 中对 sysctl 做了一些支持。 但是也只是有限的支持。在 Docker 启动容器时,指定 –sysctl 参数可以设置 sysctl 的参数 。 在 docker-compose.yml 文件中也提供了 sysctls 的参数 。
1 | sysctls: |
但是,Docker 中 sysctl 的可调参数要比宿主机少得多。
未被 docker 限制的参数Docker通过一个 ValidateSysctl函数来限制 sysctl参数可以传入的项。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// docker/opts/opts.go
func ValidateSysctl(val string) (string, error) {
validSysctlMap := map[string]bool{
"kernel.msgmax": true,
"kernel.msgmnb": true,
"kernel.msgmni": true,
"kernel.sem": true,
"kernel.shmall": true,
"kernel.shmmax": true,
"kernel.shmmni": true,
"kernel.shm_rmid_forced": true,
}
validSysctlPrefixes := []string{
"net.",
"fs.mqueue.",
}容器中可以看见该配置项可以使用 sysctl -a 看到
配置项可以 namespace 化配置项无法 namespace化,指的是该配置项是全局的,无法为每个 namespace生成独立的配置。一般来说,宿主机和容器是一对多的关系,一个无法 namespace化的配置项,调整之后会影响所有其他容器以及宿主机本身,这是我们无法接受的。
以上内容参考https://segmentfault.com/a/1190000009225126
- 在设置 socket 的一些网络参数时 。对内核参数进行修改
1 | net.core.wmem_max=12582912 |
直接修改 docker 的 sysctl 是不能成功的。 在 docker-compose 中可以通过使用 network_mode: “host” ,修改宿主机的参数来实现。 缺点时集群模式无法使用,并且容器和宿主机共享网络空间,无法做到隔离。
- 使用 –privileged默认情况下 docker 容器是无特权的。容器不允许访问任何的设备。授予 –privileged 后,Docker 启动对宿主机的所有设备的访问。以允许容器对主机的访问几乎与在主机上容器外部运行的进程相同。
docker_sysctl