Docker系列-7.容器间通信
Docker的网络模式
Docker安装后会自带 三种网络模式,使用docker network ls
、docker network inspect
查看docker网络相关信息。
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c19cfce6e2b6 bridge bridge local
1e96011ad6bf host host local
ee187a6ae682 none null local
默认网桥
Docker启动时,会在主机上创建虚拟网桥docker0,然后分配一个本地空闲私有网段(172.17.0.1/16)给docker0字网,docker0的IP地址即为容器的默认网关。
[root@docker ~]# ifconfig -a
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:26:99:6a:c8 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
每启动一个容器,daemon就会分配主机docker0子网中的一个IP给容器使用,在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端在容器中命名为eth0@xxxx(容器的网卡),另一端放在主机中,以vethxxx@xxx这样类似的名字命名,并将其加入到docker0网桥中。
#查看主机网桥
[root@docker ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024294aeb060 no veth955fcfc
#查看docker0详情
[root@docker ~]# ip link show |grep docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
22: veth955fcfc@if21: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
#查看容器参数
[root@docker ~]# filter='Name={{.Name}} Hostname={{.Config.Hostname}} ' && filter+='IP={{or .NetworkSettings.IPAddress .NetworkSettings.Networks.testnet.IPAddress}} ' && filter+='Mac={{or .NetworkSettings.MacAddress .NetworkSettings.Networks.testnet.MacAddress}} ' && filter+='Bridge={{if .NetworkSettings.IPAddress}} docker0 {{else}} testnet {{end}}' && docker inspect web --format "$filter" | sed 's/=//=/g'
Name=web Hostname=8dfa1d32d82a IP=172.17.0.2 Mac=02:42:ac:11:00:02 Bridge= docker0
#容器中的eth0@if22
[root@docker ~]# docker exec -it 8dfa1d32d82a ip a |grep eth
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
注:假设有冲突,修改docker配置文件/etc/docker/daemon.json可以修改docker默认的网段。
{
"bip":"192.168.100.1/24"
}
使用--Link
绑定容器
docker默认使用Bridge网络模式,容器启动后到都会被分配一个内网的虚拟IP而且这个虚拟IP并不是一成不变的,为了解决容器服务和动态IP的绑定关系, 我门可以首先用--name
来指定别名标识容器,然后用别名和--link
替代容器的动态IP,这种用法有点类似于在hosts中设置关联服务器的hostname。
下面模拟基于tomcat的web容器来连接mysql数据库服务器
##启动mysql容器命名为databse
[root@docker ~]# docker run -d -it --name database mysql /bin/bash
faa5ce0dcca7b807c3d74fa79fc86805f35ed2ab77b7696f27a556d45e2b2f83
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
faa5ce0dcca7 mysql "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 3306/tcp, 33060/tcp database
##启动tomcat容器
[root@docker ~]# docker run -d --name web --link database tomcat
81722e9e849b091b5fb64c5c374894b5c019709e1dac7f93d4d232a9c2e2ebbb
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81722e9e849b tomcat "catalina.sh run" About a minute ago Up About a minute 8080/tcp web
faa5ce0dcca7 mysql "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 3306/tcp, 33060/tcp database
[root@docker ~]# docker exec 81722e9e849b -it /bin/bash
##容器中ping database
root@81722e9e849b:/usr/local/tomcat# ping database
PING database (172.17.0.2) 56(84) bytes of data.
64 bytes from database (172.17.0.2): icmp_seq=1 ttl=64 time=0.152 ms
64 bytes from database (172.17.0.2): icmp_seq=2 ttl=64 time=0.110 ms
64 bytes from database (172.17.0.2): icmp_seq=3 ttl=64 time=0.163 ms
64 bytes from database (172.17.0.2): icmp_seq=4 ttl=64 time=0.107 ms
使用network creat
创建网桥
我们可以使用docker network create
创建可以使用name标签来相互通信的网桥。
##启动容器
[root@docker ~]# docker run -d --name web tomcat
f50422d4092535b73e7d26da957c6aca00317a9babc55ba8076dd6fe2ca21543
[root@docker ~]# docker run -d -it --name database centos /bin/bash
0d57fe82fe66506f93977b718df7ad1d8ed2b3d4bc63bcc11b7e051f2b934377
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0d57fe82fe66 centos "/bin/bash" 4 seconds ago Up 4 seconds database
f50422d40925 tomcat "catalina.sh run" 9 minutes ago Up 9 minutes 8080/tcp web
##创建自定义网桥
[root@docker ~]# docker network create cross-bridge
925757717f0c96ec7a16e6833e04666281e11a42035697bc189c68c1b5610d03
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
22015ebeb4c6 bridge bridge local
925757717f0c cross-bridge bridge local
1e96011ad6bf host host local
ee187a6ae682 none null local
##将容器加入自定义网桥
[root@docker ~]# docker network connect cross-bridge web
[root@docker ~]# docker network connect cross-bridge database
##测试容器间通信
[root@docker ~]# docker exec -it 0d57fe82fe66 /bin/bash
[root@0d57fe82fe66 /]# ping web
PING web (172.18.0.2) 56(84) bytes of data.
64 bytes from web.cross-bridge (172.18.0.2): icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from web.cross-bridge (172.18.0.2): icmp_seq=2 ttl=64 time=0.100 ms
[root@docker ~]# docker exec -it f50422d40925 /bin/bash
root@f50422d40925:/usr/local/tomcat# ping database
PING database (172.18.0.3) 56(84) bytes of data.
64 bytes from database.cross-bridge (172.18.0.3): icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from database.cross-bridge (172.18.0.3): icmp_seq=2 ttl=64 time=0.114 ms
参考
How to manage bridge and docker bridge on Linux device