Docker容器的网络连接
Docker容器的网络连接
我们用ifconfig
命令来查看网络设备
我们可以看到上面有个叫docker0的网络设备,docker守护进程就是通过docker0为docker的容器提供网络连接的。
那么docker0是什么呢?
- Linux虚拟网桥
那么什么又是网桥?
网桥是数据链路层的一种网络设备,它通过MAC地址(也就是网络设备的物理地址)来对网络进行划分。
但是Linux的虚拟网桥还是有不同的特点:
- 可以设置IP地址
- 相当于拥有一个隐藏的虚拟网卡
Docker0的地址划分:
IP:172.17.42.1
子网掩码:255.255.0.0
MAC:02:42:ac:11:00:00到02:42:ac:11:ff:ff
总共提供了65534个地址
需要查看网桥,我们需要linux中的网桥管理工具
1.[KANO@kelvin ~]$ sudo dnf install bridge-utils
安装完成后,使用
1.[KANO@kelvin ~]$ sudo brctl show
来查看网桥
1.[KANO@kelvin ~]$ sudo brctl show
2.[sudo] KANO 的密码:
3.bridge name bridge id STP enabled interfaces
4.docker0 8000.000000000000 no
5.virbr0 8000.5254008ebbf7 yes virbr0-nic
在docker中新建一个新的容器,然后查看网桥
1.[KANO@kelvin ~]$ docker run -it --name test1 ubuntu /bin/bash
2.Unable to find image 'ubuntu:latest' locally
3.Trying to pull repository docker.io/library/ubuntu ... latest: Pulling from library/ubuntu
4.
5.9377ad319b00: Pull complete
6.9377ad319b00: Download complete
7.a82f81f25750: Download complete
8.b207c06aba70: Download complete
9.d55e68e6cc9c: Download complete
10.Status: Downloaded newer image for docker.io/ubuntu:latest
11.
12.root@5daca1f236f8:/# ifconfig
13.eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:01
14. inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
15. inet6 addr: fe80::42:acff:fe11:1/64 Scope:Link
16. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
17. RX packets:25 errors:0 dropped:0 overruns:0 frame:0
18. TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
19. collisions:0 txqueuelen:0
20. RX bytes:3734 (3.7 KB) TX bytes:648 (648.0 B)
21.
22.lo Link encap:Local Loopback
23. inet addr:127.0.0.1 Mask:255.0.0.0
24. inet6 addr: ::1/128 Scope:Host
25. UP LOOPBACK RUNNING MTU:65536 Metric:1
26. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
27. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
28. collisions:0 txqueuelen:0
29. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
30.
31.[KANO@kelvin ~]$ sudo brctl show
32.[sudo] KANO 的密码:
33.bridge name bridge id STP enabled interfaces
34.docker0 8000.0eaba27155c6 no veth60c9e4f
35.virbr0 8000.5254008ebbf7 yes virbr0-nic
36.[KANO@kelvin ~]$
自定义docker0
修改docker0地址:
1.sudo ifconfig docker0 192.168.200.1 netmask 255.255.255.0
自定义虚拟网桥
- 添加虚拟网桥
1.sudo brctl addbr br0
2.sudo ifconfig br0 192.168.100.1 netmask 255.255.255.0
- 更改docker守护进程的启动配置
/etc/default/docker 中添加DOCKER_OPS值-b=br0
Docker容器的互联
环境准备
用于测试的Docker镜像文件Dockerfile:
1.FROM ubuntu:14.04
2.RUN apt-get install -y ping
3.RUN apt-get update
4.RUN apt-get install -y nginx
5.RUN apt-get install -y curl
6.EXPOSE 80
7.CMD /bin/bash
用来创建一个新镜像文件
1.[KANO@kelvin cct]$ docker build -t cct .
2.Sending build context to Docker daemon 2.048 kB
3.Step 0 : FROM ubuntu:14.04
4. ---> d55e68e6cc9c
5.Step 1 : RUN apt-get install -y ping
6. ---> Using cache
7. ---> 9e3403835f14
8.Step 2 : RUN apt-get update
9. ---> Using cache
10. ---> a106b2980907
11.Step 3 : RUN apt-get install -y nginx
12. ---> Using cache
13. ---> 3bef71e3de8b
14.Step 4 : RUN apt-get install -y curl
15. ---> Using cache
16. ---> c415feb9c1f6
17.Step 5 : EXPOSE 80
18. ---> Using cache
19. ---> f807cd227da3
20.Step 6 : CMD /bin/bash
21. ---> Using cache
22. ---> d2837534e0ae
23.Successfully built d2837534e0ae
24.
由于之前已经创建过了,这里就没有显示新的构建过程
允许所有容器间互联
关键选项:--icc=true
默认
创建两个容器
1.[KANO@kelvin cct]$ docker run -it --name cct1 cct
2.root@11e66ba81881:/# nginx
3.root@11e66ba81881:/# [KANO@kelvin cct]$
4.[KANO@kelvin cct]$ docker run -it --name cct2 cct
5.root@80db1bdfb2ad:/#
然后用cct2与cct1进行互联
查看cct2的ip地址
1.root@80db1bdfb2ad:/# ifconfig
2.eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:08
3. inet addr:172.17.0.8 Bcast:0.0.0.0 Mask:255.255.0.0
4. inet6 addr: fe80::42:acff:fe11:8/64 Scope:Link
5. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
6. RX packets:8 errors:0 dropped:0 overruns:0 frame:0
7. TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
8. collisions:0 txqueuelen:0
9. RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)
10.
11.lo Link encap:Local Loopback
12. inet addr:127.0.0.1 Mask:255.0.0.0
13. inet6 addr: ::1/128 Scope:Host
14. UP LOOPBACK RUNNING MTU:65536 Metric:1
15. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
16. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
17. collisions:0 txqueuelen:0
18. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
19.
20.root@80db1bdfb2ad:/# [KANO@kelvin cct]$
Ctrl+P & Ctrl+Q退出容器
进入cct1查看其IP
1.[KANO@kelvin cct]$ docker attach cct1
2.
3.root@11e66ba81881:/# ifconfig
4.eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:07
5. inet addr:172.17.0.7 Bcast:0.0.0.0 Mask:255.255.0.0
6. inet6 addr: fe80::42:acff:fe11:7/64 Scope:Link
7. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
8. RX packets:16 errors:0 dropped:0 overruns:0 frame:0
9. TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
10. collisions:0 txqueuelen:0
11. RX bytes:1296 (1.2 KB) TX bytes:648 (648.0 B)
12.
13.lo Link encap:Local Loopback
14. inet addr:127.0.0.1 Mask:255.0.0.0
15. inet6 addr: ::1/128 Scope:Host
16. UP LOOPBACK RUNNING MTU:65536 Metric:1
17. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
18. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
19. collisions:0 txqueuelen:0
20. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
21.
使用ping来查看cct1与cct2是否能连接
1.root@11e66ba81881:/# ping 172.17.0.8 -c 4
2.PING 172.17.0.8 (172.17.0.8) 56(84) bytes of data.
3.64 bytes from 172.17.0.8: icmp_seq=1 ttl=64 time=0.126 ms
4.64 bytes from 172.17.0.8: icmp_seq=2 ttl=64 time=0.074 ms
5.64 bytes from 172.17.0.8: icmp_seq=3 ttl=64 time=0.085 ms
6.64 bytes from 172.17.0.8: icmp_seq=4 ttl=64 time=0.083 ms
7.
8.--- 172.17.0.8 ping statistics ---
9.4 packets transmitted, 4 received, 0% packet loss, time 2999ms
10.rtt min/avg/max/mdev = 0.074/0.092/0.126/0.020 ms
11.
可以看出cct1能ping通cct2
再进入cct2,查看cct1上nginx提供的服务
1.[KANO@kelvin cct]$ docker attach cct2
2.
3.root@80db1bdfb2ad:/# curl http://172.17.0.7
4.<!DOCTYPE html>
5.<html>
6.<head>
7.<title>Welcome to nginx!</title>
8.<style>
9. body {
10. width: 35em;
11. margin: 0 auto;
12. font-family: Tahoma, Verdana, Arial, sans-serif;
13. }
14.</style>
15.</head>
16.<body>
17.<h1>Welcome to nginx!</h1>
18.<p>If you see this page, the nginx web server is successfully installed and
19.working. Further configuration is required.</p>
20.
21.<p>For online documentation and support please refer to
22.<a href="http://nginx.org/">nginx.org</a>.<br/>
23.Commercial support is available at
24.<a href="http://nginx.com/">nginx.com</a>.</p>
25.
26.<p><em>Thank you for using nginx.</em></p>
27.</body>
28.</html>
29.root@80db1bdfb2ad:/#
30.
可以看到服务可以正常访问,也就是说在默认情况下docker并没有限制容器间的相互访问
下面停止cct1,并且再启动
1.[KANO@kelvin cct]$ docker stop cct1
2.
3.cct1
4.
5.[KANO@kelvin cct]$ docker restart cct1
6.cct1
7.[KANO@kelvin cct]$ docker attach cct1
8.root@11e66ba81881:/#
9.root@11e66ba81881:/# ifconfig
10.eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:09
11. inet addr:172.17.0.9 Bcast:0.0.0.0 Mask:255.255.0.0
12. inet6 addr: fe80::42:acff:fe11:9/64 Scope:Link
13. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
14. RX packets:8 errors:0 dropped:0 overruns:0 frame:0
15. TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
16. collisions:0 txqueuelen:0
17. RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)
18.
19.lo Link encap:Local Loopback
20. inet addr:127.0.0.1 Mask:255.0.0.0
21. inet6 addr: ::1/128 Scope:Host
22. UP LOOPBACK RUNNING MTU:65536 Metric:1
23. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
24. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
25. collisions:0 txqueuelen:0
26. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
27.
可以看到我们停止一个容器并且再启动时,它的ip地址会发生变化。这也说明容器的IP地址是个不可靠的服务,它会在容器重启时发生变化。对于这点,docker也提供了另外的一种方式。
这就是在容器启动时的link选项
1.--link
2. docker run --link=[CONTAINER_NAME]:[ALIAS] [IMAGE] [COMMOND]
譬如:
1.[KANO@kelvin cct]$ docker run -it --name cct3 --link=cct1:webtest cct
2.root@f326b86b2059:/# ping webtest
3.PING webtest (172.17.0.9) 56(84) bytes of data.
4.64 bytes from webtest (172.17.0.9): icmp_seq=1 ttl=64 time=0.100 ms
5.64 bytes from webtest (172.17.0.9): icmp_seq=2 ttl=64 time=0.049 ms
6.64 bytes from webtest (172.17.0.9): icmp_seq=3 ttl=64 time=0.072 ms
7.64 bytes from webtest (172.17.0.9): icmp_seq=4 ttl=64 time=0.056 ms
8.64 bytes from webtest (172.17.0.9): icmp_seq=5 ttl=64 time=0.067 ms
9.64 bytes from webtest (172.17.0.9): icmp_seq=6 ttl=64 time=0.063 ms
10.64 bytes from webtest (172.17.0.9): icmp_seq=7 ttl=64 time=0.109 ms
11.64 bytes from webtest (172.17.0.9): icmp_seq=8 ttl=64 time=0.055 ms
12.64 bytes from webtest (172.17.0.9): icmp_seq=9 ttl=64 time=0.073 ms
13.64 bytes from webtest (172.17.0.9): icmp_seq=10 ttl=64 time=0.079 ms
14.64 bytes from webtest (172.17.0.9): icmp_seq=11 ttl=64 time=0.053 ms
15.^C
16.--- webtest ping statistics ---
17.11 packets transmitted, 11 received, 0% packet loss, time 9999ms
18.rtt min/avg/max/mdev = 0.049/0.070/0.109/0.020 ms
19.
可以通过别名连通到cct1上
查看/etc/hosts
可以看见这里添加了webtest的地址映射
重启一下
1.[KANO@kelvin ~]$ sudo service docker restart
2.[sudo] KANO 的密码:
3.Redirecting to /bin/systemctl restart docker.service
4.[KANO@kelvin ~]$ docker ps
5.CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6.[KANO@kelvin ~]$ docker restart cct1 cct2 cct3
7.cct1
8.cct2
9.cct3
10.[KANO@kelvin ~]$ docker attach cct3
11.root@f326b86b2059:/#
12.root@f326b86b2059:/# ping webtest
13.PING webtest (172.17.0.1) 56(84) bytes of data.
14.64 bytes from webtest (172.17.0.1): icmp_seq=1 ttl=64 time=0.087 ms
15.64 bytes from webtest (172.17.0.1): icmp_seq=2 ttl=64 time=0.077 ms
16.64 bytes from webtest (172.17.0.1): icmp_seq=3 ttl=64 time=0.055 ms
17.64 bytes from webtest (172.17.0.1): icmp_seq=4 ttl=64 time=0.110 ms
18.^C
19.--- webtest ping statistics ---
20.4 packets transmitted, 4 received, 0% packet loss, time 2999ms
21.rtt min/avg/max/mdev = 0.055/0.082/0.110/0.020 ms
22.
仍然能ping通
再查看/etc/hosts
1.[KANO@kelvin ~]$ docker attach cct3
2.root@f326b86b2059:/#
3.root@f326b86b2059:/# ping webtest
4.PING webtest (172.17.0.1) 56(84) bytes of data.
5.64 bytes from webtest (172.17.0.1): icmp_seq=1 ttl=64 time=0.087 ms
6.64 bytes from webtest (172.17.0.1): icmp_seq=2 ttl=64 time=0.077 ms
7.64 bytes from webtest (172.17.0.1): icmp_seq=3 ttl=64 time=0.055 ms
8.64 bytes from webtest (172.17.0.1): icmp_seq=4 ttl=64 time=0.110 ms
9.^C
10.--- webtest ping statistics ---
11.4 packets transmitted, 4 received, 0% packet loss, time 2999ms
12.rtt min/avg/max/mdev = 0.055/0.082/0.110/0.020 ms
13.
可以看到这三个容器的IP地址已经重新分配,但是webtest所对应的ip地址也自动修改了
拒绝所有容器间的互联
Docker守护进程的启动选项 --icc=false
修改docker启动进程的选项 sudo vim /etc/default/docker
在末尾加上DOCKER_OPTS="--icc=false"
这样就不能ping通了
允许特定容器间的连接
Docker守护进程的启动选项:
1.--icc=false
2.--iptables=true
3.--link
Docker容器与外部网络连接
ip_forward
ip_forward是linux系统中一个变量,它的值决定了是否会转发流量
docker中默认--ip-forward=true
,也就是在启动时将其设置为1,允许流量转发
这个时候也可以使用系统自带的工具,查看流量转发是否开启
1.sysctl net.ipv4.conf.all.forwarding
譬如
1.[KANO@kelvin ~]$ sudo sysctl net.ipv4.conf.all.forwarding
2.[sudo] KANO 的密码:
3.net.ipv4.conf.all.forwarding = 1
iptables
什么是iptables?
iptables是与linux内核集成的包过滤防火墙系统,几乎所有的linux发行版本都会包含iptables的功能。
其中几个关键点:
- 表(table)
- 链(chain)
- 规则(rule)
ACCEPT 、REJECT、DROP
filter表中包含的链:
- INPUT
- FORWARD
- OUTPUT
如:这里也可以省略filter,因为iptables参数默认为filter表
1.[KANO@kelvin ~]$ docker run -it -p 80 --name cct5 cct
2.root@ad64bce234aa:/# nginx
3.
4.[KANO@kelvin ~]$ sudo iptables -t filter -L -n
5.[sudo] KANO 的密码:
6.Chain INPUT (policy ACCEPT)
7.target prot opt source destination
8.ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
9.ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
10.ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:67
11.ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
12.
13.Chain FORWARD (policy ACCEPT)
14.target prot opt source destination
15.DOCKER all -- 0.0.0.0/0 0.0.0.0/0
16.ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
17.ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
18.ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
19.ACCEPT all -- 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
20.ACCEPT all -- 192.168.122.0/24 0.0.0.0/0
21.ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
22.REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
23.REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
24.
25.Chain OUTPUT (policy ACCEPT)
26.target prot opt source destination
27.ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:68
28.
29.Chain DOCKER (1 references)
30.target prot opt source destination
31.ACCEPT tcp -- 0.0.0.0/0 172.17.0.1 tcp dpt:80
32.
33.[KANO@kelvin ~]$ docker port cct5
34.80/tcp -> 0.0.0.0:32768
35.[KANO@kelvin ~]$ curl http://127.0.0.1:32768
36.<!DOCTYPE html>
37.<html>
38.<head>
39.<title>Welcome to nginx!</title>
40.<style>
41. body {
42. width: 35em;
43. margin: 0 auto;
44. font-family: Tahoma, Verdana, Arial, sans-serif;
45. }
46.</style>
47.</head>
48.<body>
49.<h1>Welcome to nginx!</h1>
50.<p>If you see this page, the nginx web server is successfully installed and
51.working. Further configuration is required.</p>
52.
53.<p>For online documentation and support please refer to
54.<a href="http://nginx.org/">nginx.org</a>.<br/>
55.Commercial support is available at
56.<a href="http://nginx.com/">nginx.com</a>.</p>
57.
58.<p><em>Thank you for using nginx.</em></p>
59.</body>
60.</html>
61.
62.
若想阻止特定IP特定容器的访问
1.sudo iptables -I DOCKER -s 10.211.55.2 -d 172.17.0.7 -p TCP --dport 80 j DROP