[头脑风暴] 解读Docker Bridge网络模型

简介: bridge网桥内容器通过容器IP相互访问,外部网络隔离docker run -p 参数通过端口映射,让bridge网桥外网络可以访问容器一般情况下,对外提供web服务的docker镜像会在0.0.0.0 地址上监听请

背景

这几天在研究Kubernetes, 遇到一个有意思的nodejs镜像:luksa/kubia


    # 不带端口映射启动容器docker  run  -it -d   luksa/kubia# 连接到默认的Bridge网桥,容器IP是 172.17.0.2


    之后,在宿主机使用容器IP和8080 端口可访问该容器nodejs服务


    ab5a48e7a0b75c04d14020098d44873a.png


    对此我有几个疑问,这几个疑问在我看来有点与我之前对docker 网络的认知相冲突。


    Q1. 不是说如果容器没有端口映射,容器内外隔离吗,怎么在宿主机使用容器IP还可以访问?

    Q2.  使用容器IP:8080可以访问nodejs服务,这个8080从哪里来?


    头脑风暴


    首先排除一些同事说法:这个容器是以host网络模型连到宿主机,所以可以在宿主机通过容器IP访问。这个新建容器肯定还是连接到默认的bridge网桥上。


    • All containers without a --network specified, are attached to the default bridge network.
    • In terms of Docker, a bridge network uses a software bridge which allows containers connected to the same bridge network to communicate, while providing isolation from containers which are not connected to that bridge network.


    对于Q1,我有个误区:没有端口映射,容器内外网络隔离,宿主机是无法访问容器的。


    A:  实际上,对于加入同一bridge网桥上的容器,网桥内外网络确实是隔离的,网桥上的容器都可以相互连接。


    而我们的宿主机也在这个默认的bridge网桥设备上,其IP地址是网桥设备的网关(172.17.0.1)。


    9d77a326ba45b0532eb4a713c5e4b2ec.png


    Q3.那端口映射到底起什么作用呢?


    A:网桥模型确保了网桥内容器可相互访问,但除此网桥之外的网络均不能访问容器, 这也正是bridge网络隔离的效果。


    端口映射-p表示容器绑定宿主机的网卡端口来实现转发访问,绑定的网卡决定了你对外暴露的程度。

    1. 绑定宿主机的回环地址127.0.0.1


      docker run -it  -d  -p 127.0.0.1:8080:8080 luksa/kubia


      那么在宿主机内只能使用127.0.0.1:8080访问容器


      077d3b237a85f72a7b4caab0bebb41db.png


      1. 绑定宿主机的物理地址 10.201.80.126


        docker run -it  -d  -p 10.201.80.126:8080:8080 luksa/kubia


        那么可使用宿主机物理IP10.201.80.126:8080访问容器,这样局域网机器就能访问到容器了


        733e679c4bf5ce8f94be347ce1d482bb.png


        3. 不写IP,这样会绑定到0.0.0.0,也就是宿主机所有的网卡。


          docker run -it  -d  -p 8080:8080 luksa/kubia


          很显然,宿主机内回环地址和物理地址均可以访问该容器了。


          再回到上面的Q2问题,通过容器IP:8080访问容器,8080是哪里来的?


          8080是容器内nodejs进程的监听端口,我们在构建镜像时本就无所谓使用expose指令


          The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published.


          所以在docekr ps时候,并不会在PORTS列显示任何内容,但是通过容器IP可直接连通容器内进程监听端口。


          为啥访问容器IP:8080 就可以访问容器内nodejs提供的服务?


          这是因为容器镜像在构建的时候,一般在0.0.0.0地址上监听请求,这意味着程序在所有地址的8080端口上监听请求。


          这样就延伸出一个有趣的现象,让我们进入容器内部:


            docker exec -it 3cc9f428fc25 bash curl 127.0.0.1:8080 curl 127.0.0.2:8080 curl 127.0.1:8080 curl 172.17.0.2:8080 curl 172.17.2:8080


            9cea80d2db5c5102260be7850eeaf3f5.png


            几个看起来错误的IP竟然也可以访问nodejs服务, 这正是nodejs在http://0.0.0.0:8080地址监听请求的结果。


            c16245e2a99d69373888f3b7d8d49e55.png


              # 截取自该镜像构建源码:https://github.com/luksa/kubia-qps/blob/master/kubia-qps/app.jsvar www = http.createServer(handler);www.listen(8080);
              # nodejs: server.listen([port[, host[, backlog]]][, callback]) apiIf host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.


              猜想+ 验证+ 源码支持,回应了一开始的几个疑问,对容器Bridge的网络认知进一步加深。


              总结输出


              1. bridge网桥内容器通过容器IP相互访问,外部网络隔离


              1. docker run -p 参数通过端口映射,让bridge网桥外网络可以访问容器


              1. 一般情况下,对外提供web服务的docker镜像会在0.0.0.0 地址上监听请求
              相关文章
              基于Reactor模型的高性能网络库之地址篇
              这段代码定义了一个 InetAddress 类,是 C++ 网络编程中用于封装 IPv4 地址和端口的常见做法。该类的主要作用是方便地表示和操作一个网络地址(IP + 端口)
              469 58
              |
              网络协议 算法 Java
              基于Reactor模型的高性能网络库之Tcpserver组件-上层调度器
              TcpServer 是一个用于管理 TCP 连接的类,包含成员变量如事件循环(EventLoop)、连接池(ConnectionMap)和回调函数等。其主要功能包括监听新连接、设置线程池、启动服务器及处理连接事件。通过 Acceptor 接收新连接,并使用轮询算法将连接分配给子事件循环(subloop)进行读写操作。调用链从 start() 开始,经由线程池启动和 Acceptor 监听,最终由 TcpConnection 管理具体连接的事件处理。
              421 2
              基于Reactor模型的高性能网络库之Tcpconnection组件
              TcpConnection 由 subLoop 管理 connfd,负责处理具体连接。它封装了连接套接字,通过 Channel 监听可读、可写、关闭、错误等
              355 1
              |
              JSON 监控 网络协议
              干货分享“对接的 API 总是不稳定,网络分层模型” 看电商 API 故障的本质
              本文从 OSI 七层网络模型出发,深入剖析电商 API 不稳定的根本原因,涵盖物理层到应用层的典型故障与解决方案,结合阿里、京东等大厂架构,详解如何构建高稳定性的电商 API 通信体系。
              |
              域名解析 网络协议 安全
              计算机网络TCP/IP四层模型
              本文介绍了TCP/IP模型的四层结构及其与OSI模型的对比。网络接口层负责物理网络接口,处理MAC地址和帧传输;网络层管理IP地址和路由选择,确保数据包准确送达;传输层提供端到端通信,支持可靠(TCP)或不可靠(UDP)传输;应用层直接面向用户,提供如HTTP、FTP等服务。此外,还详细描述了数据封装与解封装过程,以及两模型在层次划分上的差异。
              2593 13
              |
              网络协议 中间件 网络安全
              计算机网络OSI七层模型
              OSI模型分为七层,各层功能明确:物理层传输比特流,数据链路层负责帧传输,网络层处理数据包路由,传输层确保端到端可靠传输,会话层管理会话,表示层负责数据格式转换与加密,应用层提供网络服务。数据在传输中经过封装与解封装过程。OSI模型优点包括标准化、模块化和互操作性,但也存在复杂性高、效率较低及实用性不足的问题,在实际中TCP/IP模型更常用。
              1868 10
              |
              机器学习/深度学习 移动开发 测试技术
              RT-DETR改进策略【模型轻量化】| 替换骨干网络为MoblieNetV2,含模型详解和完整配置步骤
              RT-DETR改进策略【模型轻量化】| 替换骨干网络为MoblieNetV2,含模型详解和完整配置步骤
              802 1
              RT-DETR改进策略【模型轻量化】| 替换骨干网络为MoblieNetV2,含模型详解和完整配置步骤
              基于Reactor模型的高性能网络库之Poller(EpollPoller)组件
              封装底层 I/O 多路复用机制(如 epoll)的抽象类 Poller,提供统一接口支持多种实现。Poller 是一个抽象基类,定义了 Channel 管理、事件收集等核心功能,并与 EventLoop 绑定。其子类 EPollPoller 实现了基于 epoll 的具体操作,包括事件等待、Channel 更新和删除等。通过工厂方法可创建默认的 Poller 实例,实现多态调用。
              542 60
              基于Reactor模型的高性能网络库之Channel组件篇
              Channel 是事件通道,它绑定某个文件描述符 fd,注册感兴趣的事件(如读/写),并在事件发生时分发给对应的回调函数。
              574 60
              |
              安全 调度
              基于Reactor模型的高性能网络库之核心调度器:EventLoop组件
              它负责:监听事件(如 I/O 可读写、定时器)、分发事件、执行回调、管理事件源 Channel 等。
              555 57