分享关于容器网络模型CNM和libnetwork

2023-05-19
关注

CNM

CNM (Container Network Model) 是 Docker 发布的容器网络标准。也有不是Docker发布的标准,例如CNI.CNI是由以Kubernetes为代表的公司发布的标准。主要还是因为Kubernetes面对的是多容器而不是单容器,所以标准和docker的不一样,有专门的博客来介绍为什么Kubernetes不选择CNM作为容器的网络标准。虽然最后k8s的CNI成为了容器网络标准,但是libnetwork的容器网络模式使得pod中容器共享网络环境成为可能。

libnetwork

Docker网络部分代码被抽离并单独成为了Docker的网络库,即libnetwork。

(图片来自网络,侵删)

从上图可以看到libnetwork和docker daemon之间的关系。Docker daemon通过调用libnetwork对外提供的API完成网络的创建和管理等功能。libnetwork中则使用了CNM来完成网络功能的提供。同时也可以看到CNM的三个重要元素:

沙箱(sandbox):沙箱代表一个容器网络栈的信息。可以对容器的接口、路由和DNS设置等进行管理。沙盒的实现可以是Linux network namespace、FreeBSD Jail或者类似的机制。一个沙盒可以有多个端点和多个网络。

接入点(Endpoint):接入点将沙箱连接到网络中,代表容器的网络接口,接入点的实现通常是 Linux 的 veth 设备。一个接入点只可以属于一个网络并且只属于一个沙箱。

网络(Network):网络是一组可以直接互相联通的接入点。网络的实现可以是Linux bridge、VLAN等。它将多接入点组成一个子网,并且多个接入点之间可以相互通信

了解了CNM,接下来我们来认识libnetwork的四种常见网络模式:

  1. null 空网络模式:可以帮助我们构建一个没有网络接入的容器环境,以保障数据安全。
  2. bridge 桥接模式:可以打通容器与容器间网络通信的需求。
  3. host 主机网络模式:可以让容器内的进程共享主机网络,从而监听或修改主机网络。
  4. container 网络模式:可以将两个容器放在同一个网络命名空间内,让两个业务通过 localhost 即可实现访问。

(1)null 空网络模式

空网意味着没有网络信息,就是一个单纯的没有连接网络的一个容器。我们可以使用docker命令来创建一个空网模式的容器来检查容器内部的网络信息,首先我们可以先打开正常模式的容器来看一下网络信息:

/yapi # ifconfig                                                                                             
eth0      Link encap:Ethernet  HWaddr 02:42:AC:12:00:02                                                      
          inet addr:172.18.0.2  Bcast:172.18.255.255  Mask:255.255.0.0                                       
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1                                                 
          RX packets:597521 errors:0 dropped:0 overruns:0 frame:0                                            
          TX packets:1194752 errors:0 dropped:0 overruns:0 carrier:0                                         
          collisions:0 txqueuelen:0                                                                          
          RX bytes:126660347 (120.7 MiB)  TX bytes:254347460 (242.5 MiB)                                     


lo        Link encap:Local Loopback                                                                          
          inet addr:127.0.0.1  Mask:255.0.0.0                                                                
          UP LOOPBACK RUNNING  MTU:65536  Metric:1                                                           
          RX packets:38 errors:0 dropped:0 overruns:0 frame:0                                                
          TX packets:38 errors:0 dropped:0 overruns:0 carrier:0                                              
          collisions:0 txqueuelen:1000                                                                       
          RX bytes:2362 (2.3 KiB)  TX bytes:2362 (2.3 KiB)    
/yapi # route -n                                                                                             
Kernel IP routing table                                                                                      
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface                                
0.0.0.0         172.18.0.1      0.0.0.0         UG    0      0        0 eth0                                 
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

可以看到里面是有网卡信息eth0,ip也正常展示。接下来我们新建空网模式的容器,再来观察它的网卡信息和路由信息:

[root@VM-12-13-centos ~]# docker run --net=none -it busybox                                                  
/ # ifconfig                                                                                                 
lo        Link encap:Local Loopback                                                                          
          inet addr:127.0.0.1  Mask:255.0.0.0                                                                
          UP LOOPBACK RUNNING  MTU:65536  Metric:1                                                           
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                                                 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                                               
          collisions:0 txqueuelen:1000                                                                       
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)                                                             


/ # route -n                                                                                                 
Kernel IP routing table                                                                                      
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface                                
/ #

可以看到,新建的容器没有eth0的信息,并且没有ip信息。这种模式如果不进行特定的配置是无法正常使用的,但是优点也非常明显,它给了用户最大的自由度来自定义容器的网络环境。

(2)bridge 桥接模式

bridge桥接模式是Docker网络模型中的一种常见网络模式,它可以让多个容器之间相互通信,也可以与外部网络进行通信。在bridge模式下,每个容器都会分配一个唯一的IP地址,并且可以通过容器名称或者IP地址互相访问。我们先来了解关于Docker的bridge模式的实现原理。

linux veth 和linux bridge

(图片来自网络,侵删)

