Dcocker网络-现象

容器与宿主机的网络隔离

首先我们创建一个容器,然后进入此容器查询容器的网关,然后退出口查看宿主机的网关,查看可以发现它们是完全不一样的,由此可见容器的Network Namespace与宿主机是隔离开的,演示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 1.启动容器
jjw@jjw-PC:~$ docker run -d --name demo01 jjw-story/flask-hello-world
645a63e0a07637efcd5fe85813d30eb5d92b4533b7c7a1458d2c4db5d6142cda

# 2.进入容器查看网关
jjw@jjw-PC:~$ docker exec -it demo01 /bin/bash
root@645a63e0a076:/app# ip a
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
5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever

# 3.查看宿主机网关
jw@jjw-PC:~$ ip a
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: enp2s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether d8:d0:90:00:dd:94 brd ff:ff:ff:ff:ff:ff
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 48:5f:99:ce:dc:3b brd ff:ff:ff:ff:ff:ff
inet 192.168.1.9/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp3s0
valid_lft 603108sec preferred_lft 603108sec
inet6 2409:8a00:78ce:bb0:eaf5:3d9b:3a9d:dfd0/64 scope global dynamic noprefixroute
valid_lft 259159sec preferred_lft 172759sec
inet6 fe80::d29c:f72a:7c51:83cc/64 scope link noprefixroute
valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ca:69:08:5a 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:caff:fe69:85a/64 scope link
valid_lft forever preferred_lft forever
6: veth531bf01@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether ae:ba:05:48:45:07 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::acba:5ff:fe48:4507/64 scope link
valid_lft forever preferred_lft forever

容器与容器之间网络是互通的

我们创建第二个容器,然后进入第二个容器查看网关,发现与第一个容器是不一样的,然后我们在第二个容器中ping第一个容器的ip,发现是可以ping通的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 1.创建第二个容器
jjw@jjw-PC:~$ docker run -d --name demo02 jjw-story/flask-hello-world
f6606faba1d160e78e4fb1accadadbb4cf61df5feddeabc1b3ef0d25f229fa3d

# 2.进入容器查看第二个容器的网管
jjw@jjw-PC:~$ docker exec -it demo02 /bin/bash
root@f6606faba1d1:/app# ip a
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
7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever


# 3.ping第一个容器的ip地址
root@f6606faba1d1:/app# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.169 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.111 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.106 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.103 ms
^C
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 73ms
rtt min/avg/max/mdev = 0.103/0.122/0.169/0.028 ms

下面一节我们讲述一下原理

Namespace-网络命名空间

我们通过在Linux上创建一个可用的Network Namespace来说明它的原理

  • 查看当前机器的Network Namespace: sudo ip netns list

  • 删除指定的Network Namespace: sudo ip netns delete [namespace名称]

  • 创建Network Namespace: sudo ip netns add [namespace名称]

  • 查看Network Namespace的网关及ip地址:sudo ip netns exec [namespace名称] ip a

  • 查询各个网口当前的状态: ip link,注意 DOWN表示未启动,UP表示正在与运行,UNKNOWN表示未知

  • 修改指定网口的状态: sudo ip netns exec [namespace名称] ip link set dev [网口名称] up

  • l0:每次我们查询网关的时候都会发现有这样的一个网关,它代表的是localback0,本地回环口

  • 我们的网口需要UP起来,它必须是要与另外一个网口成为一对的,也就是说它必须是要两端直连起来的,也就是单个端口是没有办法UP起来的,这个是硬性限制,网络的基础知识,需要注意

创建自己的网口并且是UP状态示例

  1. 添加自定义的Namespace,然后查询此Namespace中网口的ip和状态
1
2
3
4
5
6
7
jjw@jjw-PC:~$ sudo ip netns add test1
jjw@jjw-PC:~$ sudo ip netns list
test1

jjw@jjw-PC:~$ sudo ip netns exec test1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

我们发现此网口没有IP地址,并且状态是DOWN

  1. 修改此网口的状态为UP,并查看修改结果
1
2
3
4
jjw@jjw-PC:~$ sudo ip netns exec test1 ip link set dev lo up
jjw@jjw-PC:~$ sudo ip netns exec test1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

我们发现这里设置为UP之后,它并不是直接成为UP状态,而是成为了UNKNOWN状态,这是因为我们此端口并没有与另外一个端口成为一对并且直连,所以它并不会UP起来

  1. 我们创建一对相互配对的网口(为了创建出一个UP的端口)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
