前言:
虽然每个docker容器之间都能通过ip来进行互联,但当容器重新启动,ip就会被重新分配给重新启动的容器,这时同个容器由于重启导致ip不一样了,这时就会导致开发和运维的困难程度大大增加,这时候就要考虑能不能不通过ip互联,而是通过容器的名称或id来实现容器的互联呢?这样的话即使docker容器重启了,我们也能通过固定的容器名称来实现容器互联,而不再是通过变动的ip来实现容器互联。
1、Docker网络基础结构及原理
每启动一个docker容器,docker就会给每个docker容器分配一个ip(通过子网掩码把主机的ip划分成多个子网,把多个子网分配给多个docker容器,所以所有容器和主机都处于同一个网段下),docker安装后就会有一个名为docker0的网桥,docker0的默认网络模式是(bridge)桥接模式,docker容器之间的连接都通过Linux的虚拟网络技术---虚拟网线(veth-pair)来进行连接的,当容器停止或删除,对应的虚拟网线就会被收回。
2、使用参数--link实现docker容器互联(注意!!!docker容器之间能通过ip来进行互联,这里的容器互联是指通过容器id或容器名来进行容器间互联)
(1)普通的docker容器之间使用容器名称互ping,结果是ping不通的
操作过程图:
(2)使用--link参数,让centos03连接centos2
例:
- #选项及解释
- --itd表示容器后台启动
- -P表示随机指定端口
- --name="name"参数用于给容器取名字 ,用来区分容器
- --link表示让centos03链接到centos02
-
- docker run -itd -P --name centos03 --link centos02 centos:7 /bin/bash
让容器centos03 ping centos02能ping通
操作过程图:
反过来让容器centos02 ping centos03结果发现不能ping通
操作过程图:
使用以下命令查看容器的元数据(容器的所有信息)li
docker inspect 容器id或容器名称
例:
docker inspect centos03
使用上述命令后可以在centos03的元数据里查看到关于link的信息并说明了容器centos02和centos03之间存在网络下的关联关系
(3)--link的原理
使用下面命令查看容器的hosts文件
docker exec -it 容器id或容器名称 cat /etc/hosts
例:
docker exec -it centos03 cat /etc/hosts
由下图可知--link能实现容器间通过容器id或容器名称来进行互联的原因是--link通过改变hosts文件来实现容器ip和容器名称、容器id的映射,从而使centos03容器直接ping centos02的容器名时能通过hosts文件映射的方式,直接ping通centos02容器
效果图:
从上述操作得知使用参数--link虽然能实现容器间通过容器id或名称进行互联,但还是有很大的局限性,所以需要使用接下来的自定义网络来实现容器间的互联
3、自定义Docker网络
(1)Docker的网络模式
- #桥接(容器的默认网络模式,不支持通过容器id或容器名称来进行容器互联,虽然能通过使用--link来进行容器互联,但通过--link来实现容器互联不方便)
- bridge
-
- #不配置网络
- none
-
- #和宿主机共享网络
- host
-
- #容器网络互联(局限性很大,使用得少)
- container
(2)指定网络模式来启动容器
例:
而通过--net bridge指定容器的网络模式来启动的容器,该容器的docker0的网络模式就是bridge模式
- #选项及解释
- --itd表示容器后台启动
- -P表示随机指定端口
- --name="name"参数用于给容器取名字 ,用来区分容器
- --net表示使用指定的网络来启动容器
-
- docker run -d -P --name centos01 --net bridge centos:7
效果图:
注意:因为bridge为容器的默认网络模式,所以平常启动容器不指定网络模式时,容器的网络模式会默认使用bridge模式,所以以下两条启动容器的命令是等价的
docker run -d -P --name centos01 centos:7
docker run -d -P --name centos01 --net bridge centos:7
(3)使用以下命令自定义Docker网络
- #选项及解释
- --driver表示指定自定义网络的网络模式(bridge表示网络模式是桥接模式)
- --subnet表示配置子网(/16是子网掩码中网络地址位数(0-32),网络地址位数是16的子网掩码为255.255.0.0,通过子网掩码能配置出65025(255×255)个ip地址)
- --gateway表示设置网关
- mynet表示该自定义网络的名称
-
- docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
效果图:
(4)使用以下命令查看docker的所有网络
docker network ls
效果图:
(5)使用以下命令查看刚刚创建的网络的元数据
docker network inspect 自定义的网络名称
例:
docker network inspect mynet
效果图:
(6)用创建的自定义网络去创建新的docker容器并让容器通过容器名来互ping,发现两容器之间能互相ping通
例:
- #选项及解释
- --itd表示容器后台启动
- -P表示随机指定端口
- --name="name"参数用于给容器取名字 ,用来区分容器
- --net表示使用指定的网络来启动容器
-
- docker run -itd -P --name centos-mynet-01 --net mynet centos:7 /bin/bash
- docker run -itd -P --name centos-mynet-02 --net mynet centos:7 /bin/bash
操作过程图:
(7)再次使用以下命令查看刚刚创建的网络的元数据,发现名为mynet的自定义网络下多出两个容器
docker network inspect 自定义的网络名称
例:
docker network inspect mynet
效果图:
4、网络连通
在实际开发里我们可能会创建不同的集群,例如redis集群和mysql集群,而为了集群的安全和健康的,我们创建集群的时候给集群分配的网段是不同的,但这时候我们希望两个不在同一个网段下的集群间能互相连通,所以需要用到网络连通。
(1)正常情况下两个不同网段之间的容器不能互相ping通,如下图,网段为172.17的容器和网段为192.168的容器之间不能互相ping通
操作过程图:
(2)使用以下命令连通不在同一个网段下的docker容器
docker network connect 网络名称 容器名称
例:
docker network connect mynet centos01
效果图:
(3)再次通过容器名称来互相ping,发现能互相ping通
操作过程图:
(4)使用以下命令查看名为mynet的网络的元数据,发现名为mynet的自定义网络下多出一个名为centos01的容器,也就是说把centos01容器放到了mynet网络下,所以不同网段下能互相连通
创作不易,如果这篇文章对你有帮助,希望能点个赞帮助文章的推广,如果文章有错漏,希望各位能批评指正,谢谢大家。