概述
最近在尝试使用c++实现出一个简易的docker版本,因此需要对docker的架构有一个比较清晰的认识。众所周知,docker通过linux 的namespace和CGroup技术为docker上的不同容器实现资源(文件系统、网络等)的隔离;但是在隔离的基础之上,在docker的使用中,我们可能需要实现容器和外部网络或者不同容器之间的通信(基于协作等关系)。今天想开始学习一下docker中不同容器之间的通信原理。
容器之间的通信可以分为单主机容器之间的通信和跨主机容器之间的通信。
单主机容器之间的通信
基于net namespace的控制,docker可以实现容器之间网络栈的隔离,这种隔离既包括容器与宿主机之间网络的隔离。docker的网络有五种模式:
(1)bridge:这是docker默认的网络设置,各个容器具有独立的网络命名空间,有自己的网卡;
(2)host:容器和宿主机之间共享网络命名空间;
(3)none:容器拥有自己的namespace,但是并不做任何的网络设置,容器中没有网卡、IP、路由等,需要用户手动设置添加;
(4)container:主要和host模式区分,容器和宿主机之间不再共享网络命名空间,而是和指定的容器之间共享网络命名空间,容器之间可以使用lo网卡进行通信;但是容器之间的文件、进程列表等还是隔离的;
(5)用户定义:允许容器使用第三方的网络实现或者创建单独的bridge网络,提供网络隔离能力。
bridge模式
docker为容器创建独立的网络环境,实现宿主和容器、容器之间的网络隔离;但是可以通过docker0网桥实现容器之间、容器与宿主机之间、乃至与外界之间 的网络通信。如下图所示:
bridge模式网络架构可以看到,各个容器有自己的eth0网卡,容器所有的网络请求都通过eth0向外传递。但是为了实现容器之间的通信,容器必须增加一个网络设备veth,并将它们加到宿主机上的docker0网桥之上,实现不同网段数据包的转发功能,进而具备通信能力。但是,考虑到外界和容器主动与容器进行通信的情况,我们知道容器只是活在宿主机上的一个进程而已,如何让外界追溯到特定的容器呢?docker使用的是端口绑定的方式,并将外界的端口流量转发到目的端口,也就是特定的容器之上,这就实现了外界和容器之间的通信。
host模式
host模式指的是容器和宿主机之间共享网络命名空间,也就是说容器和宿主机之间共享IP地址,可以使用宿主机的网卡等网络资源。从外界来看,容器的IP地址和宿主机的IP地址并没有区别。该模式的结构图如下所示:
host模式结构可以看到,该容器没有自己的网卡,而是直接使用宿主机上的eth0网卡,直接使用宿主机的IP地址和外界进行通信。由于这种模式不需要额外对收到的外界的数据包进行拆分、转发,因此在性能和效率上具有一定的优势。但是,这种模式的缺点之一就是不具有独立的网络环境。
none模式
容器有独立的网络栈,但不包含任何网络配置,只具有lo这个loopback网卡用于进程通信。
container模式
这种模式中,容器和宿主机之间的关系和bridge模式相似,不同之处在于在这种模式之下,新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等,指定容器之间不具有独立的网络环境。架构图如下所示:
container模式的架构跨主机之间的通信
这部分的内容暂时不更新,有时间继续拉~
参考:https://www.cnblogs.com/ilinuxer/p/6680205.html
http://www.dockone.io/article/1261
网友评论