我对 Docker 网络模型的理解

简介: 单机容器内的通信是通过 docker 自带的网桥连接互通的,如果是集群,那么做这些单机网络模型就行不通了,因为集群必然会将一个服务的多个任务需要分布到不同的机器上进行部署,因为如果把所有的任务都分配到一台机器部署了,这台服务器有故障,就会导致这个服务不能正常运行了,而且一个集群内,不同主机之间的容器是怎么进行通信的呢,这里我们就涉及到 docker 网络模型。

单机容器内的通信是通过 docker 自带的网桥连接互通的,如果是集群,那么做这些单机网络模型就行不通了,因为集群必然会将一个服务的多个任务需要分布到不同的机器上进行部署,因为如果把所有的任务都分配到一台机器部署了,这台服务器有故障,就会导致这个服务不能正常运行了,而且一个集群内,不同主机之间的容器是怎么进行通信的呢,这里我们就涉及到 docker 网络模型。


容器的端口映射



还记得 docker 单机部署时的 run -p port:port 吗?这样做的目的是将 docker 容器内的端口映射到宿主机的端口上,以便能够通过外网 ip 访问到 docker 容器,这时我们就想,如果我们把所有容器的接口都暴露在宿主机中,通过访问外网 ip 来达到容器间通信,这不是万事大吉了吗?


但是在集群中如果这样暴露容器的端口,是有问题的,如果其中一个容器监听了宿主机 8080 端口,那么其他容器只能映射到其它端口了,因为端口并不能被共享,而且映射到宿主机的端口上,意味着容器也就暴露到外网了,如果要限制访问,那么就需要做一些安全配置。


单机网络模型



在介绍跨主机网络模型前,先来看看单机网络模型,在安装 docker 之后,docker 就会有 4 种网络模型,分别是:


  • host 模式,使用 --net=host 指定。
  • container 模式,使用 --net=container:NAME_or_ID 指定。
  • none 模式,使用 --net=none 指定。
  • bridge 模式,使用 --net=bridge 指定,默认设置。


但这四种网络模式都仅限于单机,其中 bridge 网络模型是 docker 的默认单机网络模型,它会将一个主机上的 docker 容器连接到一个虚拟网桥上,这个虚拟桥名称为 docker0,如下图:

640.png

brige


单机中的容器之间就可以通过 docker0 互相通信了,但是如果容器被分布在不同主机上,在没有跨主机网络模型前,只能通过映射端口的形式来通信了。


640.png

brige


如上图,net1 和 net2 都代表一台主机中的 docker0 网络,在同主机下的容器通过 docker0 网络互相通信,但是在不同主机中却又是隔离的。


跨主机网络模型



docker 1.9 版本之后,加入了一个默认的 overlay 的网络模型,它是 docker swarm 内置的跨主机通信方案,这是一个基于 vxlan 协议的网络实现,其作用是虚拟出一个子网,让处于不同主机的容器能透明地使用这个子网。所以跨主机的容器通信就变成了在同一个子网下的容器通信,看上去就像是同一主机下的 bridge 网络通信。


关于详细的 vxlan 协议原理,请移步:vxlan 协议原理简介


在 swarm 管理节点发布的服务想要监听端口,只需要在 像 docker run 一样在后缀加 -p 8080:8080 就可以了,如下:

$ docker service create --replicas 2 -p 8080:8080 --name hello \
chenghuizhang/helloword:0.0.2


但是跟 docker run 的 -p 又有本质的区别,实际上面那条命令并没有将 8080 端口直接暴露出去,而是将 8080 端口托付给 docker 的 overlay 网络模型中了。

640.png

docker ps


如上图可知,hello 服务的两个实例都在同一台服务器,都是 8080 端口,且没有映射到宿主机的端口上。


查看 docker 默认网络:

$ docker network ls

640.png

docker network


其中 ingress 为 docker 默认的 overlay 网络。