jw@jjw-PC:~$ sudo ip link add veth-test1 type veth peer name veth-test2
jjw@jjw-PC:~$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp2s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000
link/ether d8:d0:90:00:dd:94 brd ff:ff:ff:ff:ff:ff
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
link/ether 48:5f:99:ce:dc:3b brd ff:ff:ff:ff:ff:ff
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:ca:69:08:5a brd ff:ff:ff:ff:ff:ff
6: veth531bf01@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether ae:ba:05:48:45:07 brd ff:ff:ff:ff:ff:ff link-netnsid 0
8: veth973fc89@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether f6:6d:60:62:80:cf brd ff:ff:ff:ff:ff:ff link-netnsid 1
9: veth-test2@veth-test1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 62:55:74:b2:2f:11 brd ff:ff:ff:ff:ff:ff
10: veth-test1@veth-test2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 22:c8:a4:b3:f4:b2 brd ff:ff:ff:ff:ff:ff

创建后我们发现我们已经创建成功,并且他们的名称都是 veth-test2@veth-test1 和 veth-test1@veth-test2,它们有mac地址,但是没有ip地址,状态都为DOWN

  1. 将我们创建的网口添加到我们之前创建的Namespace中
1
2
3
4
5
6
jjw@jjw-PC:~$ sudo ip link set veth-test1 netns test1
jjw@jjw-PC:~$ sudo ip netns exec test1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
10: veth-test1@if9: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 22:c8:a4:b3:f4:b2 brd ff:ff:ff:ff:ff:ff link-netnsid 0

我们发现我们新创建的网口已经被添加到我们之前创建的Namespace中了

  1. 同理我们创建test2的Namespace,然后将veth-test2这个网口添加到test2这个Namespace中
1
2
3
4
5
6
7
8
9
10
jjw@jjw-PC:~$ sudo ip netns add test2
jjw@jjw-PC:~$ sudo ip netns list
test2
test1 (id: 2)
jjw@jjw-PC:~$ sudo ip link set veth-test2 netns test2
jjw@jjw-PC:~$ sudo ip netns exec test2 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
9: veth-test2@if10: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 62:55:74:b2:2f:11 brd ff:ff:ff:ff:ff:ff link-netns test1
  1. 查看本机的ip link,我们发现已经没有了刚才的veth-test2@veth-test1 和 veth-test1@veth-test2,说明我们已经将此两个端口放到了我们创建的两个Namespace中

  2. 给我们刚刚创建的两个Namespace的端口分配IP地址

1
2
jjw@jjw-PC:~$ sudo ip netns exec test1 ip addr add 192.168.1.1/24 dev veth-test1
jjw@jjw-PC:~$ sudo ip netns exec test2 ip addr add 192.168.1.2/24 dev veth-test2
  1. 这时如果我们去查看这两个Namespace的ip和状态,发现我们的网口还是没有ip地址,并且状态还是DOWN,这时我们需要设置将这两个网口启动起来
1
2
jjw@jjw-PC:~$ sudo ip netns exec test1 ip link set dev veth-test1 up
jjw@jjw-PC:~$ sudo ip netns exec test2 ip link set dev veth-test2 up
  1. 这时我们再去查看这两个Namespace中的新创建网口状态和IP发现就都是正常的了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
jjw@jjw-PC:~$ sudo ip netns exec test1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: veth-test1@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 16:af:b8:ee:76:02 brd ff:ff:ff:ff:ff:ff link-netns test2
inet 192.168.1.1/24 scope global veth-test1
valid_lft forever preferred_lft forever
inet6 fe80::14af:b8ff:feee:7602/64 scope link
valid_lft forever preferred_lft forever
jjw@jjw-PC:~$ sudo ip netns exec test1 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: veth-test1@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 16:af:b8:ee:76:02 brd ff:ff:ff:ff:ff:ff link-netns test2

jjw@jjw-PC:~$ sudo ip netns exec test2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
11: veth-test2@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 36:f9:03:cb:ef:e1 brd ff:ff:ff:ff:ff:ff link-netns test1
inet 192.168.1.2/24 scope global veth-test2
valid_lft forever preferred_lft forever
inet6 fe80::34f9:3ff:fecb:efe1/64 scope link
valid_lft forever preferred_lft forever
jjw@jjw-PC:~$ sudo ip netns exec test2 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
11: veth-test2@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 36:f9:03:cb:ef:e1 brd ff:ff:ff:ff:ff:ff link-netns test1

现在我们就终于创建好了我们自己的正常的Namespace和互联互通的网口,我们就可以在其中一个Namespace中去ping另外一个Namespace的这个网口,发现就可以通了

  1. 互相ping IP地址
1
2
3
4
5
6
7
8
9
jjw@jjw-PC:~$ sudo ip netns exec test1 ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.031 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.058 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.058 ms
^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 49ms
rtt min/avg/max/mdev = 0.031/0.049/0.058/0.012 ms

综上就是我们Namespace的使用方法及具体作用,如第一节中我们所示,Docker创建的容器他们之间ip能互通,基本使用的就是此原理,与我们的示例原理是一致的

Docker Bridge

