容器实战高手课
李程远
eBay 总监级工程师,云平台架构师
24647 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
容器实战高手课
15
15
1.0x
00:00/00:00
登录|注册

15 | 容器网络:我修改了/proc/sys/net下的参数,为什么在容器中不起效?

思考题
重点总结
解决问题
知识详解
问题再现
容器网络参数配置

该思维导图由 AI 生成,仅供参考

你好,我是程远。
从这一讲开始,我们进入到了容器网络这个模块。容器网络最明显的一个特征就是它有自己的 Network Namespace 了。你还记得,在我们这个课程的第一讲里,我们就提到过 Network Namespace 负责管理网络环境的隔离。
今天呢,我们更深入地讨论一下和 Network Namespace 相关的一个问题——容器中的网络参数。
和之前的思路一样,我们先来看一个问题。然后在解决问题的过程中,更深入地理解容器的网络参数配置。

问题再现

在容器中运行的应用程序,如果需要用到 tcp/ip 协议栈的话,常常需要修改一些网络参数(内核中网络协议栈的参数)。
很大一部分网络参数都在 /proc 文件系统下的/proc/sys/net/目录里。
修改这些参数主要有两种方法:一种方法是直接到 /proc 文件系统下的"/proc/sys/net/"目录里对参数做修改;还有一种方法是使用sysctl这个工具来修改。
在启动容器之前呢,根据我们的需要我们在宿主机上已经修改过了几个参数,也就是说这些参数的值已经不是内核里原来的缺省值了.
比如我们改了下面的几个参数:
# # The default value:
# cat /proc/sys/net/ipv4/tcp_congestion_control
cubic
# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
# cat /proc/sys/net/ipv4/tcp_keepalive_probes
9
# # To update the value:
# echo bbr > /proc/sys/net/ipv4/tcp_congestion_control
# echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
# echo 10 > /proc/sys/net/ipv4/tcp_keepalive_intvl
# echo 6 > /proc/sys/net/ipv4/tcp_keepalive_probes
#
# # Double check the value after update:
# cat /proc/sys/net/ipv4/tcp_congestion_control
bbr
# cat /proc/sys/net/ipv4/tcp_keepalive_time
600
# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
10
# cat /proc/sys/net/ipv4/tcp_keepalive_probes
6
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入讨论了在容器中修改/proc/sys/net下的参数为何不会生效的问题,并详细解释了Network Namespace的概念和操作。作者首先提出了一个问题,即在容器中运行的应用程序需要修改网络参数时,常常需要修改/proc/sys/net目录下的参数。通过实验发现容器中的参数值并不会继承宿主机Network Namespace里的值,而是继承了原系统的默认值。文章指出了容器中的/proc/sys目录是只读的,因为runC出于安全考虑将其做了read-only mount的处理。然后介绍了如何修改容器中Network Namespace的网络参数,包括使用"nsenter"工具和在容器启动时通过runC sysctl相关的接口进行配置。最后,提出了思考题,鼓励读者分享收获和疑问。 总的来说,本文通过实际问题出发,深入讨论了容器中网络参数配置的相关知识,包括参数继承问题和Network Namespace的概念和操作。读者可以从中了解到容器中网络参数配置的细节和原理,以及如何操作Network Namespace。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《容器实战高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(18)

  • 最新
  • 精选
  • 莫名
    # nsenter -t <pid> -n bash -c 'echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time' (root 用户) $ sudo nsenter -t <pid> -n sudo bash -c 'echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time' (非 root 用户) 其中,<pid> 表示容器 init 进程在宿主机上看到的 PID。

    作者回复: 对!

    2020-12-19
    2
    15
  • 谢哈哈
    宿主机的进入容器网络地址空间通过nsenter --target $(docker inspect -f {.State.Pid}) --net

    作者回复: 是的

    2020-12-19
    3
    7
  • aMaMiMoU
    老师您好,有几个问题能否帮忙解答下,谢谢 1.在/proc/sys/net 的诸多参数里,如何确认哪些是host level 哪些是容器level的呢? 2.对于host level的这些参数,在启动容器的时候通过sysctl能修改么?如果能修改,是不是相当于同时影响了同host里其他容器的运行时参数呢?

    作者回复: @AMaMiMou 很好的问题,对于/proc/sys/net下的参数,你在容器中看到的,基本都是network namespace下的。 对于容器启动的时候,runc只允许修改namesapce下的参数值,而不会修改host相关的值。 可以参看一下runc的sysctl validation的代码: https://github.com/opencontainers/runc/blob/ff819c7e9184c13b7c2607fe6c30ae19403a7aff/libcontainer/configs/validate/validator.go#L135

    2020-12-26
    2
    4
  • Geek_c2089d
    老师,咨询一个问题,就是我有一个容器里面有两个服务,映射出8000和9000的端口,在容器内会出现8000端口的服务访问宿主机ip:9000的端口不通,但是我service iptables stop ; seriver docker stop ; server docker start ; 就可以访问了。一旦reboot就不行了。请问是怎么样的问题

    作者回复: > service iptables stop 看上去应该是 iptables stop 后把原来的iptables rules flush了,就可以工作了。 你可以查看一下具体是那条iptables规则阻止了访问。

    2021-01-22
    3
  • Helios
    这些问题文档上都没写,还是老师功力高,场景多。 请教个问题,对于proc文件系统的其他目录容器怎么隔离的呢,比如在容器里面free命令看到的是宿主机的内存。

    作者回复: /proc下的内容大部分是没有隔离的,就想你说的/proc/meminfo, /proc/stat 在容器中看到的都和宿主机上的是一样的。 其他有一些因为namespace不同而不同的/proc的内容, 比如 /proc/<pid>/, 容器下只能看到自己pid namespace里的进程pid。 /proc/mounts的内容和mount namespace相关。 还有IPC namesapce相关的一些/proc下的参数,等等。

    2020-12-22
    3
  • 🐭
    既然nsenter与docker exec 原理一样,为啥nsenter修改proc/sys/net不会报错无权限呢

    作者回复: docker exec 同时进入了容器的pid/mnt/net namespace, 而 nsenter 修改参数的时候,只是进入了容器的net namespace.

    2021-08-03
    2
  • 乔纳森
    我们是在 initContainers 中 执行 如下来修改容器内的内核参数的,需要privileged: true mount -o remount rw /proc/sys sysctl -w net.core.somaxconn=65535

    作者回复: 嗯,如果container有privileged的权限,那么在容器中几乎和host有同等权限了。

    2021-07-04
    1
  • Demon.Lee
    老师,为啥隔离的这些网络参数不和 /sys/fs/cgroup/net_cls,net_prio,cpu,pid 等一样,统一放在/sys/fs/cgroup/下面,而是跟宿主机共用一套 ?

    作者回复: 一个是namespace, 主要是资源隔离 另外一个是cgroup,主要是资源的划分。

    2021-07-02
    1
  • 程序员老王
    网卡是通过端口号来区分栈数据吧,命名空间在这里隔离是网络参数配置吗?还是网卡

    作者回复: @王传义 你这里说的“端口”是指tcp/udp层的端口号吗?

    2020-12-18
    2
    1
  • 小Y
    来到网络的章节基本不太懂,得多听几遍,多补充补充了😆

    编辑回复: 知道了盲区也是好事,可以去补一补。一定可以的~

    2022-02-28
收起评论
显示
设置
留言
18
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部