Обновить сеть.ядро.somaxcomm (или любое свойство sysctl) для контейнеров docker

Я пытаюсь изменить net.core.somaxconn для контейнера docker, чтобы иметь большую очередь запросов для моего веб-приложения.

в ОС, вне 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 (в надежде, что докер прочитает этот файл при запуске контейнера)
  • перезагрузки контейнеры sudo docker stop и sudo docker run опять
  • перезагрузки все настройки sudo service docker restart

но внутри контейнера cat /proc/sys/net/core/somaxconn всегда показывает 128.

я запускаю docker 1.2 (поэтому я не могу по умолчанию изменить /proc атрибуты внутри контейнера) и в упругой бобовый стебель (без --privileged режим, который позволил бы мне изменить /proc).

как я могу распространить изменения sysctl на docker?

6 ответов


просто выяснил, как это решить, теперь 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"
  }]
}

обратите внимание что я дублировать этот ответ из другого потока.


subsys "net / core" - это зарегистрирован на сетевое пространство имен. И начальное значение для somaxconn установлено в 128.

когда вы делаете sysctl на хост-системе, он устанавливает основные параметры для его сетевое пространство имен, которое принадлежит init. (в основном это пространство имен по умолчанию). Это не влияет на другие сетевые пространства имен.

при запуске контейнера Docker виртуальный сетевой интерфейс (отображается как vethXXX на хосте) этого контейнера прилагается к собственному пространству имен, который по-прежнему имеет начальное значение somaxconn 128. Так что, технически, вы не можете propogate это значение в контейнер, так как два сетевых пространства имен не разделяют его.

есть, однако, два способа настроить это значение, в дополнение к запуску контейнера в привилегированном режиме.

  1. используйте "--net host " при запуске контейнера, таким образом, он использует сетевой интерфейс хоста и, следовательно, разделяет то же сетевое пространство имен.

  2. вы можете подключить файловую систему proc как чтение-запись с помощью поддержки сопоставления томов Docker. фокус в том, чтобы сопоставить его с Томом, не названным "/proc", так как Docker будет remount/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.АРМ.в JSON. Также он должен работать для других настраиваемых параметров в /proc, которые относятся к пространству имен. Но это, скорее всего, оплошность со стороны Докера, поэтому они могут добавить дополнительную проверку на сопоставление томов, и тогда этот трюк не сработает.


docker 1.12 добавить поддержку для установки sysctls с --sysctl.

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


Я нашел решение:

{
    "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'

Update: этот ответ устарел, поскольку Docker теперь поддерживает !

решение, которое я использую для моего контейнера OpenVPN, - это войти в пространство имен контейнера с полными возможностями, используя nsenter, remounting /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'

таким образом, контейнеру не нужно запускать привилегированные классы.


в docker 3.1 поддерживается указание sysctl. Примечание
sysctl-вызовов:
    - чистый.ядро.somaxconn=1024

мой пример docker-compose file

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"