21

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

在 OS 上,在 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再次
  • 通过以下方式重新启动整个 docker 服务sudo service docker restart

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

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

如何将 sysctl 更改传播到 docker?

4

7 回答 7

39

“net/core”子系统是按网络命名空间注册的。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 的疏忽,所以他们可能会在卷映射上添加额外的验证,然后这个技巧就行不通了。

于 2014-10-04T22:42:40.363 回答
8

docker 1.12 添加了对使用 --sysctl 设置 sysctls 的支持。

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

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

于 2016-09-15T14:48:33.653 回答
4

我找到了一个解决方案:

{
    "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'
于 2014-12-09T07:27:22.720 回答
4

更新:此答案已过时,因为 Docker 现在支持该docker run --sysctl选项!

我用于我的 OpenVPN 容器的解决方案是使用 进入具有完整功能的容器命名空间,临时nsenter重新安装/proc/sys读写,设置内容并再次以只读方式重新安装它。

下面是一个示例,在容器中启用 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'

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

于 2015-07-19T10:21:37.523 回答
2

刚刚弄清楚如何解决这个问题,现在Elastic Beanstalk 支持运行特权容器,您只需将其添加"privileged": "true"到您Dockerrun.aws.json的示例中(请查看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"
  }]
}

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

于 2016-03-15T19:27:08.297 回答
2

在 docker 3.1 中,支持指定 sysctl。注意sysctls

    -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"                                   
于 2017-06-15T05:17:41.380 回答
1

正如@nazim.sp 回答 Docker compose 将支持 sysctls,我遇到了与 @Or Gal “忽略不支持的选项:”相同的问题,但是使用不同的语法,它被接受了来自 docker-compose.yaml 的示例节

redis:
  image: redis
  container_name: redis
  sysctls: 
    net.core.somaxconn: "1024"

来源:https ://rollout.io/blog/adjusting-linux-kernel-parameters-with-docker-compose/

我意识到这应该是适当答案中的评论但是嘿新手没有代表添加评论你必须跳进去并“回答”

于 2021-01-01T12:47:34.940 回答