五、Docker网络管理

一、Docker网络的介绍

Docker 通过Network Namespace 的方式,为每一个容器建立了独立的网络,形成了完全与宿主机隔离的环境。

安装 Docker 后,会自动创建三种默认的网络,分别为 bridge,host,none。。

可以使用 docker network ls 命令进行查看:

[root@TBEARZ206458 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
1934a5d2941a        bridge              bridge              local
a8e866affd79        host                host                local
9b21f21fd421        none                null                local

bridge,即桥接网络,在安装 docker 后会创建一个桥接网络,该桥接网络的名称为 docker0。我们可以通过下面两条命令去查看该值。

可以通过 docker network inspect bridge 进行网络的查看 

[root@TBEARZ206458 ~]# docker network inspect bridge 
[
    {
        "Name": "bridge",
        "Id": "1934a5d2941a18450a31505487c205c5004a140fb85340aee3824efc368b0356",
        "Created": "2020-03-02T09:36:01.469784644+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "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": {}
    }
]

使用ifconfig命令,可以查看到docker0网络的信息

[root@TBEARZ206458 ~]# ifconfig 
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:2a:9f:77:8a  txqueuelen 0  (Ethernet)
        RX packets 25809  bytes 13495463 (12.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 30103  bytes 17251842 (16.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 103.39.213.253  netmask 255.255.255.192  broadcast 103.39.213.255
        ether 00:0c:29:ed:e0:2d  txqueuelen 1000  (Ethernet)
        RX packets 12367111  bytes 8008281549 (7.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2096342  bytes 328067827 (312.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.39.213.253  netmask 255.255.255.192  broadcast 10.39.213.255
        ether 00:0c:29:ed:e0:37  txqueuelen 1000  (Ethernet)
        RX packets 1307344  bytes 80354955 (76.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1312  bytes 78750 (76.9 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 40  bytes 10068 (9.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 40  bytes 10068 (9.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 

默认情况下, Docker 启动时会在宿主机上架设一个名为docker0的虚拟网络,用来连接宿主机与容器。既然容器的网络是以独立隔离的形式存在的,那么Docker 又是如何利用docker0 来实现容器与宿主机。

 

容器启动时, Docker 会把容器内通过Network Namespace 建立的独立网络,通过VethPair 连接到docker0所在的虚拟网络上。

 

 

 默认情况下,我们创建一个新的容器都会自动连接到 bridge 网络。

以下命令是等价的

 docker container run -it -d  --name defaultcontainer1 centos 

 docker container run -it -d  --network bridge  --name defaultcontainer1 centos 

例如创建一个新的容器,然后查看一下bridge

[root@TBEARZ206458 ~]# docker container run -it -d  --name defaultcontainer1 centos 
c7d0722065660b024789c7757dfc8fa3395c2167d3ba5ed90aee5f343bf4dde7
[root@TBEARZ206458 ~]# docker network inspect bridge 
[
    {
        "Name": "bridge",
        "Id": "1934a5d2941a18450a31505487c205c5004a140fb85340aee3824efc368b0356",
        "Created": "2020-03-02T09:36:01.469784644+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "c7d0722065660b024789c7757dfc8fa3395c2167d3ba5ed90aee5f343bf4dde7": {
                "Name": "defaultcontainer1",
                "EndpointID": "0fe7699d6fa21d02a3179546a23594cff016b9530128461a69152dc27c99a5db",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/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": {}
    }
]

备注:如果出现bash: ifconfig: command not found,可以执行如下操作:

yum install net-tools 

② host

host 网络,容器可以直接访问主机上的网络。

$ docker run -it --network host --rm busybox /bin/sh

③ none

none 网络,容器中不提供其它网络接口。none 网络的容器创建之后还可以自己 connect 一个网络,比如使用 docker network connet bridge 容器名 

可以将这个容器添加到 bridge 网络中。

$ docker run -it --nerwork none --rm busybox /bin/sh   

二、网络访问

上面的图表明了,docker容器-宿主机-外部之间的沟通方式,首先容器可以通过docker0对外部进行访问,但是外部通过docker0必须之后转发给具体的哪个容器,这个比较简单的解决方法就是通过绑定端口方式。

I.绑定端口

我们在启动容器的时候,可以通过 (docker run -d -p nginx-p 指定绑定的端口。  

[root@TBEARZ206458 ~]# docker container run -itd --name mydotnet -p 8080:80 centosdotent:1.0.0
f6a624c5d8ac79eb964dd702774e41655da1930d9eaa83d01b9a909b95c0abd6
[root@TBEARZ206458 ~]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                            NAMES
f6a624c5d8ac        centosdotent:1.0.0   "dotnet DotnetWebDem…"   20 seconds ago      Up 18 seconds       5000/tcp, 0.0.0.0:8080->80/tcp   mydotnet 

上面的命令执行之后,就可以通过宿主机的8080端口,访问到容器的80端口了。

此外当容器需要绑定多个端口的时候,可以使用多次 -p <ip>:<hport>:<cport>这种参数形式,绑定多个。

II.容器连接

使用端口绑定可以达到外部对宿主机内部容器访问的目的,但是有时候还需要处理容器之间的连接,此时就需要用到【容器连接】。

一个容器中运行的应用程序,也需要与运行在另外一个容器中的应用程序,通过网络进行数据交换。

要设置容器间通信,我们可以通过在创建容器时携带link 参数来实现,参数的使用形式是 一link <c ontainer

 

举例:创建一个dotnet站点的容器并连接一个mysql的容器

创建一个mysql容器,然后连接它  

[root@TBEARZ206458 ~]# docker run -d -p 8082:80 -p 443:443 --name dotnet --link mysql centosdotent:1.0.0
74c7ed3616ea2930679a91940a60c111601b448f8cf438334f8b92cadf50cd8e 

设置容器间通信的参数,只需要指定被连接的容器,并不需要指明被连接容器的端口,在创建和启动被连接容器时,也不需要通过-P -p 参数来映射端口。

这就保证了被连接容器的端口只在容器间的通信中使用,不会被暴露在外网中,也不会被其他容器访问到。

用了上面方法的连接的mysql容器,在dotnet容器中只要在使用mysql的时候使用连接的名字例如把Host改成mysql就可以连接mysql服务了。  

 

 

posted @ 2020-03-11 17:36  奋斗的大橙子  阅读(305)  评论(0编辑  收藏  举报