docker - 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
解决方案
这就是网络命名空间(Docker 使用的 Linux 工具)的工作方式。
但是容器不应该只从主机获取这些内核参数吗?
不。创建网络命名空间时(在您的情况下 - 当启动 Docker 容器时),它不会从初始(您的术语中的“主机”)网络命名空间继承大多数网络内核参数,而是这些参数是设置为在编译时为内核定义的默认值。
此外,更改特定网络命名空间(包括初始)中特定网络参数的值不会更改其他网络命名空间中的此参数,因此,更改“host's”net.ipv4.tcp_keepalive_time
参数的值不会影响任何容器(已经运行或随后推出)。
如何在不通过 --sysctl 选项的情况下更改此值?
考虑到上面的解释,改变你的容器的这个内核参数从内核的默认值的唯一方法是从容器的网络命名空间修改这个参数。--sysctl
当提供该选项时,这是 Docker 在容器启动期间所做的事情。
如果 Swarm 不支持使用此选项启动容器,恐怕您唯一的方法是从容器的入口点修改此参数,除非您将容器运行为--privileged
. 显然,这是一个糟糕的决定,因为它本质上是一个安全漏洞,允许容器以多种方式影响主机系统。
推荐阅读
- c - gcc "–Werror: No such file" 指的是目标还是 Werror 用法?
- swift - 如何读写 liter() 类型的 HKUnit 数据?
- c# - 球体在没有重力的情况下减速
- java - 从 exiftool 读取二进制图片数据?
- kotlin - Kotlin,杰克逊:无法在主构造函数中注释 @JsonCreator
- r - 将来自 2 个不同图形的边序列合并为一个图形,R
- pagination - Angular 6 - 使用 HttpParams + 分页的动态搜索
- string - 类型转换错误
- svg - 转换 SVG 时的 ImageMagick 视图框
- matlab - 了解图像处理中的特征提取和特征向量?