深入浅出容器学习--Docker网络

一.Docker的网络概念

容器网络模型主要包含了三个概念:

  • network:网络,这里可以理解为一个Driver,是一个第三方网络栈,包含多种网络模式。

    • 单主机网络模式(none、host、bridge)
    • 多主机网络模式(overlay、macvlan、flannel)
  • sandbox:沙盒,它定义了容器内的虚拟网卡、DNS和路由表,是network namespace的一种实现,是容器的内部网络栈。

  • endpoint:端点,用于连接sandbox和network。

    这里,我们可以类比传统网络模型,将network比作交换机,sandbox比作网卡,endpoint比作接口和网线。

二.Docker的网络模式

这里网络模式包含:

  • host模式
  • none模式
  • bridge模式
  • container模式

2.1 host模式

这个相当于Vmvare中的桥接模式,与宿主机在同一个网络中,但是没有独立的IP地址。
Docker不会为容器创建独有的network namespace,使用宿主机默认的网络命名空间,共享一个网络栈。表现为容器内核宿主机的IP一致。这种模式适用于网络性能要求较高的场景,但网络隔离性不太好。

2.2 bridge模式

桥接模式,这里相当于Vmvare中的Nat模式。
Docker进程启动时会创建一个docker0网桥,docker会为容器创建独有的network namespace,也会为这个命名空间配置好虚拟网卡、路由、DNS、IP地址与iptables规则(也就是sanbox内容)

2.2.1 Docker完成Bridge网络配置详细说明

1.在主机上创建一堆虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
2.Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth45h6这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show查看。

[root@harbor ~]# brctl show 
bridge name	        bridge id		STP enabled	interfaces
br-2ba1d6a2e994		8000.02426cb4a81a	no		veth6a79ace
br-8d4b6181687f		8000.0242d8d0780d	no		
docker0		        8000.02424dbb4b07	no

3.从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。

[root@harbor ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
4b59058aece1        docker-nexus3:v1    "sh -c ${SONATYPE_DI…"   2 months ago        Up 2 months         0.0.0.0:81->8081/tcp   nexus3
[root@harbor ~]# docker inspect 4b59058aece1
.......
            "Networks": {
                "nexus_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "4b59058aece1",
                        "docker_nexus3"
                    ],
                    "NetworkID": "2ba1d6a2e994bb68c9a9ec000867db8fb14e20c6abcaa95f9399b0d9a270b960",
                    "EndpointID": "e191fe5833aff25bbc6f71c215a717c5fa6c9f2b62690d94806768a302272129",
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:12:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]
# 查看nexus_default的bridge network 
[root@harbor_reg ~]# docker network inspect nexus_default
[
    {
        "Name": "nexus_default",
        "Id": "2ba1d6a2e994bb68c9a9ec000867db8fb14e20c6abcaa95f9399b0d9a270b960",
        "Created": "2020-08-24T10:20:21.947908808+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "4b59058aece184806ecc8d7d2c7c9dd93b24d7d120ea782d5c6909819725fe2d": {
                "Name": "nexus3",
                "EndpointID": "e191fe5833aff25bbc6f71c215a717c5fa6c9f2b62690d94806768a302272129",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "nexus",
            "com.docker.compose.version": "1.23.2"
        }
    }
]

2.3 none模式

none模式可以说是桥接模式的一种特例,docker会为容器创建独有的network namespace ,但不会为这个命名空间准备虚拟网卡,IP地址,路由等,需要用户自己配置。这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

2.4 container模式

容器共享模式,这种模式是host模式的一种延伸,一组容器共享一个network namespace。对外表现为它们有共同的IP地址,共享一个网络栈。

三.Docker跨主机网络通讯

默认情况下,单台主机上的Docker容器可以通过docker0网桥直接通信,而不同主机上的Docker容器之间只能通过在主机上做端口映射进行通信。这种端口映射方式对许多集群应用来说非常不方便,如果可以让Docker容器直接使用自己的IP地址进行通信可以解决很多问题。这里按照实现原理可以分为:

  • 直接路由模式
  • overlay隧道模式(如flannel、ovs+gre)
  • 桥接模式(如pipework)

3.1 直接路由

直接在两侧主机增加静态路由来实现:

ip route add 172.16.1.0/24 via 192.168.20.1
ip route add 172.16.2.0/24 via 192.168.20.2

注意:centos系统需要卡其ip转发

vim /etc/sysctl.d/99-sysctl.conf
net.ipv4.ip_forward = 1
sysctl -p

这里测试两台主机的容器跨主机通信可以参考此博文,相当详细:https://www.cnblogs.com/xiao987334176/p/10049844.html

3.2 overlay隧道模式

这里以flannel(flannel+udp或flannel+vxlan)来说明
flannel实现的容器的跨主机通信过程如下过程实现:

  • 每个主机安装并运行etcd和flannel
  • 在etcd中规划配置所有主机的docker0子网范围
  • 每个主机上的flanneld根据etcd中的配置,为本主机的docker0分配子网,保证所有主机的docker0网段不重复,并将结果(及本主机上的docker0子网信息和本主机IP的对应关系)存储到etcd中,这样etcd就保存了所有主机上的docker子网信息和本主机IP的对应关系。
  • 当需要与其它主机上的网络进行通信时,查找etcd数据库,找到目的容器的子网所对应的outip(目的宿主机的IP)。
  • 将原始数据包封装在Vxlan或UDP数据包,IP层以outip为目的IP进行封装。
  • 由于目的IP是宿主机IP,因此路由是可达的。
  • Vxlan或UDP数据包到达目的宿主机解封装,解出原始数据包,最终到达目的容器。

3.3 桥接模式

这里可以通过静态指定容器的IP为宿主机同一个网络的形式来实现。这里不做具体说明,可以参考其它博文实现:https://blog.csdn.net/xpt211314/article/details/97375671

参考文档连接:
https://www.jianshu.com/p/22a7032bb7bd
https://zhuanlan.zhihu.com/p/82735394

posted @ 2020-10-26 17:21  yuhaohao  阅读(257)  评论(0编辑  收藏  举报