我们都知道docker容器之间是互相隔离的,不能互相访问,但如果有些依赖关系的服务要怎么办呢。下面介绍三种方法解决容器互访问题。
虚拟ip访问
- 安装docker时,docker会默认创建一个内部的桥接网络docker0,每创建一个容器分配一个虚拟网卡,容器之间可以根据ip互相访问。
- 运行两个容器,并且进入容器查看相应的IP,这种方式必须知道每个容器的ip,在实际使用中并不实用。
link
- 运行两个容器,运行时通过link关联
docker run -d -P --name tomcat01 leoiceo/centos7-tomcat
docker run -d -P --name tomcat04 --link tomcat03 leoiceo/centos7-tomcat
- 测试网络连通性
tomcat04
-->tomcat03
[root@centos72 ~]# docker exec -it tomcat04 ping tomcat03
PING tomcat03 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat03 (172.17.0.2): icmp_seq=1 ttl=64 time=0.157 ms
64 bytes from tomcat03 (172.17.0.2): icmp_seq=2 ttl=64 time=0.103 ms
64 bytes from tomcat03 (172.17.0.2): icmp_seq=3 ttl=64 time=0.099 ms
- 但是反向不能ping通
[root@centos72 ~]# docker exec -it tomcat03 ping tomcat04
ping: tomcat04: Name or service not known
- 查看docker网络
[root@centos72 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
1801f6ebf58a bridge bridge local
b9329542552a elknetwork bridge local
c2977f6d6792 host host local
1ffd490d1182 none null local
- 查看network详细信息
docker inspect 1801f6ebf58a
"Containers": {
"bd4099ef1434edfe1414858f442eb4d264c3599fe39f19d04b02e429d9d95cae": {
"Name": "tomcat03",
"EndpointID": "9c68b74059a4ca8985a870735d265dd2f082113397469b554cd3f6af04c09432",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"d86c5731df77c154bc87fc96bd959f101e69a7ff390e47d72b4b0ae8b55370e9": {
"Name": "tomcat04",
"EndpointID": "3acfe9e531261b4c67a715e34f92b335b0cea36e4cd4fa690678dd92ef91d87f",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
},
- 查看容器详细信息可以看到有这个配置
docker inspect d86c5731df77
"Links": [
"/tomcat03:/tomcat04/tomcat03"
],
- link的原理,实际上是在tomcat04
hosts
中添加tomcat03的地址
[root@centos72 ~]# docker exec -it d86c5731df77 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 tomcat03 bd4099ef1434
172.17.0.3 d86c5731df77
- 此方法对容器创建的顺序有要求,如果集群内部多个容器要互访,使用就不太方便,也不推荐使用。
创建bridge网络
- 运行如下命令创建bridge网络
[root@centos72 ~]# docker network create testnet
f8de1d69de400503565981de021aa1bc068d6f63de532ef8c125348bb6437924
# 查看本地docker网络
[root@centos72 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
1801f6ebf58a bridge bridge local
b9329542552a elknetwork bridge local
c2977f6d6792 host host local
1ffd490d1182 none null local
f8de1d69de40 testnet bridge local
- 还可以自定义网络号
docker network create --driver bridge --subnet 192.168.200.0/24 --gateway 192.168.200.1 mynet
[root@centos72 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
1801f6ebf58a bridge bridge local
b9329542552a elknetwork bridge local
c2977f6d6792 host host local
1f12b8a96ac3 mynet bridge local
1ffd490d1182 none null local
f8de1d69de40 testnet bridge local
- 网络模式
bridge: 桥接 docker
none: 不配置网络
host: 和宿主机共享网络
container: 容器网络连通
- 运行容器连接到testnet网络。
使用方法:docker run -it --name <容器名> ---network <bridge> --network-alias <网络别名> <镜像名>
docker run -d -P --name tomcat05 --network testnet --network-alias tomcat05-net leoiceo/centos7-tomcat
docker run -d -P --name tomcat06 --network testnet --network-alias tomcat06-net leoiceo/centos7-tomcat
- 从一个容器ping另外一个容器,测试结果如下,相互可以通
[root@centos72 ~]# docker exec -it tomcat05 ping tomcat06
PING tomcat06 (172.21.0.3) 56(84) bytes of data.
64 bytes from tomcat06.testnet (172.21.0.3): icmp_seq=1 ttl=64 time=0.273 ms
64 bytes from tomcat06.testnet (172.21.0.3): icmp_seq=2 ttl=64 time=0.103 ms
# 现在不使用 --link也能互访
[root@centos72 ~]# docker exec -it tomcat06 ping tomcat05
PING tomcat05 (172.21.0.2) 56(84) bytes of data.
64 bytes from tomcat05.testnet (172.21.0.2): icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from tomcat05.testnet (172.21.0.2): icmp_seq=2 ttl=64 time=0.073 ms
- 若访问容器中服务,可以使用这用方式访问 <网络别名>:<服务端口号>
推荐使用这种方法,自定义网络,因为使用的是网络别名,可以不用顾虑ip是否变动,只要连接到docker内部bright网络即可互访。bridge也可以建立多个,隔离在不同的网段。
- 优势
redis 不同集群使用不同的网络,保证集群是安全和健康的
mysql 不同集群使用不同的网络,保证集群是安全和健康的
mysql