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

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

В ОС, вне докеров, я сначала модифицирую свойство успешно:

$ 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

Но тогда я не знаю, как распространять это изменение на докер. Я пробовал:

  • Также редактирование /etc/sysctl.conf (в надежде, что докер выполнит чтение этого файла при запуске контейнера)
  • Перезапуск контейнеров sudo docker stop и sudo docker run снова
  • Перезапуск всей службы докеров на sudo service docker restart

Но внутри контейнера cat /proc/sys/net/core/somaxconn всегда отображается 128.

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

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

Ответы

Ответ 1

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

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

Ответ 2

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

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

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

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

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

  • вы можете смонтировать файловую систему proc как чтение и запись с использованием поддержки точного отображения Docker. трюк состоит в том, чтобы сопоставить его с томом NOT с именем "/proc", поскольку Docker будет remount/proc/sys, среди прочих, как только для чтения для не- привилегированные контейнеры. Это требует, чтобы хост монтировал /proc как rw, что имеет место в большинстве систем.

    docker run -it --rm -v /proc:/writable-proc ubuntu:14.04 /bin/bash
    [email protected]:/# echo 1024 > /writable-proc/sys/net/core/somaxconn
    [email protected]:/# sysctl net.core.somaxconn
    net.core.somaxconn = 1024
    

Метод 2 должен работать на эластичном бобовом стебле через поддержку отображения тома в Dockerrun.aws.json. Также он должен работать для других настраиваемых параметров в /proc для пространства имен. Но, скорее всего, это надзор над частью Docker, поэтому они могут добавить дополнительную проверку на отображение томов, и этот трюк не будет работать тогда.

Ответ 3

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

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

подробнее здесь:/opt/elasticbeanstalk/hooks/appdeploy/pre/04run.sh

Update:

Добавить файл .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'

Ответ 5

Обновление: этот ответ устарел, поскольку 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'

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

Ответ 6

В docker 3.1 есть поддержка для указания sysctl. обратите внимание на :
параметров ядра           - net.core.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"