当前位置: 首页 > 面试题库 >

为什么Docker运行这么多进程来将端口映射到我的应用程序?

包丁雨
2023-03-14
问题内容

我有一个在容器中运行的应用程序,该容器要求将一系列端口映射到该容器。

docker run -p 2000-3000:2000-3000 myapp

当我运行此docker命令时,我的开发vm陷入停顿。

然后查看进程,docker-proxy每个端口都有运行

$ ps -ef 
...
root     19796  7835  0 03:31 ?        00:00:00 docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 4000 -container-ip 172.17.0.4 -container-port 3000
root     19804  7835  0 03:31 ?        00:00:00 docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3999 -container-ip 172.17.0.4 -container-port 2999
root     19812  7835  0 03:31 ?        00:00:00 docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3998 -container-ip 172.17.0.4 -container-port 2998
...

$ ps -ef | grep -c docker-proxy
1003

他们都是docker守护程序的子代

root@default-docker:~# pstree -p
init(1)-+-VBoxService(1251)
        |-acpid(1277)
        |-crond(1235)
        |-docker(7835)-+-docker-containe(7841)-+-docker-containe(8031)---gitlab-ci-multi(8048)
        |              |                       |-docker-containe(9678)---mysqld(9693)
        |              |                       `-docker-containe(20577)---registry(20591)
        |              |-exe(19796)
        |              |-exe(19804)
        |              |-exe(19812)

每个进程使用的专用存储器块(Pss/proc/$pid/smaps

$ for pid in $(pgrep exe); do printf "pid:%5s mem:%5s\n" $pid $(awk '/^Pss:/{t=t+$2}END{print t}' /proc/$pid/smaps); done
...
pid:28534 mem: 4011
pid:28543 mem: 3817
pid:28552 mem: 4001

每个端口上都有DNAT规则,这是我期望在具有专用网络的Linux主机上完成此操作的方式。

root@default-docker:~# iptables -t nat -vnL DOCKER
Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
...
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:4000 to:172.17.0.4:3000
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:3999 to:172.17.0.4:2999
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:3998 to:172.17.0.4:2998
...

Docker为什么要为每个端口启动一个进程?
为什么每个进程需要4-6MB的内存?
为什么Docker完全使用用户空间进程


问题答案:

为什么Docker完全使用用户空间进程?

Nigel Brown在docker-proxy上写了一篇详细的文章,解释了如何以及为什么。

docker-proxy,然后,是一个“捕获所有”用于允许容器端口转发到主机多克尔方法。但是,通常认为这docker- proxy是对上述问题的不佳解决方案,并且当暴露大量容器端口时,它将消耗大量内存。先前曾尝试删除对的依赖docker-proxy,但这与RHEL
6.x和CentOS 6.x中老化的内核的限制相抵触,Docker项目感到必须支持这些限制。因此,在docker- proxy当前版本1.5之前的所有Docker版本中,这些
仍然是Docker经验的主要组成部分。在我撰写本文时,即将发布1.6版,并且已经采取了一些措施来删除对docker- proxy,我将在另一篇文章中介绍。

Docker现在包括一个守护程序运行时选项,以使用禁用用户态代理--userland- proxy=false。这是在v1.7中引入的。

禁用userland代理时,似乎存在一些边缘案例错误。还有IPV6问题

GitHub上存在一个开放的问题,默认情况下禁用userland代理(Docker不再支持RHEL6)。

Docker为什么要为每个端口启动一个进程?

除了以这种方式实现之外,似乎没有其他原因。一个进程应该能够处理容器的所有端口映射

为什么每个进程需要4-6MB的内存?


代理实现和包装看起来干净和内置转到功能使用所以这可能只是转到最初的垃圾收集范围,允许它增长到5MB〜。

编辑 :内存使用已在Docker
1.12中得到了改进。每个端口仍然有一个进程,但是每个进程现在仅使用约750k的私有内存空间。



 类似资料:
  • 我在运行钢筋应用程序时遇到了类似的问题 基本上,我想从以下位置运行演示代码:https://github.com/hukl/fancyapi 当我在根目录中时,我会: ERL如何找到fancyapi代码?

  • 我想从节点内部获取映射端口。js应用程序。 前任。 : : 我想从node获取端口。js应用。 有什么想法吗?

  • 我已经从Dockerfile中构建了一个名为Centos+ssh的基本映像。在Centos+ssh的Dockerfile中,我使用CMD来运行ssh服务。 然后我想构建一个映像,运行其他名为rabbitmq的服务,DockerFile: 若要启动rabbitmq容器,请运行: 但是ssh服务不工作,它感测RabbitMQ的Dockerfile CMD覆盖Centos的CMD。 CMD如何在dock

  • 问题内容: 我想更改运行我的应用程序的主机和端口。我设置并进入,但是命令仍然在默认值上运行。如何更改flask命令使用的主机和端口? 问题答案: 该命令与方法分开。它看不到应用程序或其配置。要更改主机和端口,请将它们作为选项传递给命令。 通过以获取完整的选项列表。 设置配置也不会影响该命令,因为该命令看不到应用程序的配置。 切勿将开发服务器暴露在外部(例如绑定到)。使用生产WSGI服务器,例如uW

  • 我对一些代码进行了分析,并对花费了这么多时间感到惊讶。 但我发现这快了大约5倍: 下面是Math.min的代码以供参考: 注意:我的用例是对称的,上面的情况都适用于max,而不是min。 我在我的应用程序中添加了以下代码,以尝试获得更好的数据: 这将打印每个新触摸事件的运行比率。当我在屏幕上旋转手指时,首先记录的比率是或或。这让我觉得这个测试不是很准确地测量时间。随着收集到更多的数据,比率往往在和