Docker-禁用userland代理

本文探讨了Docker中userland-proxy的作用及其对性能和安全的影响。Docker守护进程通常使用userland-proxy进行端口映射,但DNAT模式提供了更好的性能和安全性。建议在支持DNAT的系统上禁用userland-proxy以减少资源消耗。禁用方法是在启动dockerd时添加--userland-proxy=false。不过,旧版内核或特定网络配置可能需要userland-proxy服务。关闭此功能可能导致某些场景下的功能缺失或影响系统性能。

禁用userland代理

 

描述

当容器端口需要被映射时,docker守护进程都会启动用于端口转发的userland-proxy方式。 如果使用了DNAT方式,该功能可以被禁用。

解释

Docker引擎提供了两种机制将主机端口转发到容器,DNAT和userland-proxy。 在大多数情况下,DNAT模式是首选,因为它提高了性能,并使用本地Linux iptables功能而需要附加组件。如果DNAT可用,则应在启动时禁用userland-proxy以减少安全风险。

审计方法

ps -ef | grep dockerd。

结果

确保--userland-proxy参数设置为false。

修复

行Docker守护进程如下:dockerd --userland-proxy = false。

影响

某些旧版Linux内核的系统可能无法支持DNAT,因此需要userland-prox服务。 此外,某些网络设置可能会因删除userland-prox而受到影响。



首先介绍userland-proxy一直以来的作用。众所周知,在Docker的桥接bridge网络模式下,Docker容器是通过宿主机上的NAT模式,建立与宿主机之外世界的通信。然而在宿主机上,一般情况下,进程可以通过三种方式访问容器,分别为:<eth0IP>:<hostPort>, <containerIP>:<containerPort>,以及<0.0.0.0>:<hostPort>。实际上,最后一种方式的成功访问完全得益于userland-proxy,即Docker Daemon在启动一个Docker容器时,每次为容器在宿主机上映射一个端口,都会启动一个docker-proxy进程,实现宿主机上0.0.0.0地址上对容器的访问代理。

当时引入userland-proxy时,也许是因为设计者意识到了0.0.0.0地址对容器访问上的功能缺陷。然而,在docker-proxy加入Docker之后相当长的一段时间内。Docker爱好者普遍感受到,很多场景下,docker-proxy并非必需,甚至会带来一些其他的弊端。

影响较大的场景主要有两种。

第一,单个容器需要和宿主机有多个端口的映射。此场景下,若容器需要映射1000个端口甚至更多,那么宿主机上就会创建1000个甚至更多的docker-proxy进程。据不完全测试,每一个docker-proxy占用的内存是4-10MB不等。如此一来,直接消耗至少4-10GB内存,以及至少1000个进程,无论是从系统内存,还是从系统CPU资源来分析,这都会是很大的负担。

第二,众多容器同时存在于宿主机的情况,单个容器映射端口极少。这种场景下,关于宿主机资源的消耗并没有如第一种场景下那样暴力,而且一种较为慢性的方式侵噬资源。

如今,Docker Daemon引入- -userland-proxy这个flag,将以上场景的控制权完全交给了用户,由用户决定是否开启,也为用户的场景的proxy代理提供了灵活性

相关链接

1.http://windsock.io/the-docker-proxy 2.https://github.com/docker/docker/issues/14856 3 https://github.com/docker/docker/issues/22741 4.https://docs.docker.com/engine/userguide/networking/default_network/binding/

 

sudo systemctl restart docker Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details. [root@192 ~]# systemctl status dockerdocker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) Active: failed (Result: exit-code) since 三 2025-03-19 14:28:02 CST; 13s ago Docs: http://docs.docker.com Process: 3554 ExecStart=/usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json $OPTIONS $DOCKER_STORAGE_OPTIONS $DOCKER_NETWORK_OPTIONS $ADD_REGISTRY $BLOCK_REGISTRY $INSECURE_REGISTRY $REGISTRIES (code=exited, status=1/FAILURE) Main PID: 3554 (code=exited, status=1/FAILURE) 3月 19 14:28:02 192.168.137.128 systemd[1]: Starting Docker Application Container..... 3月 19 14:28:02 192.168.137.128 dockerd-current[3554]: unable to configure the Doc...l 3月 19 14:28:02 192.168.137.128 systemd[1]: docker.service: main process exited, ...RE 3月 19 14:28:02 192.168.137.128 systemd[1]: Failed to start Docker Application Co...e. 3月 19 14:28:02 192.168.137.128 systemd[1]: Unit docker.service entered failed state. 3月 19 14:28:02 192.168.137.128 systemd[1]: docker.service failed. Hint: Some lines were ellipsized, use -l to show in full. [root@192 ~]# sudo vim /etc/docker/daemon.json [root@192 ~]# sudo systemctl daemon-reload [root@192 ~]# sudo systemctl restart docker Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details. [root@192 ~]# docker -v
03-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值