查看 ingress 网络信息:

$ docker network inspect ingress
[
    {
        "Name": "ingress",
        "Id": "x58u3pdo4z4qooriloi82l58k",
        "Created": "2018-08-15T12:54:22.080771222+08:00",
        "Scope": "swarm",
        "Driver": "overlay",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "10.255.0.0/16",
                    "Gateway": "10.255.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {
            "aef3e18d73b1db723aab0f162600a805aa7c50b5f51ec31d82d80b7eb3438c08": {
                "Name": "hello.1.tzk61cn6d0jjat2w4mu5x8bbf",
                "EndpointID": "40e9352419b4eccea739be3a6ab7e6327ee28a2220ce185750f028d74e2e05c8",
                "MacAddress": "02:42:0a:ff:00:05",
                "IPv4Address": "10.255.0.5/16",
                "IPv6Address": ""
            },
            "ef4a7f16567d3b51d0dff629b3b6252f50d06ec77a24b36dcd8d40b6ab9afc2d": {
                "Name": "hello.2.lcvumjyd19tymzankbjwita1w",
                "EndpointID": "d5b9a2e41654097337d6f22b139e1501b253e260d2ac3ac52e8eaf491a70340d",
                "MacAddress": "02:42:0a:ff:00:06",
                "IPv4Address": "10.255.0.6/16",
                "IPv6Address": ""
            },
            "ingress-sbox": {
                "Name": "ingress-endpoint",
                "EndpointID": "b610f32940e6066751a6c7b8d87f11874077f779a00d28855d8d3329d15783e9",
                "MacAddress": "02:42:0a:ff:00:03",
                "IPv4Address": "10.255.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.driver.overlay.vxlanid_list": "4096"
        },
        "Labels": {},
        "Peers": [
            {
                "Name": "VM_0_10_centos-8ef37c047944",
                "IP": "172.16.0.10"
            }
        ]
    }
]


由于 orverlay 网络模型是基于 vxlan 协议的网络实现,所以根据上面的网络信息可知,它是要在三层网络中虚拟出二层网络,即跨网段建立虚拟子网,也就是把 docker 要发送的信息先发送到虚拟子网地址 10.255.0.1,再由虚拟子网包装为宿主机的真实网网址  172.16.0.10,这样做的好处就是不会公开暴露容器的端口,让这些事情交给  overlay 网络驱动去做就行了,而且在同一台服务器,不会引起端口冲突,最重要的一点是可以实现集群容器间的负载均衡。


640.png


正如它的名字一样,在所有容器的上面一层,覆盖了一层网络,该网络可以使在集群中的容器像本地通信一样,所以 orverlay 网络模型也称之为覆盖网络。


构建自定义 overlay 网络集群



  • 新建网络驱动:
$ docker network create -d overlay mynet

-d 指定 mynet 网络驱动为 overlay 类型。


  • 创建 etcd 服务:
$ docker service create \
--name etcd \
--replicas 1 \
--network mynet \
-p 2379:2379


  • 创建 mysql 服务:
$ docker service create \
--name mysql-galera \
--replicas 3 \
--network mynet \
-p 3306:3306


  • 创建 hello 应用服务:
$ docker service create \
--name hello chenghuizhang/helloword:0.0.2 \
--replicas 2 \
--network mynet \
-p 8080:8080


到这里,我们已经构建了一个名为 mynet 的网络集群了,集群网络模型如下:640.png

swarm 集群的内部会为容器的各个节点之间负责负载均衡的管理,无需我们去操心了,如上如图三台服务器,无论我们访问的哪台服务器,都可以访问到 docker 各个可用节点中,比如访问 172.16.1.11:8080,也可以通过 swarm 集群的负载均衡转发到 172.16.1.12:8080。


