背景
同一宿主机上运行多个容器,每个容器对应不同的服务,当服务之间需要进行通信时(比如:http通信)就涉及到容器之间互联的问题,根据以往的经验给出几种实现的方式
ip
容器之间通过ip地址进行通信。 缺点很明显,容器的ip地址不是一成不变的,容器重启或者迁移都会造成ip地址的变化,从而导致服务之间通信失败。
network=container:xxx
[root@t32 ~]# docker run -itd --name myapp docker.io/ikubernetes/myapp:v2
cfb3370a23e314ad407f0a5e98db5aecd445e94774b41f5f6cbab8a847af74b0
[root@t32 ~]# docker run -it --network=container:myapp --name test centos:7.5.1804 bash
[root@cfb3370a23e3 /]# curl localhost:80
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@cfb3370a23e3 /]# 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.10 cfb3370a23e3
容器myapp与容器test在同一个network namespace,因此在容器test下可以使用localhost
link
[root@t32 ~]# docker run -it --link=myapp --name test centos:7.5.1804 bash
[root@b41364a8bdc4 /]# curl localhost:80
curl: (7) Failed connect to localhost:80; Connection refused
[root@b41364a8bdc4 /]# curl myapp:80
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@b41364a8bdc4 /]# 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.10 myapp cfb3370a23e3
172.17.0.11 b41364a8bdc4
容器myapp与容器test不在同一个network namespace下,但是test连接myapp之后,会将myapp以及对应ip地址写入到test下的/etc/hosts下,从而可以通过containerName:port
通信
network=container:xxx
与link
的方法在多个容器需要互相通信的情况下,会导致启动命令过于复杂,维护性差
network=host
network=host
是docker标准网络形式之一,指定容器与宿主机共享同一个network namespace。
多个容器共享host的network,容器之间可以通过localhost
完成通信。
但是,这种方式的缺点十分明显,不能够充分发挥容器的便捷性,比如部署两个mysql数据库,如果都采用host网络,则会有一个mysql容器启动失败(因为5432端口已经被占用)
bridge
最后出场的,也是最推崇的办法,即创建一个bridge,多个容器链接到同一个bridge上面,从而通过containerName:port
通信。
[root@t32 ~]# docker network create my-net2
7135ba540b5fd164b16c7f85629d53df5de9d014378b9984a641a8d0f3fddb18
[root@t32 ~]# docker network ls |grep my-net2
7135ba540b5f my-net2 bridge local
[root@t32 ~]# docker run -itd --name myapp --network=my-net2 docker.io/ikubernetes/myapp:v2
85011452d8df633642224e1b1dd5b91ca0d408774296010ff808eb9227b90379
[root@t32 ~]# docker run -itd --name myapp1 --network=my-net2 docker.io/ikubernetes/myapp:v3
048e70a79e65f064e21c0ef48b26e3142280b627dedf5864b28dc76d269cc857
[root@t32 ~]# docker run -it --name test --network=my-net2 centos:7.5.1804 bash
[root@f6cd7182338f /]# 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.21.0.4 f6cd7182338f
[root@f6cd7182338f /]# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
[root@f6cd7182338f /]# curl myapp
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@f6cd7182338f /]# curl myapp1
Hello MyApp | Version: v3 | <a href="hostname.html">Pod Name</a>
- bridge方式中的
/etc/resolv.conf
与其他方法不同,其他方法共享宿主机上的/etc/resolve.conf(即dns解析),而bridge则使用自己的dns解析信息 - 多个容器全部使用bridge,可以便于多容器互联
查看bridge的信息
[root@t32 ~]# docker inspect my-net2
[
{
"Name": "my-net2",
"Id": "7135ba540b5fd164b16c7f85629d53df5de9d014378b9984a641a8d0f3fddb18",
"Created": "2020-10-14T21:11:04.941285678+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.21.0.0/16",
"Gateway": "172.21.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {
"048e70a79e65f064e21c0ef48b26e3142280b627dedf5864b28dc76d269cc857": {
"Name": "myapp1",
"EndpointID": "31ad488d3c0b94a4b223fd6026e8e59586ac7214b2a4319a7b17c050eeb95f28",
"MacAddress": "02:42:ac:15:00:03",
"IPv4Address": "172.21.0.3/16",
"IPv6Address": ""
},
"85011452d8df633642224e1b1dd5b91ca0d408774296010ff808eb9227b90379": {
"Name": "myapp",
"EndpointID": "c8cb27609c1ac8d5bc6ed717f5be7945e0db2f1cd387cc12ba230125e1c544a0",
"MacAddress": "02:42:ac:15:00:02",
"IPv4Address": "172.21.0.2/16",
"IPv6Address": ""
},
"9a1526e9d2fe2c07081c1f1e3b08e564468d9d908e1b0965095e90e94e6de914": {
"Name": "test",
"EndpointID": "1e013be5fd8307400999501c28a2d43871d75c2c306e0cb180d3938a1b6d4fcf",
"MacAddress": "02:42:ac:15:00:04",
"IPv4Address": "172.21.0.4/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
- 能够查看挂载在my-net2上面的容器
- 不同的bridge分配不同的网段,多个容器在同一个网段下。