在docker实例中你可以使用现有的容器连接到一个或多个网络,容器也可以使用不通网络驱动的网络。一旦连击了容器就可以使用另外一个容器的ip和主机名进行对外通信。

对于支持多主机的覆盖型或自定义的网络,连接到同一个主机网络但是不同启动主机的容积也可以使用这种方式。

 

下面会创建6个容器,通过这个过程讲解网络使用:

1.创建两个容器container1container2

[root@salt-node1 ~]#
docker run -itd --name=container1 busybox
cafef076b2d4fe587e2441cf801d3c411badd816effe2f0936da6c755e521f27
[root@salt-node1 ~]#
docker run -itd --name=container2 busybox
ed27144379918206669013f13afd5617a87f32778ca1df26daff8ee0edd70e7f

 

2.创建一个隔离的桥接网络test_bridge

[root@salt-node1 ~]#
docker network create -d bridge --subnet 10.6.0.0/16 test_bridge
5ed752ce05ef33d4e326385693eaa0c9cc325b18045fab7727901893dd233c6e

 

3.container2连接到test_bridge,查看网络信息:

通过下面操作可以看到container2获取到了test_bridge指定网段ip地址“10.6.0.2”,现在container1依然连接的默认的网络

[root@salt-node1 ~]#
docker network connect test_bridge container2
[root@salt-node1 ~]#
docker network inspect test_bridge
[
    {
        "Name":
"test_bridge",
        "Id":
"5ed752ce05ef33d4e326385693eaa0c9cc325b18045fab7727901893dd233c6e",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver":
"default",
            "Options": {},
            "Config": [
                {
                    "Subnet":
"10.6.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Containers": {
           
"ed27144379918206669013f13afd5617a87f32778ca1df26daff8ee0edd70e7f":
{
                "Name":
"container2",
                "EndpointID":
"5cfa7576b9fdb66080f81533ade3b8511c6106d3dd12c90a839a6ec8df7f73fd",
                "MacAddress":
"02:42:0a:06:00:02",
                "IPv4Address":
"10.6.0.2/16",
                "IPv6Address":
""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

 

通过下面的信息可以知道,容器2依然在默认的网络里面,所以这里说明docker只是给容器2新建了一个网络到指定的网络里面

[root@salt-node1 ~]#
docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id":
"13b6e04d86a5ec237d3a33946b75ad197f569ae28e793bb4ea967e81cbfe126b",
        "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,
        "Containers": {
           
"cafef076b2d4fe587e2441cf801d3c411badd816effe2f0936da6c755e521f27":
{
                "Name":
"container1",
                "EndpointID":
"8fac97e5cacc4909d0ddf0d341b130acab38341db58c3bf14902dfc097ef8084",
                "MacAddress":
"02:42:ac:11:00:02",
                "IPv4Address":
"172.17.0.2/16",
                "IPv6Address":
""
            },
           
"ed27144379918206669013f13afd5617a87f32778ca1df26daff8ee0edd70e7f":
{
                "Name":
"container2",
                "EndpointID":
"411271ca18bc64d471cdf2fbe43b3c08f4cd487cf380dc7046aeb4403dcb8163",
                "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",
           
"com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

 

4.创建第三个容器,并指定ip10.6.9.3

    只要你的ip在指定网段就可以,你可以使用--ip--ip6来完成ip的指定,这个操作尽量在用户自定义网络用。

因为docker默认生成网络的网络并不固定,一旦docker重启网段很可能发生变化。

[root@salt-node1 ~]# docker run --network=test_bridge --ip=10.6.9.3 -itd --name=container3 busybox

44f5c4429946b81b71ad6e905d486c1a1760401216edbb717fe2f024caecca7b

 

5.查看容器3的网络

因为container3 使用的test_bridge所以看不到默认的桥接网络

[root@salt-node1 ~]#
docker inspect --format=''  container3
………………………
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID":
"ae1da0ceaa8ac1c62104769eb62ffe2c60b001cc21423fc71af573bee27ed11b",
            "HairpinMode": false,
            "LinkLocalIPv6Address":
"",
            "LinkLocalIPv6PrefixLen":
0,
            "Ports": {},
            "SandboxKey":
"/var/run/docker/netns/ae1da0ceaa8a",
            "SecondaryIPAddresses":
null,
            "SecondaryIPv6Addresses":
null,
            "EndpointID":
"",
            "Gateway": "",
            "GlobalIPv6Address":
"",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress":
"",
            "IPPrefixLen": 0,
            "IPv6Gateway":
"",
            "MacAddress":
"",
            "Networks": {
                "test_bridge": {
                    "IPAMConfig": {
                       
"IPv4Address": "10.6.9.3"
                    },
                    "Links": null,
                    "Aliases": [
                       
"44f5c4429946"
                    ],
                    "NetworkID":
"5ed752ce05ef33d4e326385693eaa0c9cc325b18045fab7727901893dd233c6e",
                    "EndpointID":
"24a4655ee32fbe84902a06adba431ab8455c42f4949cc4705cec5b50a75089eb",
                    "Gateway":
"10.6.0.1",
                    "IPAddress":
"10.6.9.3",
                    "IPPrefixLen":
16,
                    "IPv6Gateway":
"",
                   
"GlobalIPv6Address": "",
                   
"GlobalIPv6PrefixLen": 0,
                    "MacAddress":
"02:42:0a:06:09:03"
                }
…………………

 

6.查看容器2的网络

你可以看到两个网络分配的不同ip

[root@salt-node1 ~]#
docker inspect --format=''  container2 |
python -m json.tool
……………….
            "Networks": {
                "bridge": {
                    "Aliases": null,
                    "EndpointID":
"411271ca18bc64d471cdf2fbe43b3c08f4cd487cf380dc7046aeb4403dcb8163",
                    "Gateway":
"172.17.0.1",
                   
"GlobalIPv6Address": "",
                   
"GlobalIPv6PrefixLen": 0,
                    "IPAMConfig":
null,
                    "IPAddress":
"172.17.0.3",
                    "IPPrefixLen":
16,
                    "IPv6Gateway":
"",
                    "Links": null,
                    "MacAddress":
"02:42:ac:11:00:03",
                    "NetworkID":
"13b6e04d86a5ec237d3a33946b75ad197f569ae28e793bb4ea967e81cbfe126b"
                },
                "test_bridge": {
                    "Aliases": [
                       
"ed2714437991"
                    ],
                    "EndpointID":
"5cfa7576b9fdb66080f81533ade3b8511c6106d3dd12c90a839a6ec8df7f73fd",
                    "Gateway":
"10.6.0.1",
                   
"GlobalIPv6Address": "",
                   
"GlobalIPv6PrefixLen": 0,
                    "IPAMConfig": {},
                    "IPAddress":
"10.6.0.2",
                    "IPPrefixLen":
16,
                    "IPv6Gateway":
"",
                    "Links": null,
                    "MacAddress":
"02:42:0a:06:00:02",
                    "NetworkID":
"5ed752ce05ef33d4e326385693eaa0c9cc325b18045fab7727901893dd233c6e"
                }
            },
            "Ports": {},
            "SandboxID":
"2100a213c8e716e91d540157066ada99f9cabf3556bea8aaf343a8a99434b5ce",
            "SandboxKey":
"/var/run/docker/netns/2100a213c8e7",
            "SecondaryIPAddresses":
null,
            "SecondaryIPv6Addresses":
null
        },

………………….

此图是现在三个节点网络状态

运维之我的docker-网络示例_第1张图片

 

 

 

7.进入到容器2内部查看网络状况明显是2块网卡,每块网卡在不同网络分配不同的IP

 

[root@salt-node1
~]#  docker attach container2
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03 
          inet addr:172.17.0.3  Bcast:0.0.0.0 
Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:3/64
Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500 
Metric:1
          RX packets:9 errors:0 dropped:0
overruns:0 frame:0
          TX packets:8 errors:0 dropped:0
overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:718 (718.0 B)  TX bytes:648 (648.0 B)
 
eth1      Link encap:Ethernet  HWaddr 02:42:0A:06:00:02 
          inet addr:10.6.0.2  Bcast:0.0.0.0 
Mask:255.255.0.0
          inet6 addr: fe80::42:aff:fe06:2/64
Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500 
Metric:1
          RX packets:32 errors:0 dropped:0
overruns:0 frame:0
          TX packets:8 errors:0 dropped:0
overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:3306 (3.2 KiB)  TX bytes:648 (648.0 B)
 
lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536 
Metric:1
          RX packets:0 errors:0 dropped:0
overruns:0 frame:0
          TX packets:0 errors:0 dropped:0
overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

 

 

8.现在测试一下docker自带的dns

如果dns正常我们可以使用容器的名称ping,就可以获取容器ip,但是默认网络bridge它不能dns解析,但是

/ # ping -w 4
container3
PING container3
(10.6.9.3): 56 data bytes
64 bytes from
10.6.9.3: seq=0 ttl=64 time=0.151 ms
64 bytes from
10.6.9.3: seq=1 ttl=64 time=0.144 ms
64 bytes from
10.6.9.3: seq=2 ttl=64 time=0.116 ms
64 bytes from
10.6.9.3: seq=3 ttl=64 time=0.102 ms
^C
--- container3 ping
statistics ---
4 packets
transmitted, 4 packets received, 0% packet loss
round-trip
min/avg/max = 0.102/0.128/0.151 ms

 

 

容器container1container2都有默认网络bridgeip可以ping通但是不能dns解析

/ # ping -w 4
container1
ping: bad address
'container1'
 
/ # ping 172.17.0.2
PING 172.17.0.2
(172.17.0.2): 56 data bytes
64 bytes from
172.17.0.2: seq=0 ttl=64 time=0.114 ms
64 bytes from
172.17.0.2: seq=1 ttl=64 time=0.119 ms
64 bytes from
172.17.0.2: seq=2 ttl=64 time=0.087 ms
^C
--- 172.17.0.2 ping
statistics ---
3 packets
transmitted, 3 packets received, 0% packet loss
round-trip
min/avg/max = 0.087/0.106/0.119 ms

 

通过Ctrl+D退出,这时容器自动终止

/ # [root@salt-node1
~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
44f5c4429946        busybox             "sh"                38 minutes ago      Up 38 minutes                           container3
cafef076b2d4        busybox             "sh"                56 minutes ago      Up 56 minutes                           container1

 

使用非用户定义网络link

 

因为默认bridge网络无法解析主机名,所以这也是link唯一值得用到的地方,但是我们更建议你使用自定义网络。

使用传统的link你的容器会获取下面变化

1.能解析容器的nameip地址

2.能定义网络别名是替换网络的另一种方式,实用参数:--link=CONTAINER-NAME:ALIAS实现

3.保证容器的连接安全,独立通道--icc=false

4.环境变量的注入

要重申,当您使用用户自定义的网络时,默认提供所有这些功能,不需要其他配置。 此外您可以动态附加到多个网络和从多个网络分离。

1.使用dns自动解析name

2.支持--link选项为链接的容器提供名称别名

3.为容器在网络中会自动创建隔离的网络

4.环境变量的注入

 

1.下面稍微描述下link用户

 

[root@salt-node1 ~]# docker run --network=test_bridge -itd --name=container4 --link container5:c5 busybox

e738b850f3c12d03f5fecf27e8bfa051f8e5d2c4cdd77f4aaae53cdbb1291453

上面操作你可能不确认有没有创建c5容器可以测试下,发现并没有这个容器

[root@salt-node1 ~]#
docker attach container4
/ # ping container5
ping: bad address
'container5'
/ # ping c5
ping: bad address
'c5'
/ #

 

现在启动container5 容器

[root@salt-node1 ~]#
docker run --network=test_bridge -itd --name=container5 --link container4:c4
busybox
64dd012cf0df4072562d6ff770c6273e8f0142c6aacbf8268af6b2d8d55b3f09

连接到container4里面,才发现之前的link只是给container5 进行了别名的定义

[root@salt-node1 ~]#
docker attach container4
You cannot attach to
a stopped container, start it first
[root@salt-node1 ~]#
docker start container4
container4
[root@salt-node1 ~]#
docker attach container4
/ # ping -w 4 c5
PING c5 (10.6.0.3):
56 data bytes
64 bytes from
10.6.0.3: seq=0 ttl=64 time=0.253 ms
64 bytes from
10.6.0.3: seq=1 ttl=64 time=0.146 ms
64 bytes from
10.6.0.3: seq=2 ttl=64 time=0.143 ms
64 bytes from
10.6.0.3: seq=3 ttl=64 time=0.148 ms
 
--- c5 ping
statistics ---
4 packets
transmitted, 4 packets received, 0% packet loss
round-trip
min/avg/max = 0.143/0.172/0.253 ms
/ # ping -w 2
container5
PING container5
(10.6.0.3): 56 data bytes
64 bytes from
10.6.0.3: seq=0 ttl=64 time=0.212 ms
64 bytes from
10.6.0.3: seq=1 ttl=64 time=0.150 ms
 
--- container5 ping
statistics ---
2 packets
transmitted, 2 packets received, 0% packet loss
round-trip
min/avg/max = 0.150/0.181/0.212 ms

 

 

 

网络变量作用域

 

当你link容器,无论是传统link网络还是用户自定义网络,你指定的任何变量意味着只能在指定区域使用,不能再其它传统网络容器内使用。此外,一个容器属于多个网络,那么你在变量只工作在指定的网络。因此,一个容器可以连接不同变量道不同网络,所有的alias不能工作在同一个网络。

 

下面举例:

1.创建一个桥接网络local_alias

[root@salt-node1 ~]#
docker network create -d bridge --subnet 172.26.0.0/24 local_alias
8e836ae84547ad5b4bb26df276ef3e5de52ea50d6c5a0109d7c9c921a001e493

 

2.container4local_alias网络创建container5的变量名foocontainer5local_alias网络创建container4的变量名bar

[root@salt-node1 ~]#
docker network connect --link container5:foo local_alias container4
[root@salt-node1 ~]#
docker network connect --link container4:bar local_alias container5

 

容器4可以使用foo解析到容器5,容器3却不可以

[root@salt-node1 ~]#
docker attach container4
/ # ping -w 2 foo
PING foo
(172.26.0.3): 56 data bytes
64 bytes from
172.26.0.3: seq=0 ttl=64 time=0.155 ms
64 bytes from
172.26.0.3: seq=1 ttl=64 time=0.151 ms
 
 [root@salt-node1 ~]# docker attach container3
/ # ping -w 2 foo
ping: bad address
'foo

 

 

现在容器5断开test_bridge则不可以连接

[root@salt-node1 ~]#
docker network disconnect test_bridge container5
[root@salt-node1 ~]#
docker attach container4
/ # ping -w 2 c5
ping: bad address
'c5'
/ #
ping -w 2 foo
PING foo
(172.26.0.3): 56 data bytes
64 bytes from
172.26.0.3: seq=2 ttl=64 time=0.147 ms
64 bytes from
172.26.0.3: seq=3 ttl=64 time=0.189 ms
 
--- foo ping
statistics ---
4 packets
transmitted, 4 packets received, 0% packet loss
round-trip
min/avg/max = 0.135/0.162/0.189 ms