相关文章
|
5月前
|
C++
基于Reactor模型的高性能网络库之地址篇
这段代码定义了一个 InetAddress 类,是 C++ 网络编程中用于封装 IPv4 地址和端口的常见做法。该类的主要作用是方便地表示和操作一个网络地址(IP + 端口)
315 58
|
5月前
|
网络协议 算法 Java
基于Reactor模型的高性能网络库之Tcpserver组件-上层调度器
TcpServer 是一个用于管理 TCP 连接的类,包含成员变量如事件循环(EventLoop)、连接池(ConnectionMap)和回调函数等。其主要功能包括监听新连接、设置线程池、启动服务器及处理连接事件。通过 Acceptor 接收新连接,并使用轮询算法将连接分配给子事件循环(subloop)进行读写操作。调用链从 start() 开始,经由线程池启动和 Acceptor 监听,最终由 TcpConnection 管理具体连接的事件处理。
217 2
|
5月前
基于Reactor模型的高性能网络库之Tcpconnection组件
TcpConnection 由 subLoop 管理 connfd,负责处理具体连接。它封装了连接套接字,通过 Channel 监听可读、可写、关闭、错误等
172 1
|
5月前
|
JSON 监控 网络协议
干货分享“对接的 API 总是不稳定,网络分层模型” 看电商 API 故障的本质
本文从 OSI 七层网络模型出发,深入剖析电商 API 不稳定的根本原因,涵盖物理层到应用层的典型故障与解决方案,结合阿里、京东等大厂架构,详解如何构建高稳定性的电商 API 通信体系。
|
7月前
|
域名解析 网络协议 安全
计算机网络TCP/IP四层模型
本文介绍了TCP/IP模型的四层结构及其与OSI模型的对比。网络接口层负责物理网络接口,处理MAC地址和帧传输;网络层管理IP地址和路由选择,确保数据包准确送达;传输层提供端到端通信,支持可靠(TCP)或不可靠(UDP)传输;应用层直接面向用户,提供如HTTP、FTP等服务。此外,还详细描述了数据封装与解封装过程,以及两模型在层次划分上的差异。
1340 13
|
7月前
|
网络协议 中间件 网络安全
计算机网络OSI七层模型
OSI模型分为七层,各层功能明确:物理层传输比特流,数据链路层负责帧传输,网络层处理数据包路由,传输层确保端到端可靠传输,会话层管理会话,表示层负责数据格式转换与加密,应用层提供网络服务。数据在传输中经过封装与解封装过程。OSI模型优点包括标准化、模块化和互操作性,但也存在复杂性高、效率较低及实用性不足的问题,在实际中TCP/IP模型更常用。
984 10
|
2月前
|
机器学习/深度学习 数据采集 人工智能
深度学习实战指南:从神经网络基础到模型优化的完整攻略
🌟 蒋星熠Jaxonic,AI探索者。深耕深度学习,从神经网络到Transformer,用代码践行智能革命。分享实战经验,助你构建CV、NLP模型,共赴二进制星辰大海。
|
3月前
|
机器学习/深度学习 传感器 算法
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
236 2
|
3月前
|
机器学习/深度学习 并行计算 算法
【CPOBP-NSWOA】基于豪冠猪优化BP神经网络模型的多目标鲸鱼寻优算法研究(Matlab代码实现)
【CPOBP-NSWOA】基于豪冠猪优化BP神经网络模型的多目标鲸鱼寻优算法研究(Matlab代码实现)
|
5月前
基于Reactor模型的高性能网络库之Poller(EpollPoller)组件
封装底层 I/O 多路复用机制(如 epoll)的抽象类 Poller,提供统一接口支持多种实现。Poller 是一个抽象基类,定义了 Channel 管理、事件收集等核心功能,并与 EventLoop 绑定。其子类 EPollPoller 实现了基于 epoll 的具体操作,包括事件等待、Channel 更新和删除等。通过工厂方法可创建默认的 Poller 实例,实现多态调用。
315 60

热门文章

最新文章