首页 > 解决方案 > docker 容器中的 tcp_keepalive_time

问题描述

我有一个将net.ipv4.tcp_keepalive_time内核参数设置为 600 的 docker 主机。但是当容器运行时,它使用不同的值:

$ 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是这个主机是一个 docker swarm 容器,这个选项目前在 swarm 中不受支持

但是容器不应该只从主机获取这些内核参数吗?我已经重新启动了 docker 服务(及其容器)。

编辑:一些额外的主机信息:

$ uname -r
4.15.0-38-generic
$ docker --version
Docker version 18.06.1-ce, build e68fc7a

标签: dockerdocker-swarm

解决方案


这就是网络命名空间(Docker 使用的 Linux 工具)的工作方式。

但是容器不应该只从主机获取这些内核参数吗?

不。创建网络命名空间时(在您的情况下 - 当启动 Docker 容器时),它不会从初始(您的术语中的“主机”)网络命名空间继承大多数网络内核参数,而是这些参数是设置为在编译时为内核定义的默认值。

此外,更改特定网络命名空间(包括初始)中特定网络参数的值不会更改其他网络命名空间中的此参数,因此,更改“host's”net.ipv4.tcp_keepalive_time参数的值不会影响任何容器(已经运行或随后推出)。

如何在不通过 --sysctl 选项的情况下更改此值?

考虑到上面的解释,改变你的容器的这个内核参数从内核的默认值的唯一方法是从容器的网络命名空间修改这个参数。--sysctl当提供该选项时,这是 Docker 在容器启动期间所做的事情。

如果 Swarm 不支持使用此选项启动容器,恐怕您唯一的方法是从容器的入口点修改此参数,除非您将容器运行为--privileged. 显然,这是一个糟糕的决定,因为它本质上是一个安全漏洞,允许容器以多种方式影响主机系统。


推荐阅读