刷新docker容器的net.core.somaxcomm(或任何sysctl属性)

我正在尝试更改net.core.somaxconn容器的net.core.somaxconn ,以便能够为我的Web应用程序提供更大的请求队列。

在操作系统上,在Docker之外,我首先成功地修改了属性:

 $ cat /proc/sys/net/core/somaxconn 128 $ sudo sysctl -w net.core.somaxconn=1024 net.core.somaxconn = 1024 $ cat /proc/sys/net/core/somaxconn 1024 

但是,我不知道如何把这个变化传播到docker。 我试过了:

  • 还要编辑/etc/sysctl.conf (希望docker在容器启动时读取该文件)
  • 重新启动容器sudo docker stopsudo docker run再次sudo docker run
  • 通过sudo service docker restart整个docker服务

但是在容器里面, cat /proc/sys/net/core/somaxconn总是显示128

我正在运行docker1.2(所以我不能,默认情况下,修改容器内的/proc属性)和Elastic Beanstalk(所以没有 – --privileged模式,这将允许我修改/proc )。

我如何将sysctl更改传播给docker?

Solutions Collecting From Web of "刷新docker容器的net.core.somaxcomm(或任何sysctl属性)"

只是想出了如何解决这个问题,现在Elastic Beanstalk支持运行一个特权容器 ,你只需要在你的Dockerrun.aws.json添加"privileged": "true" ,如下面的示例(请看一下container-1 ):

 { "AWSEBDockerrunVersion": 2, "containerDefinitions": [{ "name": "container-0", "essential": "false", "image": "ubuntu", "memory": "512" }, { "name": "container-1", "essential": "false", "image": "ubuntu", "memory": "512", "privileged": "true" }] } 

请注意 ,我从另一个线程复制了这个答案 。

“网络/核心”子系统是按照网络名称空间注册的 。 somaxconn的初始值设置为128。

当你在主机系统上执行sysctl时,它为它的网络命名空间设置核心参数,这是init所拥有的。 (基本上这是默认的命名空间)。 这不会影响其他网络名称空间。

当一个Docker容器启动时,该容器的虚拟网络接口(在主机上显示为vethXXX ) 被附加到它自己的名字空间 ,它仍然具有最初的somaxconn值128.所以从技术上讲,你不能将这个值传播到容器,因为两个网络名称空间不共享它。

但是,有两种方法可以调整此值,另外还可以在特权模式下运行容器。

  1. 运行容器时使用“–net host”,所以它使用主机的网络接口,因此共享相同的网络名称空间。

  2. 您可以使用Docker的卷映射支持将proc文件系统挂载为读写。 诀窍是把它映射到一个名为“/ proc”的卷上,因为Docker会将/ proc / sys等重新挂载为非特权容器的只读 。 这要求主机将/ proc挂载为rw,这在大多数系统上就是这种情况。

     docker run -it --rm -v /proc:/writable-proc ubuntu:14.04 /bin/bash root@edbee3de0761:/# echo 1024 > /writable-proc/sys/net/core/somaxconn root@edbee3de0761:/# sysctl net.core.somaxconn net.core.somaxconn = 1024 

方法2应该通过Dockerrun.aws.json中的卷映射支持在Elastic Beanstalk上工作。 此外,它应该为每个命名空间的/ proc下的其他可调参数工作。 但是这很可能是Docker部分的一个疏漏,所以他们可能会在卷映射上增加额外的验证,而这个技巧将无法工作。

我找到一个解决方案:

 { "AWSEBDockerrunVersion": "1", "Command": "run COMMAND", "Image": { "Name": "crystalnix/omaha-server", "Update": "true" }, "Ports": [ { "ContainerPort": "80" } ] } 

更多细节在这里:/opt/elasticbeanstalk/hooks/appdeploy/pre/04run.sh

更新:

添加文件.ebextensions/02-commands.config

 container_commands: 00001-docker-privileged: command: 'sed -i "s/docker run -d/docker run --privileged -d/" /opt/elasticbeanstalk/hooks/appdeploy/pre/04run.sh' 

docker 1.12添加对使用–sysctl设置sysctl的支持。

 docker run --name some-redis --sysctl=net.core.somaxconn=511 -d redis 

docs: https : //docs.docker.com/engine/reference/commandline/run/#/configure-namespaced-kernel-parameters-sysctls-at-runtime

更新:因为Docker现在支持docker run --sysctl选项,所以这个答案已经过时了。

我用于OpenVPN容器的解决方案是使用nsenter进入具有完整功能的容器名称空间, nsenter重新nsenter /proc/sys读写,设置填充并重新将其重新nsenter只读。

这里是一个例子,在容器中启用IPv6转发:

 CONTAINER_NAME=openvpn # enable ipv6 forwarding via nsenter container_pid=`docker inspect -f '{{.State.Pid}}' $CONTAINER_NAME` nsenter --target $container_pid --mount --uts --ipc --net --pid \ /bin/sh -c '/usr/bin/mount /proc/sys -o remount,rw; /usr/sbin/sysctl -q net.ipv6.conf.all.forwarding=1; /usr/bin/mount /proc/sys -o remount,ro; /usr/bin/mount /proc -o remount,rw # restore rw on /proc' 

这样容器不需要运行特权。

在docker 3.1中有指定sysctl的支持。 注意
的sysctl:
– net.core.somaxconn = 1024

我的示例docker-compose文件

 version: '3.1' services: my_redis_master: image: redis restart: always command: redis-server /etc/redis/redis.conf volumes: - /data/my_dir/redis:/data - /data/my_dir/logs/redis:/var/tmp/ - ./redis/redis-master.conf:/etc/redis/redis.conf sysctls: - net.core.somaxconn=1024 ports: - "18379:6379"