小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
Docker 学习 | 容器互联
本文研究 Docker两个容器之间如何通信的问题
--link
准备工作
- 使用Docker 启动两个tomcat
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat02 tomcat
用Tomcat01 通过 服务名 Ping Tomcat02
docker exec -it tomcat01 ping tomcat02
结果我们发现 ping 不通
如何才能解决呢?
我们需要这两个容器服务进行网络连接~
思考一下以下场景, 我们编写了一个微服务, 数据库的URL地址为IP,但是数据库的IP换掉了,我们此时需要修改代码重启项目才能解决。那么,我们能不能通过服务名来进行对数据库的访问, 即使IP地址换了,也不影响我们的项目呢?
--link
# 通过 --link 实现容器联通
docker run -d -P --name tomcat03 --link tomcat02 tomcat
测试一下
$ docker exec -it tomcat03 ping tomcat02
# 结果: ping 通了
但是这样做会有很多坑, 而且很不方便,而且不可以反向Ping
需要在tomcat02 中 --link tomcat03 才能实现互联
查看Docker 网络
docker network ls
查看网卡里面的所有东西
docker network inspect NETWORK_ID
本质原理
--link 将tomcat02的地址 在tomcat03中的 hosts 中增加了映射~
就这? 真是开发中是不建议使用的
docker0 不支持容器名连接访问
自定义网络
容器互联
查看 docker 当前网络
docker network ls
docker network ls
NETWORK ID NAME DRIVER SCOPE
51e24adb9482 bridge bridge local
3db21d51de9c host host local
8d20e8fd6793 none null local
移除网络
docker network rm <NAME>
网络模式
- bridge: 桥接模式(默认, 自己创建也使用 bridge 模式)
- none: 不配置网络
- host: 主机模式: 与宿主机共享网络
- container: 容器内网络连通
docker network --help
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
测试之前清空容器 docker rm -f $(docker ps -aq)
ip addr 查看宿主机当前网卡
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 52:54:00:4c:83:06 brd ff:ff:ff:ff:ff:ff
inet 10.0.8.10/22 brd 10.0.11.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe4c:8306/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:fc:84:98:fb brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:fcff:fe84:98fb/64 scope link
valid_lft forever preferred_lft forever
测试
# 我们直接启动的命令, 默认是有 --net bridge 的, 这个就是 Docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
# Docker0 特点: 1.默认的 2.域名不能访问
我们可以自定义一个网络
docker create
docker network create --help
# 我们自定义一个网络
# docker network create
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
# mynet
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 现在我创建了一个网络, driver 是桥接(bridge), 网络的名字叫 mynet, 子网 [192.168.0.0/16] 最多支持 65535 个网络, 默认路由网关 [192.168.0.1]
de55be69be90cc51324b0dfcd6b1a25bf4d5cc2f91569208025a9f068565a383
# 创建成功
# 查看
[root@VM-8-10-centos tomcat]$ docker network ls
NETWORK ID NAME DRIVER SCOPE
acaeca217cc5 bridge bridge local
3edbb9cd9ab0 host host local
de55be69be90 mynet bridge local # mynet 网络创建成功
dad0ff6720e0 none null local
docker inspect mynet
[root@VM-8-10-centos tomcat]# docker inspect mynet
[
{
"Name": "mynet",
"Id": "de55be69be90cc51324b0dfcd6b1a25bf4d5cc2f91569208025a9f068565a383",
"Created": "2021-09-29T23:54:40.88159831+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
# 到此, 我们自己的网络就创建好了~
测试: 创建 Tomcat 容器并使用我们创建的网络
$ docker run -d -P --name tomcat-net-01 --net mynet mytomcat
$ docker run -d -P --name tomcat-net-02 --net mynet mytomcat
查看 mynet
$ docker inspect mynet
[
{
"Name": "mynet",
"Id": "de55be69be90cc51324b0dfcd6b1a25bf4d5cc2f91569208025a9f068565a383",
"Created": "2021-09-29T23:54:40.88159831+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
# 在此处 我们发现, mynet 网络下存在了 tomcat01 和 tomcat02 两个容器
"Containers": {
"52514945040be96967dbc982f4cbe86a07c6303b51931595c645fc8f0deb9570": {
"Name": "tomcat-net-02",
"EndpointID": "d2bcd6a479f20e20575c03d6309a0d2790d9867a47325f11c140db25e792569f",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"e629bb8bcd66a2f43dbb617d9decc35d40bd1678c81a217d159057a4443aed22": {
"Name": "tomcat-net-01",
"EndpointID": "e2e501168303a5e33464ba0fb4d8838bd6a6a9f09545026b7a900b4abb8833a4",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
测试 tomcat-net-01 能直接 ping 通 tomcat-net-02么~
$ docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.117 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.054 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.063 ms
64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.056 ms
64 bytes from 192.168.0.3: icmp_seq=5 ttl=64 time=0.054 ms
64 bytes from 192.168.0.3: icmp_seq=6 ttl=64 time=0.058 ms
64 bytes from 192.168.0.3: icmp_seq=7 ttl=64 time=0.054 ms
64 bytes from 192.168.0.3: icmp_seq=8 ttl=64 time=0.047 ms
64 bytes from 192.168.0.3: icmp_seq=9 ttl=64 time=0.052 ms
^C
--- 192.168.0.3 ping statistics ---
Success!
自定义网络 docker 都已经帮我们维护好了对应的关系, 推荐这样使用网络