Docker网络原理

释放双眼,带上耳机,听听看~!

Docker Network

[root@mail /]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3f5d7624918a        bridge              bridge              local
0d2af6ce6648        host                host                local
606c6ae1b257        none                null                local

docker network ls #查看docker网络模式

  • bridge:桥接式网络
  • host:本机主机网络
  • none:封闭式网络
    注意:以上只是简单概述,后面内容会自己讲解这三种网络模式

Docker Network bridge

Docker安装完成后默认会生成一个docker0的网卡,该网卡被称为 nat桥,使用的是bridge网络模式,当我们启动一个容器,Docker server会为相应的容器创建一份网卡,一半在宿主机上,我们使用ifconfig可以看到,另一半在容器里面,同样使用默认的bridge网络模式,并且这些容器在宿主机的网卡还被关联到了Docker0上我们可以使用 brctl命令来查看容器网卡是怎么关联到docker0网卡上的

[root@mail /]# yum install bridge-utils -y                          #安装brctl命令
[root@mail /]# brctl  show                                          #查看关联在docker0上的网卡接口
bridge name bridge id       STP enabled interfaces
docker0     8000.0242601bccc1   no      veth34f612f
                                        veth545339c
                                        vethc68cecf
#注意:brctl show命令可以看到虚拟接口veth34f612f、veth545339c、vethc68cecf被关联到了docker0上
[root@mail /]# docker ps -a                                         #而我们也是正好启动了三台容器
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
2e9d14fd164c        nginx               "/bin/bash"         11 days ago         Up 11 days          80/tcp               nginx
3985a490bf99        centos              "/bin/bash"         11 days ago         Up 11 days                              centos
234e58b7e8be        tomcat              "/bin/bash"         11 days ago         Up 11 days          8080/tcp            tomcat

使用 ip link show 命令查看容器接口被关联到了Docker0网卡上

[root@mail /]# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:c6:fb:66 brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:60:1b:cc:c1 brd ff:ff:ff:ff:ff:ff
31: veth34f612f@if30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether c2:52:ae:54:eb:33 brd ff:ff:ff:ff:ff:ff link-netnsid 2
35: veth545339c@if34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether 1e:bc:1c:e5:50:15 brd ff:ff:ff:ff:ff:ff link-netnsid 1
39: vethc68cecf@if38: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether 16:dd:63:ad:7b:ed brd ff:ff:ff:ff:ff:ff link-netnsid 0

每个接口的开始都显示了接口编号后缀都是以“@ifxx”结尾,编号和使用brctl show命令查看到的是一致的;这是我们上面所说的一份网卡的一份接口,而另一个接口编号为网卡编号后面的后缀“@ifxx”,而此接口是在容器内。

Docker Network host

名称空间

USer、Mount、Pid、IPC、Network、UTS

  1. 这张图是容器有独立的User,mount,pid,但UTS、Net、IPC却是和宿主机共享的
  2. 拥有独立的用户组,独立的挂载文件系统,独立的进程;但却有共同主机名、域名,共同的IP地址,共同的消息队列等;这也是我们的第二种docker网络模式host。
  3. 所谓的host就是宿主机,让容器使用宿主机的名称空间User、mount、pid
  4. host模式中容器之间通信可以通过lo接口来进行通信,因为它们是共同的网络,例如一台容器装了reids,一台容器装了nginx,在任何一 个容器以及宿主机上可以使用 127.0.0.1:port来访问相应的应用

Docker Network none

none网络代表空,空网络,意味着他们没有网络,只有lo接口,就相当你买了个主机,里面没有网卡,有些机器只需要进行计算,图片编码,视频转码等计算型服务器亦不需要联网

Docker Network模式总结

四种网络模型:

第一种Closed container,none:只有lo接口,没有网络
第二种bridge container,bridge:桥接式接口,通过容器的虚拟接口,连接到Docker0桥上,这个桥接是nat桥
第三种Joined container,host:称为联盟网络,就是我们上面讲的host模式,有独立的User,mount,pid,但UTS、Net、IPC却是和宿主机共享的,他们可以通过lo接口通信
第四种open container,开放式网络:直接共享与物理机的名称空间,名称空间内的所有东西,所以称为开放式网络,它的网卡是你的物理网络接口,物理网卡能够看到哪些,它就可以看到哪些网络

注意:如我们在创建容器时没有指定网络,那么统统为第二种网络桥接式模式:bridge网络

Docker与iptbales的前世今因

当我们启动一个容器,就会在宿主机的iptbales上生成一条规则

  1. iptables给docker提供网络的隔离和网络nat转发及发布
  2. docker使用 docker run -p等命令发布的端口都会在iptbales中自动添加相应的策略,并且iptabels的默认策略不会影响到docker所发布的端口信息
[root@mail /]# iptables -t nat -vnL | grep docker0
0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0

代表从任何接口进来,只要不是从docker0网络出去的,源地址为172.17.0.0/16段的地址,无论到达任何地址,我们都会为它做MASQUERADE(地址伪装),相当于SNAT,而且还是自动SNAT,所谓的自动SNAT就是选择一个合适的源地址自动进行伪装

Docker 容器网络信息

创建容器时如果不指定网络模式,默认为default网络,default网络为bridge

[root@mail /]# docker network inspect bridge    #查看birdge网络详细信息
[
    {
        "Name": "bridge",
        "Id": "3f5d7624918a975e014b3364c288ec2c78742fd25416a5eaa5c61f9bbdf8a8ea",
        "Created": "2018-10-13T10:06:10.573182391+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",      #bridge网络所属的网络为172.17.0.0,在这个网络内开始分配地址
                    "Gateway": "172.17.0.1"         #docker容器的网关地址
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {
            "234e58b7e8be6a2ce8894dd883866d313f08b678692b7a6b5a6af28b17ee0123": {
                "Name": "tomcat",
                "EndpointID": "1095f0c4e719bc613be520dee3ff75827867538824d1681056eb986a95980eb7",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
            "2e9d14fd164c3358a00fe50a2b264a358468679acfd2de30f9aafac388f76c1b": {
                "Name": "nginx",
                "EndpointID": "f0f71c635242ddb5cc3a518fa1e902c4dc4eab761dd338e3c7159807cca41244",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "3985a490bf998f5c35b9e794e0027c72cecacbdc267ac27727be044f5cab2874": {
                "Name": "centos",
                "EndpointID": "df97637c706cbddf1e47726f609f21f3fbb3350a0a8318e89a0aa89994520bf3",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",        #这个地方可以看到brigde网络使用的网卡为docker0
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

查看容器的详细信息

[root@mail /]# docker  container inspect nginx  | grep -C 15  Networks
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/7ac8fc7bf1d1",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "f0f71c635242ddb5cc3a518fa1e902c4dc4eab761dd338e3c7159807cca41244",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {                                 #可以看到该容器使用的网络模式为bridge
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "3f5d7624918a975e014b3364c288ec2c78742fd25416a5eaa5c61f9bbdf8a8ea",
                    "EndpointID": "f0f71c635242ddb5cc3a518fa1e902c4dc4eab761dd338e3c7159807cca41244",
                    "Gateway": "172.17.0.1",                #网关是172.17.0.1
                    "IPAddress": "172.17.0.2",              #地址是172.17.0.2
                    "IPPrefixLen": 16,                      #掩码长度
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02"       #虚拟网卡的mac地址
                }
            }

人已赞赏
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