tcp_keepalive_time in docker container
Asked Answered
C

2

16

I have a docker host that has set a net.ipv4.tcp_keepalive_time kernel parameter to 600. But when a container runs, it uses a different value:

$ 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

Why is this and how can I change this value without having to pass --sysctl option?

The reason I cannot pass --sysctl in my case is that this host is a docker swarm container and this option is currently unsupported in swarm.

But shouldn't containers just take these kernel parameters from the host? I already restarted the docker service (and its containers).

edit: some extra host info:

$ uname -r
4.15.0-38-generic
$ docker --version
Docker version 18.06.1-ce, build e68fc7a
Clientele answered 6/2, 2019 at 11:17 Comment(1)
net.* sysctls are now supported in docker swarmVandavandal
C
22

That is how network namespaces (which are the Linux facility used by Docker) work.

But shouldn't containers just take these kernel params from the host?

No. When the network namespace is created (in your case - when the Docker container is started), it does not inherit most of the network kernel parameters from the initial ("host" in your terms) network namespace, instead, these parameters are set to defaults which are defined for the kernel at the compile-time.

Also, changing the value of particular network parameter in particular network namespace (including the initial one) does not change this parameter in other network namespaces, so, changing the value of the "host's" net.ipv4.tcp_keepalive_time parameter does not affect any container (already running or subsequently launched).

how can I change this value without having to pass --sysctl option?

Taking into account the explanation above, the only way to change this kernel parameter for your container from kernel's default is to modify this parameter from the container's network namespace. This is what Docker does during the container startup when the --sysctl option is provided.

If Swarm does not support launching the container with this option, I afraid that the only way you have is to modify this parameter from the container's entrypoint, which is not possible unless you run your container as --privileged. This, obviously, is a bad decision, as it essentially is a security vulnerability, allowing the container to affect the host system in numerous ways.

Chiu answered 7/2, 2019 at 0:3 Comment(2)
Can't yet vote you up, but thanks for the clear answer. In our case, we can workaround it by lowering the sqlalchemy recycle_pool to 600 seconds so it will recreate connections before they time out.Clientele
another workaround could be to (manually, outside swarm) run a privileged container in the swarm container network namespace and use it to tune the sysctls: $ docker run --rm --privileged --network container:<CONTAINER ID> alpine sysctl net.ipv4.tcp_keepalive_time = 600 not pretty, but limits the exposure to the privileged containerVacillating
M
-1

use ADD command in Dockerfile

ADD local/path/tcp_keepalive_time /proc/sys/net/ipv4/tcp_keepalive_time
ADD local/path/tcp_keepalive_intvl /proc/sys/net/ipv4/tcp_keepalive_intvl
ADD local/path/tcp_keepalive_time /proc/sys/net/ipv4/tcp_keepalive_probes
Moresque answered 17/10, 2023 at 15:6 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.