У меня есть узел докера, который установил для параметра ядра net.ipv4.tcp_keepalive_time значение 600. Но когда контейнер запускается, он использует другое значение:
$ sysctl net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_time = 600
$ docker run --rm ubuntu:latest sysctl net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_time = 7200
Почему это так и как я могу изменить это значение, не передавая опцию --sysctl?
Причина, по которой я не могу передать --sysctl в моем случае, заключается в том, что этот хост является контейнером роя докеров, и эта опция в настоящее время не поддерживается в рое.
Но разве контейнеры не должны просто брать эти параметры ядра с хоста? Я уже перезапустил службу докеров (и ее контейнеры).
редактировать: дополнительная информация о хосте:
$ uname -r
4.15.0-38-generic
$ docker --version
Docker version 18.06.1-ce, build e68fc7a


Вот как работают сетевые пространства имен (которые являются средством Linux, используемым Docker).
But shouldn't containers just take these kernel params from the host?
Нет. При создании сетевого пространства имен (в вашем случае — при запуске Docker-контейнера) оно не наследует большинство параметров сетевого ядра от исходного («хост» в вашем понимании) сетевого пространства имен, вместо этого эти параметры установить по умолчанию, которые являются определено для ядра во время компиляции.
Кроме того, изменение значения того или иного сетевого параметра в конкретном сетевом пространстве имен (включая начальное) не меняет этот параметр в других сетевых пространствах имен, поэтому изменение значения параметра net.ipv4.tcp_keepalive_time «узла» не влияет ни на один контейнер (уже запущенный или запущенный). впоследствии запущен).
how can I change this value without having to pass --sysctl option?
Принимая во внимание объяснение выше, единственный способ изменить этот параметр ядра для вашего контейнера по умолчанию — это изменить этот параметр из сетевого пространства имен контейнера. Это то, что Docker делает во время запуска контейнера, когда предоставляется опция --sysctl.
Если Swarm не поддерживает запуск контейнера с этой опцией, я боюсь, что единственный доступный вам способ — изменить этот параметр из точки входа контейнера, что невозможно, если вы не запустите свой контейнер как --privileged. Это, очевидно, плохое решение, так как по сути является уязвимостью безопасности, позволяющей контейнеру влиять на хост-систему множеством способов.
Пока не могу проголосовать за вас, но спасибо за четкий ответ. В нашем случае мы можем обойти это, уменьшив sqlalchemy recycle_pool до 600 секунд, чтобы он воссоздал соединения до истечения времени ожидания.
другим обходным путем может быть (вручную, вне роя) запуск привилегированного контейнера в пространстве имен сети контейнеров роя и использование его для настройки sysctls: $ docker run --rm --privileged --network container:<CONTAINER ID> alpine sysctl net.ipv4.tcp_keepalive_time = 600 некрасиво, но ограничивает доступ к привилегированному контейнеру
net.* sysctls теперь поддерживаются в Docker Swarm