我们需要将前面的docker-compose仓库停掉
[root@server1 harbor]
一.Docker网络
docker的镜像是令人称道的地方,但网络功能还是相对薄弱的部分。 docker安装后会自动创建3种网络:bridge、host、none
1.桥接网络
安装桥接网络
ip addr show docker0
yum install bridge-utils -y
[root@server1 ~]
运行一个容器查看桥接
root@server1 ~]
[root@server1 ~]
当我们删除掉容器之后,桥接又消失了!
docker rm -f demo
brctl show
2.host网络模式
需要我们指定network host
我们可以看到我们的桥接口上没有出现新的桥接口
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
我们查看端口,可以发现docker运行的镜像nginx占用的是80端口!
[root@server1 ~]
这个时候,我们再运行一个容器起名为demo2,注意观察,启动之后,查看进程有两个进程demo,demo2。但是很快在查看进程,demo2消失了! 再也不会出现。 为什么? 因为加上参数–network host会占用虚拟机的80端口,所以刚开始尝试启动会看到进程,但是会被demo的80端口挤掉demo2!!
[root@server1 ~]
[root@server1 ~]
我们查看日志就知道: docker logs
3.none模式
none模式是指禁用网络功能,只有lo接口,在容器创建时使用! 先删除掉刚才创建的容器,重新运行容器:
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
/
我们发现ip addr的时候:只有lo接口
二.自定义网络
1.创建自定义网桥
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址。
创建网桥!!查看类型为brodge!!
[root@server1 ~]
[root@server1 ~]
测试: 这时我们发现我们是可以ping demo可以直接成功,说明这模式是可以给提供解析的
[root@server1 ~]
[root@server1 ~]
/
/
注意: 我们再开一个nginx,停掉所有的demo,再次开启时,顺序反一下,查看ip变化
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
/
PING demo2 (172.17.0.2):
/
PING demo1 (172.17.0.4):
我们会发现之前的demo1是172.17.0.2,demo2是172.17.0.4, 现在IP地址反过来了! 为什么? 这说明:系统会自动分配ip,按照启动顺序ip单调递增,但是ping名称的时候会自动解析地址!
2.自定义网段
创建时指定参数:–subnet 、–gateway
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
3.手动指定ip
使用–ip参数可以指定容器ip地址,但必须是在自定义网桥上
[root@server1 ~]
demo
[root@server1 ~]
demo2
[root@server1 ~]
[root@server1 ~]
ip addr
[root@server1 ~]
4.双网卡来实现不同网段间通信
桥接到不同网桥上的容器,彼此是不通信的。 如何使两个不同网桥的容器通信呢: 使用 docker network connect命令为demo添加一块mynet1 的网卡。
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
ip addr
[root@server1 ~]
ip addr
docker inspect demo 查看id
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
ip addr
我们可以看到mynet1,mynet2的ip都出现在了里面!说明通信成功!
然后可以直接在容器里面:ping demo成功!
三.Docker容器通信
容器之间除了使用ip通信外,还可以使用容器名称通信。 dns解析功能必须在自定义网络中使用。 在容器创建时使用–network=container:vm1指定。(vm1指定的是运行的容器名)
[root@server1 ~]
/
处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信。 –link 可以用来链接2个容器。 –link的格式: –link **:alias
name是源容器的name,alias是源容器在link下的别名。
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
/
/
我们再次打开一个终端链接server1:
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
我们再一次ping,发现ip变了(由 172.17.02 >>172.17.0.4),但是仍然可以ping名字demo成功!说明它i的名字随着IP实时更新变化的!! 这时我们查看/etc/hosts,发现他已经给我们自动修改了解析
1.内部访问外部
容器内部也是可以访问外部网络的
sysctl -a | grep ip_forward
可以看到路由转发功能是开启的为1 那么我们在容器里面可以ping baidu.com
docker run -it --rm --link demo:web busybox
ping baidu.com
2.外部访问内部
容器如何访问外网是通过iptables的SNAT实现的
外网如何访问容器: 端口映射 -p 选项指定映射端口
[root@server1 ~]
[root@server1 ~]
docker history nginx 看到本身的端口为80
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
[root@server1 ~]
netstat -antlp查看端口发现有docker-proxy
3.原理
外网访问容器用到了docker-proxy和iptables DNAT 宿主机访问本机容器使用的是iptables DNAT 外部主机访问容器或容器之间的访问是docker-proxy实现
测试:
[root@server1 ~]
[root@server1 ~]
都是nginx的发布页面 现在尝试将iptables里面的策略时删除,再次测试
iptables -t nat -D DOCKER 6
已经删掉了策略!
[root@server1 ~]
[root@server1 ~]
发现nginx发布页面还在 但是如果将docker-proxy进程杀掉,再次访问查看效果 已经访问不到了 当我们重新添加iptables策略
[root@server1 ~]
再次在真机上访问curl 172.25.0.1 或者在server1上访问本地localhost 发现又可以访问到nginx的发布页面了!!! 所以总结:docker-proxy,iptables里面的策略至少需要存在一个才可以!!
|