美文网首页
Docker 网络配置(转载)(三)

Docker 网络配置(转载)(三)

作者: lconcise | 来源:发表于2019-10-23 18:10 被阅读0次

    Docker 网络配置(转载)
    Docker存储
    Docker compose(转载)
    Docker 部署 SpringBoot

    Docker默认提供了三种网络模式:bridge、host和none。其中bridge是Docker默认的网络模式,在该模式下,容器拥有自己的IP namespace,容器可以通过宿主机上的docker0网桥与别的容器、宿主机或者外部网络进行通信。此外我们还可以通过端口映射的方式让外部环境也能访问到容器内部

    Docker默认的网络模式如下图所示:


    image.png

    Docker三种网络模式:

    [root@10-9-106-123 ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    c53c96b96bf6        bridge              bridge              local
    b1c072a1ed81        host                host                local
    d6428266671a        none                null                local
    

    bridge 网络模式

    下面我们通过busybox来进行演示。

    BusyBox 是一个集成了一百多个最常用 Linux 命令和工具(如 cat、echo、grep、mount、telnet 、ping、ifconfig 等)的精简工具箱,它只需要几 MB 的大小,很方便进行各种快速验证,被誉为“Linux 系统的瑞士军刀”。

    下载busybox镜像:

    docker pull busybox
    

    通过该镜像创建两个容器test1和test2:

    docker run -d --name test1 busybox /bin/sh -c "while true;do sleep 3600;done"
    docker run -d --name test2 busybox /bin/sh -c "while true;do sleep 3600;done"
    
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                               NAMES
    eed052cbe653        busybox             "/bin/sh -c 'while t…"   44 seconds ago       Up 43 seconds                                           test2
    45b8e4f93f57        busybox             "/bin/sh -c 'while t…"   About a minute ago   Up About a minute                                       test1
    

    使用docker network inspect bridge命令查看bridge网络详情:

    [root@10-9-106-123 ~]# docker network inspect bridge
    [
        {
            "Name": "bridge",
            "Id": "c53c96b96bf640ac09d308a74d533fc0473516da7bb4aa282f8dc01df0df6853",
            "Created": "2019-10-08T10:49:39.925426027+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": [
                    {
                        "Subnet": "172.17.0.0/16"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "45b8e4f93f571262958b5c6ca1bd845a45e146b8ecc1efa6dcc5b57894a2ac48": {
                    "Name": "test1",
                    "EndpointID": "75ec60d665402ef96b2e2ed165e2eae9422b37563c0463ad1166142bfea73f22",
                    "MacAddress": "02:42:ac:11:00:03",
                    "IPv4Address": "172.17.0.3/16",
                    "IPv6Address": ""
                },
                "eed052cbe653f5858a5f16d6b74db594b03172b0b37f3c5be1ec1df0cf47d046": {
                    "Name": "test2",
                    "EndpointID": "c5640f3de08311e9859c7edea71990b56d197012d7e7784aeafdb3ed8a2ba977",
                    "MacAddress": "02:42:ac:11:00:05",
                    "IPv4Address": "172.17.0.5/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",
                "com.docker.network.driver.mtu": "1500"
            },
            "Labels": {}
        }
    ]
    

    可以看到test1和test2都连接到了bridge(因为是Docker默认的网络模式),并且test1内部IP为172.17.0.3,test2内部IP为172.17.0.5。

    我们看下在test1容器内部是否可以ping通test2的IP:

    [root@10-9-106-123 ~]# docker exec -it test1 /bin/sh
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> 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
    123: eth0@if124: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    / # ping 172.17.0.5
    PING 172.17.0.5 (172.17.0.5): 56 data bytes
    64 bytes from 172.17.0.5: seq=0 ttl=64 time=0.271 ms
    64 bytes from 172.17.0.5: seq=1 ttl=64 time=0.098 ms
    64 bytes from 172.17.0.5: seq=2 ttl=64 time=0.092 ms
    64 bytes from 172.17.0.5: seq=3 ttl=64 time=0.108 ms
    64 bytes from 172.17.0.5: seq=4 ttl=64 time=0.116 ms
    ^C
    --- 172.17.0.5 ping statistics ---
    5 packets transmitted, 5 packets received, 0% packet loss
    round-trip min/avg/max = 0.092/0.137/0.271 ms
    

    可以看到是没问题的。

    看下test1内部ping宿主机IP(192.168.33.10)和外部网络是否可行:

    / # ping 106.75.99.88
    PING 106.75.99.88 (106.75.99.88): 56 data bytes
    64 bytes from 106.75.99.88: seq=0 ttl=57 time=2.656 ms
    64 bytes from 106.75.99.88: seq=1 ttl=57 time=1.274 ms
    64 bytes from 106.75.99.88: seq=2 ttl=57 time=1.683 ms
    64 bytes from 106.75.99.88: seq=3 ttl=57 time=1.318 ms
    ^C
    --- 106.75.99.88 ping statistics ---
    4 packets transmitted, 4 packets received, 0% packet loss
    round-trip min/avg/max = 1.274/1.732/2.656 ms
    / # ping baidu.com
    PING baidu.com (220.181.38.148): 56 data bytes
    64 bytes from 220.181.38.148: seq=0 ttl=49 time=3.586 ms
    64 bytes from 220.181.38.148: seq=1 ttl=49 time=3.236 ms
    64 bytes from 220.181.38.148: seq=2 ttl=49 time=3.291 ms
    64 bytes from 220.181.38.148: seq=3 ttl=49 time=3.395 ms
    ^C
    --- baidu.com ping statistics ---
    4 packets transmitted, 4 packets received, 0% packet loss
    round-trip min/avg/max = 3.236/3.377/3.586 ms
    

    link

    我们可以在创建容器的使用使用--link来让容器间的网络建立映射关系。

    我们删除test2容器,重新创建test2容器,并且让其和test1建立网络映射关系:

    [root@10-9-106-123 ~]# docker ps 
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    45b8e4f93f57        busybox             "/bin/sh -c 'while t…"   9 minutes ago       Up 9 minutes                            test1
    [root@10-9-106-123 ~]# docker run -d --name test2 --link test1 busybox /bin/sh -c "while true;do sleep 3600;done"
    231a9e9807a7e1885e500ace5c35ac78db260a3acc700d84dc0733a2d08ddd1e
    [root@10-9-106-123 ~]# docker ps 
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    231a9e9807a7        busybox             "/bin/sh -c 'while t…"   28 seconds ago      Up 27 seconds                           test2
    45b8e4f93f57        busybox             "/bin/sh -c 'while t…"   11 minutes ago      Up 11 minutes                           test1
    

    这样我们就可以在test2容器内部使用ping test1ping通test1网络了:

    [root@10-9-106-123 ~]# docker exec -it test2 /bin/sh 
    / # ping test1
    PING test1 (172.17.0.3): 56 data bytes
    64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.312 ms
    64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.092 ms
    64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.127 ms
    64 bytes from 172.17.0.3: seq=3 ttl=64 time=0.090 ms
    64 bytes from 172.17.0.3: seq=4 ttl=64 time=0.163 ms
    ^C
    --- test1 ping statistics ---
    5 packets transmitted, 5 packets received, 0% packet loss
    round-trip min/avg/max = 0.090/0.156/0.312 ms
    

    创建自定义网桥

    我们可以通过docker network create来创建自定义的网桥,比如我们创建一个新的网桥,名称为my-bridge:

    [root@10-9-106-123 ~]# docker network create -d bridge my-bridge
    d2c3eba5730dd46ff78a08112a7b135a4dbeeeb4463522d165dfdaeade110490
    [root@10-9-106-123 ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    c53c96b96bf6        bridge              bridge              local
    b1c072a1ed81        host                host                local
    d2c3eba5730d        my-bridge           bridge              local
    d6428266671a        none                null                local
    

    模式选择的是bridge。

    我们让test1和test2容器都连接到这个新的网桥上(也可以在创建容器的时候使用--network来指定需要连接的网桥):

    docker network connect my-bridge test1
    docker network connect my-bridge test2
    
    [root@10-9-106-123 ~]# docker network connect my-bridge test1
    [root@10-9-106-123 ~]# docker network connect my-bridge test2
    [root@10-9-106-123 ~]# docker network inspect my-bridge
    [
        {
            "Name": "my-bridge",
            "Id": "d2c3eba5730dd46ff78a08112a7b135a4dbeeeb4463522d165dfdaeade110490",
            "Created": "2019-10-22T09:54:31.346908759+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "172.21.0.0/16",
                        "Gateway": "172.21.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "231a9e9807a7e1885e500ace5c35ac78db260a3acc700d84dc0733a2d08ddd1e": {
                    "Name": "test2",
                    "EndpointID": "06635102c858d2c6fe7c52abef479bd16f1fa433d0d8bd0fb2779a97f64999c3",
                    "MacAddress": "02:42:ac:15:00:03",
                    "IPv4Address": "172.21.0.3/16",
                    "IPv6Address": ""
                },
                "45b8e4f93f571262958b5c6ca1bd845a45e146b8ecc1efa6dcc5b57894a2ac48": {
                    "Name": "test1",
                    "EndpointID": "d6d41a57ba024e23e4a74f10544b776c904ab9601ad4545e27d539dafcdfa0bb",
                    "MacAddress": "02:42:ac:15:00:02",
                    "IPv4Address": "172.21.0.2/16",
                    "IPv6Address": ""
                }
            },
            "Options": {},
            "Labels": {}
        }
    ]
    

    可以看到test1和test2都连接上来了。

    使用自定义网桥有个明显的好处是,容器间可以通过容器名称进行网络通信(无需在创建容器的时候使用--link来指定)。我们在创建test1容器的时候并没有使用--link test2来连接test2,我们看看在连接到my-bridge后,test1内部是否可以通过ping test2ping通test2 IP:

    端口映射

    在宿主机上我们是无法访问Docker容器内部网络的,不过我们可以通过端口映射的方式来实现这个需求。

    以MySQL为例子,我们拉取MySQL镜像:

    docker pull mysql:5.7.25
    

    在创建MySQL容器的时候可以使用-p或-P让容器暴露的端口和宿主机的端口进行映射:

    docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_WORD=root mysql:5.7.25
    

    -e指定环境变量。

    -p 3306:3306(冒号前面的端口为宿主机端口,后面的端口为容器端口)的意思是,让容器暴露的3306端口映射到宿主机的3306端口,这样我们就可以在宿主机外部通过106.75.99.88:3306来连接MySQL容器了

    Docker的host和none网络模式使用较少这里就不介绍了。

    参考博文:
    https://docs.docker.com/v17.09/engine/userguide/networking/#set-the-environment-variables-manually
    https://mrbird.cc/Docker-network.html

    相关文章

      网友评论

          本文标题:Docker 网络配置(转载)(三)

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