Docker的默认网络,上述我们发现在创建容器后发现容器之间ip是互通的,并且在容器内部是可以ping通外部网络的,并且在我们每次启动一个容器,就会在宿主机器上多出一个网口,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 1.查询原本宿主机网口
jw@jjw-PC:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
...
2: enp2s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
...
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
...
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
...

# 2.启动一个容器
jjw@jjw-PC:~$ docker start demo01
demo01

# 3.查看现在宿主机网口
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
...
2: enp2s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
...
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
...
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:5b:44:0a:01 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:5bff:fe44:a01/64 scope link
valid_lft forever preferred_lft forever
8: veth54021aa@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 72:40:50:33:72:99 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::7040:50ff:fe33:7299/64 scope link
valid_lft forever preferred_lft forever

我们发现在上述启动一个容器后,宿主机新添加了一个网口veth54021aa@if7,并且它是与docker0网口相关联的,我们说这个新的网口就是第一节示例中的Network Namespace的一对peer,它们链接了容器的ip和docker0,docker0网口就是我们说的 Docker Bridge

我们没创建一个容器,它都会创建这样的一个peer,然后与docker0相关联,这就是容器之间ip是互通的原理,也是容器内访问外网的原因

Docker Bridge是Docker网络最重要的部分

容器之间的link

–link的使用

本章注意下面命令:

  • docker network ls: 查看docker上存在的所有Network Namespace

  • docker network create -d bridge [自定义bridge名称]: 创建自定义bridge

  • docker network connect [自定义bridge名称] [容器名称]: 将容器链接到自定义bridge

  • docker network inspect [bridge ID]:查看bridge的具体信息,ID通过上述 ls 命令查看

前面我们说过,容器之间的网络是互通的,但是很多时候我们容器之间需要链接,但是我们并不知道另一方容器的ip地址,比如一个服务容器需要链接一个数据库容器,这时候我们就可以利用docker的link,我们可以不通过ip地址而是通过容器名称来进行链接

下面我们通过link使用示例来说明,我们创建两个容器,然后用第二个容器link到第一个容器,然后ping第一个容器的名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1.创建第一个容器
jjw@jjw-PC:~$ docker run -d --name test1 jjw-story/flask-hello-world
968f4e9fafe3fb2662e457515010c3cfedd57dc91d89839d7d091de753ef7e4a

# 2.创建第二个容器并链接到第一个容器(使用 --link 参数)
jjw@jjw-PC:~$ docker run -d --name test2 --link test1 jjw-story/flask-hello-world
ec56c76cc2e38daca937672582d9451758d98566f510d2d7212ec4a9ea8eea4f

# 3.进入第二个容器通过ping第一个容器的名称
jjw@jjw-PC:~$ docker exec -it test2 /bin/bash
root@ec56c76cc2e3:/app# ping test1
PING test1 (172.17.0.2) 56(84) bytes of data.
64 bytes from test1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.234 ms
64 bytes from test1 (172.17.0.2): icmp_seq=2 ttl=64 time=0.105 ms
64 bytes from test1 (172.17.0.2): icmp_seq=3 ttl=64 time=0.104 ms
^C
--- test1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 52ms
rtt min/avg/max/mdev = 0.104/0.147/0.234/0.062 ms

# 4.进入第一个容器ping第二个容器的名称,我们发现是ping不通的,因为我们创建test1容器并没有link test2这个容器
jjw@jjw-PC:~$ docker exec -it test1 /bin/bash
root@968f4e9fafe3:/app# ping test2
ping: test2: Temporary failure in name resolution

以上示例就是link的使用方法,生产中我们链接数据库时就可以通过数据库容器名称:3601来直接访问数据库服务。

创建自己的bridge

我们发现link是单向的,必须在创建容器时就指定好,不然是ping不通的,所以正式用的时候我们很少使用这种方式,而是使用第二种方式,创建自定义的bridge,将容器链接到此bridge上,这两链接的多个容器就都是互通的,可以通过容器名称互访

一般我们创建容器会链接到Docker的默认的bridge,我们也可以在创建容器时指定链接的bridge,或者在容器运行时添加链接到新的bridge,每个容器都可以链接多个bridge

以下我们通过示例创建一个自定义bridge,然后将服务挂载实现服务间名称访问网络互通

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# 1.创建自定义的bridge
jjw@jjw-PC:~$ docker network create -d bridge my-bridge
714b9b2f827ee434b7ecbc08ad792d34cf9e298e2cbc42339d697317087bf157
jjw@jjw-PC:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
413d667b89f6 bridge bridge local
cfcb7ba38694 host host local
714b9b2f827e my-bridge bridge local
7a8a158e3c19 none null local

