Docker コンテナ内の net.core.somaxconn を変える

--net=host でコンテナを起動すれば、network namespace が分離されないので net.core.somaxconn の値はホスト側と一致する。

% cat /proc/sys/net/core/somaxconn
1024
% docker run --net=host ubuntu:16.04 cat /proc/sys/net/core/somaxconn
1024

けど普通に docker run すると、ホスト側の値にかかわらず、コンテナ内ではデフォルトの128になる。

% cat /proc/sys/net/core/somaxconn
1024
% docker run ubuntu:16.04 cat /proc/sys/net/core/somaxconn
128

で、コンテナ内でこの値を変えようとしても、デフォルトでは許可されていない。

% docker run -it ubuntu:16.04 bash
root@1704e07731c0:/# cat /proc/sys/net/core/somaxconn
128
root@1704e07731c0:/# echo 512 > /proc/sys/net/core/somaxconn
bash: /proc/sys/net/core/somaxconn: Read-only file system

これを回避する方法はいくつかあって、1つは --privileged で実行する方法。

% docker run --privileged -it ubuntu:16.04 bash
root@41d5397d065b:/# echo 512 > /proc/sys/net/core/somaxconn
root@41d5397d065b:/# cat /proc/sys/net/core/somaxconn
512
root@41d5397d065b:/# exit
% cat /proc/sys/net/core/somaxconn
1024

ホスト側とは別の network namespace で値を変えているだけなので、ホスト側の値には影響は無い。 ただ、これだと不要な権限も色々と渡ってしまうのでできれば避けたい。

そこで、必要なものだけ rw で bind mount して、そこに書き込むという方法がある。

% docker run --volume /proc/sys/net/core/somaxconn:/somaxconn -it ubuntu:16.04 bash
root@9bc22f86b0f3:/# cat /somaxconn
128
root@9bc22f86b0f3:/# cat /proc/sys/net/core/somaxconn
128
root@9bc22f86b0f3:/# echo 512 > /somaxconn
root@9bc22f86b0f3:/# cat /somaxconn
512
root@9bc22f86b0f3:/# cat /proc/sys/net/core/somaxconn
512
root@9bc22f86b0f3:/# exit

なお Docker 1.12.0 からは --sysctl というオプションがつくようなので、試してないけど 1.12.0 以降は docker run --sysctl net.core.somaxconn=512 でよさそう。 https://github.com/docker/docker/pull/19265