目录
Docker:网络模型
Network:隔离设备,网络栈,端口等
Bridge:桥网络
一、S1、S2交换机之间用软件模拟虚拟网卡,进行通信
二、S1、S2交换机通过路由转发,实现不同的网段的通信
Nat:网络地址转换协议
Overlay Network:叠加网络
Docker 中网络
Docker 中 Bridge 网络
IPtables 规则
Docker 中 host 网络
引入
Container A要被外部主机B访问,还有什么方法(除了桥接)?
Dockers 中 none 网络
Docker:网络模型
Linux在内核中支持,6中名称空间(可直接操作):UTS,User,Mount,IPC,Network,PID
Network:隔离设备,网络栈,端口等
如图:容器A,B,C三个容器,创建了3个名称空间,3个名称空间独立,配置网卡就可以实现通信,当主机上的物理网卡(有2个)不够分给C这个容器的时候,该怎么办?
可以使用虚拟网卡设备来进行通信,用纯软件的方式来模拟一组设备;Linux内核支持两种级别的设备模拟;一种是二层(链路层)设备:网卡,每个网卡是成对出现的,一端在主机,一端在交换机上,Linux原生支持模拟二层网桥设备交换机(工具bridge-utils);另一种是三层(网络层)OVS(Open VSwitch),软件驱动的网络(SDN)软硬件集中到一个软件上,同一调度
Bridge:桥网络
3个容器模拟出来的网卡,一半在容器内,一半在交换机上进行来实现通信,但这样只能在单节点(S1在同一个交换机上)上进行通信,如果实现两个交换机(S1,S2之间的通信)上容器进行通信怎么来实现?
一、S1、S2交换机之间用软件模拟虚拟网卡,进行通信
简单实现,模拟一对网卡(SA-SA1),一半在S1交换器上,一半在S2交换器上,这样交换机上的节点就可以通信了
二、S1、S2交换机通过路由转发,实现不同的网段的通信
路由器(网络层)设备是一个三层的设备,LInux内核自己就可以当作路由功能来使用,只需要配置IPtables规则,核心转发功能,就可当作路由来使用;在Linux中使用一个单独的名称空间就可以使用(前提是模拟出网卡,建立关联关系)
如图通过:Container R来实现路由器的功能,实现不同的网段进行通信
如何实现不同LInux主机通信尼(跨主机通信)?
我们在物理桥,桥接指的是把物理网卡(eth0)当作交换机来用,所有发给Container A,B,C,都先到达物理网卡(etho);物理网卡根据目标Mac来判断最终交给谁,如果是给物理机的尼?
在局域网通信中,我们都知道是通过Mac地址来识别的,因此Container A,B,C,有专用Mac地址,区别于物理机的Mac地址,来进行识别区分
所以说目标地址是物理机的Mac地址就送给物理机,是Container的Mac地址,就送给对应的Container;所以我们把物理网卡(etho)当作交换机来用,能接受即便Mac不是本机的报文,从而转发给对应的Container,我们在建立一个虚拟网卡(软网卡)专门来处理物理机的报文
但是这种通信方式代价很大,所有容器(Container)和物理机都在同一个网络平面中,容易产生
网络风暴;因此在隔离和管理是不容易,在大规模的网络中使用桥接等于自找死路,除非你能用大二层的技术进行隔离,否则我们都不能直接进行桥接;这是即不使用桥接的方式,又要进行通信,就要使用Nat网络
Nat:网络地址转换协议
位于局域网中Linux A,B中容器A,D要进行通信
Linux A中容器A的网段和eth0不在同一网段,容器A把网关指向S1,把S1当作宿主机的网卡来来使用(和容器A在同一个网段)并且给S1配置一个IP地址,在物理机(Linux System A)打开核心转发功能;
通信过程:容器A和容器D进行通信时,报文先交给S1,达到物理机内核,物理机判定目标地址不是自己的查路由表,要达到容器D,要经过自己(eht0)就会把报文送出去;
但是这样发送出去的报文是回不来,因为容器A是一个私有地址;需要容器A通信接受报文,就需要在报文离开物理机(Linux system A)eht0时把源IP替换为eth0的IP,这样容器D在回复的回复Linux System A (eth0)的IP就可以,eht0通过路由表就可以查到容器A
我们看上面的过程,在通信过程中,容器A和容器D都需要2级NAT的转化,容器A和容器B是看不到对方的,容器A以为和Linux systemc B进行通信,容器B以为和Linux Systemc A进行通信,这样效率不高,但是易于管理,有没有什么办法解决这个问题尼?不想和桥接一样暴露在外,也不想和Nat一样藏在物理机之后?这个时候我们就需要叠加网络来实现
Overlay Network:叠加网络
物理机的物理网卡,同时在虚拟机上做个虚拟的桥,让各容器链接到虚拟的桥上,随后他们通信时完成报文的隧道转发,这样Container A就可以看到Container B和Container C了
Container A 通信时和 主机A 的eth0 不在同一网段,和Container B 在同一网段中,Container A在进行通信时经由主机A进行隧道转发报文.一层,一层解封,就能找到容器B
Docker 中网络
网络简图
docker 提供三种网络bridge【nat 桥】,host【仅主机模式】,none;使用docker network ls 就可以查看
Docker 中 Bridge 网络
查看bridge的命令:[root@localhost ~]# docker network inspect bridge
bridge(nat 桥并非物理桥)使用该网络,会自动创建一个纯粹的软交换机(docker0: 既能当交换机又能当网卡来使用)
上面讲过每次创建一个容器的时候都会创建一对虚拟网卡(veth6736a91),一半连接在容器上,一半连接在虚拟交换机上(docker0),
veth6736a91就是创建的一对的虚拟网卡的一半中的其中一半(在宿主机上),这一半的网卡并且插在了docker0桥上,这个怎么来看尼
[root@localhost ~]# yum install bridge-utils
[root@localhost ~]# brctl show 【veth6736a91已经在docker0】
也可以使用ip命令来查看我们也可以看得到虚拟网卡(veth6736a91)的另一半(@if6)
[root@localhost ~]# ip link show
IPtables 规则
我们知道docker0 桥实际默认是个nat 桥,每创建一个容器并启动后自动分配地址后,就会生成一个规则
从任何接口进来,只要不从docker01桥出去的,源地址来自172.17.0.0的网络任何地址,无论达到任何地址都需要进行地址伪装[自动选择一个地址】:所以说docker0时nat 桥就是这个原因
[root@localhost ~]# iptables -t nat -vnL 【查看规则】
Docker 中 host 网络
引入
当我们从主机B去,去访问主机A上的容器A,在主机A上eth0上某一个特定端口,denat转发到交换机S1上,进而到达容器A上;也就是说我们我们只要主机A上创建的容器,使用默认的bridge的网络,只能在额外的denat规则,以便于从外部主机访问
假设Container A 时nginx,Container B ,C都是基于Container A的镜像启的,对外通信物理机只有一个网卡,只有一个IP地址,怎么来做denat ,从对外主机来80端口通信就转发到Container A,那Container B,C尼【没有特别好的方法,我们只能使用映射来解决,或叠加网络,默认Nat网络是不具有的】
Container A要被外部主机B访问,还有什么方法(除了桥接)?
除了桥接好像也没有什么办法,但是容器有一个功能 ,我们都知道容器拥有独立的6个命名空间:Natwork,Mount,User,IPC,Pid,UTS,独立的资源
假设Container A,B公用UTS,Network,IPC:使用同一个主机名,域名,网络,消息协议栈;各自独立User,Mount,Pid :公用各自的账号,文件系统;这样好处在于,假设Contaner A是nginx,Container B是tomcat,他们之间就可以用127.0.0.1来进行访问
我在设想下物理机有没有网络名称空间,只要是名称空间物理机网无法无非有一些特权名称空间能看到物理网卡设备,那一个容器能使用物理机网络名称空间吗?是可以的
如图所示,Container A和主机A的eth0公用网络空间,Container B和Container C还可以直接使用桥接网络,这样Container A修改网络就会直接修改主机A的网络了;这个网络就是Docker 中Host的网络
Dockers 中 none 网络
none以为着买了电脑没有网卡,是不能进行网络通信了,只有lo接口,是一个信息孤岛;我一般使用这种网络进行数据处理,计算,处理性质的任务