# 2.创建第三个容器,指定链接到此自定义的bridge
jjw@jjw-PC:~$ docker run -d --name test3 --network my-bridge jjw-story/flask-hello-world
811ddcb7a6fbff14f3c18e7f09d93df9df23c90c4b1f162a4bd0e3d182619aa0

# 3.将之前已经存在的容器test2链接到此自定义的bridge上
jjw@jjw-PC:~$ docker network connect my-bridge test2

# 4.查看此自定义bridge信息,发现此自定义bridge上挂载了两个容器
jjw@jjw-PC:~$ docker network inspect 714b9b2f827e
[
{
"Name": "my-bridge",
"Id": "714b9b2f827ee434b7ecbc08ad792d34cf9e298e2cbc42339d697317087bf157",
...
"Containers": {
"811ddcb7a6fbff14f3c18e7f09d93df9df23c90c4b1f162a4bd0e3d182619aa0": {
"Name": "test3",
"EndpointID": "3dabecb55602d042563ac700343ac06a6f5221fa713caa521ff3eb75460b1aa7",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"ec56c76cc2e38daca937672582d9451758d98566f510d2d7212ec4a9ea8eea4f": {
"Name": "test2",
"EndpointID": "1e9dcad5b2f800d440a53f39fe809e671b5bfbe72f46820bbe9ad51daa12fe32",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
}
...
}
]

# 5.分别进入两个容器,互相ping test2 和 test3,我们发现是可以通的
jjw@jjw-PC:~$ docker exec -it test2 /bin/bash
root@ec56c76cc2e3:/app# ping test3
PING test3 (172.18.0.2) 56(84) bytes of data.
64 bytes from test3.my-bridge (172.18.0.2): icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from test3.my-bridge (172.18.0.2): icmp_seq=2 ttl=64 time=0.112 ms
^C
--- test3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3ms
rtt min/avg/max/mdev = 0.056/0.084/0.112/0.028 ms
root@ec56c76cc2e3:/app# exit
exit


jjw@jjw-PC:~$ docker exec -it test3 /bin/bash
root@811ddcb7a6fb:/app# ping test2
PING test2 (172.18.0.3) 56(84) bytes of data.
64 bytes from test2.my-bridge (172.18.0.3): icmp_seq=1 ttl=64 time=0.040 ms
64 bytes from test2.my-bridge (172.18.0.3): icmp_seq=2 ttl=64 time=0.132 ms
^C
--- test2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3ms
rtt min/avg/max/mdev = 0.040/0.086/0.132/0.046 ms

# 6. ping test1 我们发现是不通的,因为我们test1没有加入自定义的bradge
root@811ddcb7a6fb:/app# ping test1
ping: test1: Temporary failure in name resolution

由此我们可以发现,我们没创建一个容器,它都会加入默认的bridge,这是容器之间虽然通过ip是互通的,但是不能通过容器名称互通访问网络
但是我们通过创建自己的bridge,然后将两个或多个容器加入此bridge,容器之间就可以通过名称网络互通(注意默认bridge和自定义bridge的区别)

Docker容器的端口映射

注意:本章内容是一个重点

通常我们创建的Docker容器,需要对外提供服务时,我们需要将容器的ip地址和端口暴露出去,但是我们容器的ip和端口都只能在宿主机上访问,不能被外界访问,只有宿主机关联的公网ip才可以被外网访问,这个时候我们就需要将容器的端口映射到宿主机的ip端口,这时我们通过访问宿主机的ip加我们映射好的端口,就可以访问到我们Docker容器内部的服务

具体命令如下:

docker run -d -p [容器服务端口]:[宿主机需要被映射的端口] –name [容器的名称] [image名称]

使用示例如下:docker run -d -p 80:80 –name nignxweb nginx

这样,我们访问宿主机的ip加80端口,就可以映射到容器内部的80端口,从而访问服务

Docker host和none Network Namespace

上面我们通过命令docker network ls查看docker的网络命名空间,发现有三个,bridge是默认链接的,host和none没有介绍,下面我们介绍这两种命名空间

none命名空间

这个命名空间很少使用,因为此命名空间是非常孤立的,它不跟外界任何网络有联通,所以它的应用场景很局限,我们可以创建一个容器然后挂在到此命名空间上观察一下,它一般就是我们的容器非常机密,里面保存了各种密码必须只能进入容器内部才能查看这些信息,这种场景比较适合使用此none网络命名空间

host命名空间

此命名空间我们可以创建一个容器然后关联到此命名空间,然后进入容器内部使用ip a查看网口信息,发现与宿主机上查看的信息一模一样,也就是说它是直接关联宿主机的网络命名空间,host使用也非常少,因为我们容器这样关联的话,Network Namespace就和宿主机的没有隔离,容易出现端口冲突等问题

最后更新: 2020年05月23日 19:49

原始链接: https://jjw-story.github.io/2020/05/13/Docker-Network/

× 请我吃糖~
打赏二维码