Docker学习(七)网络

作者: 我犟不过你 | 来源:发表于2020-09-25 15:00 被阅读0次

    一、网络

    1、宿主机本地网络

    通过ip addr(我使用的ECS centos7.6)查看当前宿主机本地网络。

    [root@iZ2ze7sn66bchxncut8rgsZ /]# ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 00:16:3e:2c:ca:40 brd ff:ff:ff:ff:ff:ff
        inet 172.28.47.71/20 brd 172.28.47.255 scope global dynamic noprefixroute eth0
           valid_lft 314163481sec preferred_lft 314163481sec
        inet6 fe80::216:3eff:fe2c:ca40/64 scope link 
           valid_lft forever preferred_lft forever
    3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
        link/ether 02:42:a5:96:b1:de 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:a5ff:fe96:b1de/64 scope link 
           valid_lft forever preferred_lft forever
    

    发现上述结果中存在一个docker0的网卡,ip网段为172.17.0.1/16,docker容器会自动桥街到该网络上。

    2、docker网络模式

    [root@iZ2ze7sn66bchxncut8rgsZ /]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    bcea3a512ca5        bridge              bridge              local
    c6ec1c6228b7        host                host                local
    25081d2267a8        none                null                local
    

    使用docker network ls 可以查看当前docker的三种默认网络模式,分别是bridge桥连,host主机,以及none。其实docker还有一种网络模式:container模式。下面我们具体分下下四种模式。

    bridge模式:

    bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将并将一个主机上的Docker容器连接到一个虚拟网桥上。在1中看到的宿主机网络中的docker0就是单独给docker服务分配的虚拟网桥。

    我们启动之前课程构建的nginx,或者其他容器也可以

     docker run -d --name nginx-bridge -p 8080:80 nginx:v1
    

    进入容器内,查看ip,发现ip是172.17.0.2

    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker exec -it nginx-bridge bash
    [root@8245c09083ae /]# ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
            ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
            RX packets 53  bytes 5068 (4.9 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 22  bytes 3282 (3.2 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            loop  txqueuelen 1000  (Local Loopback)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    

    查看下宿主机的ip设备,发现多了一个虚拟网卡,该网卡是与容器成对的,这里Docker Daemon 利用 veth pair 了技术:

    宿主机ip addr

    由上面的步骤我们能够推断出docker 容器的bridge网络模型搭嘎如下图:

    bridge网络模型
    host模式:

    如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

    启动一个使用host模式的容器,需要指定--net host参数,发现提示使用host网络模式时,映射端口是无效的,其实不难理解,因为容器公用宿主机的网卡eth0。

    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker run -d --name nginx-bridge -p 8000:80 --net host  nginx:v1
    WARNING: Published ports are discarded when using host network mode
    39840be17832820b37dd23d2c406c8fd2c11111cc3989ff155036f2a1ea8e632
    

    查看当前宿主机ip,看看我们上一步推测是否正确:

    宿主机

    查看容器的ip:

    容器

    上面两幅图发现,容器与宿主机的ip完全相同,在容器中可以操作宿主机的全部网络设备,网络隔离性很差,安全性也很差,我们可以得到以下host网络模式的模型。

    host
    none模式:

    在none模式下,Docker容器拥有自己的Network Namespace,只有lo接口,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。使用--net none模式启动容器:

    docker run -d --name nginx-bridge -p 8000:80 --net none  nginx:v1
    

    进入容器查看其ip:

    容器
    container模式:

    这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。使用--net container:[容器名]

    先启动一个默认桥连的容器:

    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker run -it --name nginx-bridge -p 8080:80 nginx:v1 bash
    [root@f317a0dc60ee /]# ifconfig 
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
            ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
            RX packets 26  bytes 2261 (2.2 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            loop  txqueuelen 1000  (Local Loopback)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    

    再启动一个使用container模式的容器。

    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker run -it --name nginx-c --net container:nginx-bridge nginx:v1 bash
    [root@f317a0dc60ee /]# ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
            ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
            RX packets 25  bytes 2191 (2.1 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            loop  txqueuelen 1000  (Local Loopback)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    

    根据上述结果发现两个容器内部的网络设备相同。
    再看下宿主机的网络设备,只有一个网卡如下图所示:

    宿主机网络设备

    最终我们可以得到container网络模式下的模型:

    container

    3、自定义网络-简单介绍及使用

    除了使用上述四种网络模式以外,我们可以自己为容器创建网络。参考以下的shell命令:

    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker network create --driver bridge my-net
    3f590848cda6f56bf93cea94e768cc46da5803e721d43fcb2eed347c0d8a1ce9
    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    bcea3a512ca5        bridge              bridge              local
    c6ec1c6228b7        host                host                local
    3f590848cda6        my-net              bridge              local
    25081d2267a8        none                null                local
    

    上述结果中我们创建的my-net已经在列表中了,看下我们的网络的网段是多少:

    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker network inspect my-net
    [
        {
            "Name": "my-net",
            "Id": "3f590848cda6f56bf93cea94e768cc46da5803e721d43fcb2eed347c0d8a1ce9",
            "Created": "2020-09-25T14:48:46.164212085+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "172.18.0.0/16",
                        "Gateway": "172.18.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
    

    上面结果里看到我们的网段是172.18.0.1,下面在看下宿主机的网段:

    image.png

    上图看到docker0是172.17.0.1,与我们自己创建的是不同的,下面我们使用自己的网络启动容器,并查看ip:

    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker run -it --name nginx-my-net --net my-net nginx:v1 bash
    [root@63e44026f6b9 /]# ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.18.0.2  netmask 255.255.0.0  broadcast 172.18.255.255
            ether 02:42:ac:12:00:02  txqueuelen 0  (Ethernet)
            RX packets 29  bytes 2547 (2.4 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            loop  txqueuelen 1000  (Local Loopback)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    

    在上面容器的网络中看到网段是172.18.0.2,这说明当前容器已经使用我们自己创建的网络了。

    除了上述之外,还能手动指定网段,举个例子:

    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker network create --subnet 172.19.0.0/24 mysql-net
    8522866b0c686c91c27aadac015498b83d5a22632011649c81c52d0810efd4e6
    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    bcea3a512ca5        bridge              bridge              local
    c6ec1c6228b7        host                host                local
    3f590848cda6        my-net              bridge              local
    8522866b0c68        mysql-net           bridge              local
    25081d2267a8        none                null                local
    [root@iZ2ze7sn66bchxncut8rgsZ opt]# docker network inspect mysql-net 
    [
        {
            "Name": "mysql-net",
            "Id": "8522866b0c686c91c27aadac015498b83d5a22632011649c81c52d0810efd4e6",
            "Created": "2020-09-25T15:12:34.250234517+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "172.19.0.0/24"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
    

    其他特性就不做过多介绍了。
    参考文章:
    https://blog.csdn.net/hetoto/article/details/99892743
    https://blog.csdn.net/huanongying123/article/details/73556634

    相关文章

      网友评论

        本文标题:Docker学习(七)网络

        本文链接:https://www.haomeiwen.com/subject/btzxuktx.html