その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

Linux Kernel 4.12以前であればhostマシンのsysctlの値がDocker container環境に引き継がれるかどうか検証した

Docker - IPVS connection timeout issue

これを読んでいたところ

From Linux kernel 4.13 onwards, sysctl default values can be modified per container basis. Container will not inherit changes from the host sysctl modified values.

とあったので,逆にhostマシンのLinux Kernelが4.12以前であればhostマシンのsysctlの値がDocker containerに引き継がれるのか? と思い検証してみました.

TL;DR

  • (手元の環境で試してみた限り) 引き継がれなかった
  • 変なことを考えず,おとなしくdocker run--sysctl オプションを使おう!!
    • Amazon ECSは早くsysctlのサポートしてくれ!!!!!

hostマシン環境

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
$ docker -v
Docker version 18.06.1-ce, build e68fc7a

コンテナ環境

https://hub.docker.com/_/ubuntu/

ubuntu:bionicを使用.

Kernel 4.13.16でやってみる

$ uname -a
Linux moznion 4.13.16-041316-generic #201711240901 SMP Fri Nov 24 09:02:42 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ sysctl -n net.ipv4.tcp_keepalive_time # <= host
7200
$ sudo docker run ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
7200
$ sudo sysctl -w 'net.ipv4.tcp_keepalive_time=600' # <= ここでhostのtcp_keepalive_timeをいじってみる
net.ipv4.tcp_keepalive_time = 600
$ sysctl -n net.ipv4.tcp_keepalive_time # <= host
600
$ sudo docker run ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
7200

引き継がれてないですね.

Kernel 4.12.14でやってみる

$ uname -a
Linux moznion 4.12.14-041214-generic #201709200843 SMP Wed Sep 20 12:46:23 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ sysctl -n net.ipv4.tcp_keepalive_time # <= host
7200
$ sudo docker run ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
7200
$ sudo sysctl -w 'net.ipv4.tcp_keepalive_time=600' # <= ここでhostのtcp_keepalive_timeをいじってみる
net.ipv4.tcp_keepalive_time = 600
$ sysctl -n net.ipv4.tcp_keepalive_time # <= host
600
$ sudo docker run ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
7200

あれ,引き継がれないですね.

もちろんsysctlオプションを食わせながらdocker runすれば反映される

$ sudo docker run --sysctl 'net.ipv4.tcp_keepalive_time=600' ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
600

所感

Kernel 4.12.0とKernel 4.10.17でも試してみましたがhostマシン側のsysctlがcontainerに引き継がれているようには見えませんでした.なんか間違ってるんですかね? それとも引き継がれないのが普通?
とはいえ新しいKernel上ではhostのsysctlは引き継がれないし,やはりdocker runの--sysctlオプションで渡すのが良いでしょう.しかしAmazon ECSではsysctlオプションが対応されておらず*1……嗚呼