docker 的bridge模式就是这样的,可以看到docker0像一个交换机,把不同的容器连通,是他们可以互相通信。一般我们在使用docker做网络映射时,通常都加了-p指定端口,用来做容器间的通信或者与容器外部通信。

(3)host 主机网络模式

host 主机网络模式让容器内的进程共享主机的网络栈,从而使得容器内的应用程序能够直接与主机和外部网络进行通信,同时也可以避免了端口映射和NAT等额外的网络开销。使用这种模式的时候,libnetwork并不会创建独立的network namespace。同样,我们查看host模式下容器内部的网络信息

[root@VM-12-13-centos ~]# docker run -it --net=host busybox                                                                                                                                                                                                                 
/ # ip a                                                                                                                                                                                                                                                                    
1: lo:  mtu 65536 qdisc noqueue qlen 1000                                                                                                                                                                                                             
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00                                                                                                                                                                                                                   
    inet 127.0.0.1/8 scope host lo                                                                                                                                                                                                                                          
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
    inet6 ::1/128 scope host                                                                                                                                                                                                                                                
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
2: eth0:  mtu 1500 qdisc mq qlen 1000                                                                                                                                                                                                      
    link/ether 52:54:00:4f:76:46 brd ff:ff:ff:ff:ff:ff                                                                                                                                                                                                                      
    inet 10.0.12.13/22 brd 10.0.15.255 scope global eth0                                                                                                                                                                                                                    
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
    inet6 fe80::5054:ff:fe4f:7646/64 scope link                                                                                                                                                                                                                             
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
3: br-85f2d3e30fa7:  mtu 1500 qdisc noqueue                                                                                                                                                                                              
    link/ether 02:42:3e:54:35:a5 brd ff:ff:ff:ff:ff:ff                                                                                                                                                                                                                      
    inet 172.22.0.1/16 brd 172.22.255.255 scope global br-85f2d3e30fa7                                                                                                                                                                                                      
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
4: br-c42d4a549c65:  mtu 1500 qdisc noqueue                                                                                                                                                                                                
    link/ether 02:42:39:a3:4a:26 brd ff:ff:ff:ff:ff:ff                                                                                                                                                                                                                      
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-c42d4a549c65                                                                                                                                                                                                      
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
    inet6 fe80::42:39ff:fea3:4a26/64 scope link                                                                                                                                                                                                                             
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
5: docker0:  mtu 1500 qdisc noqueue                                                                                                                                                                                                        
    link/ether 02:42:fd:43:ed:84 brd ff:ff:ff:ff:ff:ff                                                                                                                                                                                                                      
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0                                                                                                                                                                                                              
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
    inet6 fe80::42:fdff:fe43:ed84/64 scope link                                                                                                                                                                                                                             
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                              
6: br-f057a92711b7:  mtu 1500 qdisc noqueue                                                                                                                                                                                              
    link/ether 02:42:78:b5:0a:b4 brd ff:ff:ff:ff:ff:ff                                                                                                                                                                                                                      
    inet 172.21.0.1/16 brd 172.21.255.255 scope global br-f057a92711b7                                                                                                                                                                                                      
       valid_lft forever preferred_lft forever                                                                                                                                                                                                                                                                                                                                                                                                                                                      
/ #

可以看到容器内的网络环境与主机完全一致。但是,但是,容器其他方面,如文件系统、进程列表等还是和宿主机隔离的。所以如果是集群规模比较大的情况,还是不是用这种host模式的。

(4)container 网络模式

container 网络模式可以将多个容器放在同一个网络命名空间内。当这些容器需要共享网络,但其他资源仍然需要隔离时就可以使用 container 网络模式,例如我们开发了一个 http 服务,但又想使用 nginx 的一些特性,让 nginx 代理外部的请求然后转发给自己的业务,这时我们使用 container 网络模式将自己开发的服务和 nginx 服务部署到同一个网络命名空间中。

当创建一个新容器时,我们可以使用以下命令将其加入到已存在的网络命名空间:

docker run -d --name my-nginx1 nginx
docker run -d --name my-nginx2 --network container:my-nginx1 nginx

通过上述命令,我们可以在my-nginx2容器中通过 curl http://localhost来访问my-nginx1容器的Web服务。在container模式下,所有的容器都共享同一个网络栈和IP地址,因此它们之间的网络性能通常比bridge模式更高,但安全性可能会降低。

总结:

  • Docker使用CNM为通信标准来完成网络实现;
  • CNM三要素:沙箱(Sandbox)、接入点(Endpoint)、网络(Network);
  • Libnetwork 常见四种网络模式:null 空网络模式、bridge 桥接模式、host 主机网络模式、container 网络模式;

  • docker
  • 容器
  • 网络模型
  • docker命令
  • brd
您觉得本篇内容如何
评分

评论

您需要登录才可以回复|注册

提交评论

大怪科学

这家伙很懒,什么描述也没留下

关注

点击进入下一篇

物联网时代的设计势在必行

提取码
复制提取码
点击跳转至百度网盘