Docker网络
环境配置
# 删除所有镜像
docker rmi -f $(docker images -aq)
# 安装支持ip addr命令
brew install iproute2mac
在使用Docker时,要注意平台之间实现的差异性,如Docker For Mac的实现和标准Docker规范有区别,Docker For Mac的Docker Daemon是运行于虚拟机(xhyve)中的, 而不是像Linux上那样作为进程运行于宿主机,因此Docker For Mac没有docker0网桥,不能实现host网络模式,host模式会使Container复用Daemon的网络栈(在xhyve虚拟机中),而不是与Host主机网络栈,这样虽然其它容器仍然可通过xhyve网络栈进行交互,但却不是用的Host上的端口(在Host上无法访问)。bridge网络模式 -p 参数不受此影响,它能正常打开Host上的端口并映射到Container的对应Port。
官方说明:https://docs.docker.com/desktop/mac/networking/
docker是如何处理容器网络访问的?
docker run -d -P --name tomcat01 tomcat
docker exec -it tomcat01 /bin/bash
cat /etc/hosts
原理
我们每启动一个docker容器,docker就会给docker容器分配一个IP。电脑安装了docker,就会有一个网卡docker0。
桥接模式:使用的是evth-pair技术
evth-pair: 就是一对的虚拟设备接口。他们都是成对出现的,一端连着协议,一端彼此相连。通过这个特性,evth-pair充当一个桥梁连接各种虚拟网络设备。
OpenStack、Docker容器之间的连接、OVS的连接都是使用evth-pair技术
测试
docker run -d -P --name tomcat02 tomcat
# 测试tomcat01是否可以访问 tomcat02
docker exec -it tomcat02 ping 172.17.0.2
tomcat01 和 tomcat02是公用一个路由器 docker0. 所有容器不指定网络的情况下都是docker0路由的。docker会给容器分配一个默认的可用的IP。
PING命令失败
exec: "ping": executable file not found in $PATH: unknown
stackoverflow:https://stackoverflow.com/questions/49463719/docker-ping-executable-file-not-found-in-path-unknown
docker container exec -it tomcat01 bash
apt update
apt install iputils-ping
exit
# 重试ping命令
小结
Docker使用的是Linux的,宿主机中是一个dokcer容器的网桥-docker0. Docker中的所有网络接口都是虚拟的,虚拟的转发效率高。只要容器删除了,对应网桥就会删除。
思考一个场景:项目连接数据库 database-url=ip,项目不重启,数据库IP变了。我们希望能处理这个问题,直接使用名字访问容器?
容器互联-link
docker exec -it tomcat01 ping tomcat02
# 报错提示
ping: tomcat02: Name or service not known
docker run -d -P --name tomcat03 --link tomcat01 tomcat
# 通过--link 可以解决网络连通问题
docker exec -it tomcat03 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.281 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.206 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.252 ms
# 通过tomcat01可以ping通 tomcat03 吗?
# 查看网络信息
docker network ls
docker network inspect 380748f193c6
本质探究
docker exec -it tomcat03 cat /etc/hosts
172.17.0.2 tomcat01 6246f132343b
172.17.0.5 b92f01f61ddd
--link 就是在tomcat03的hosts配置中添加了一个tomcat01的地址。
已经不建议使用--link
自定义网络
# 查看帮忙命令
docker network --help
# 查看所有的docker网络
docker network ls
网络模式 | 说明 |
---|---|
bridge | 桥接 docker默认 |
none | 不配置网络 |
host | 和宿主机共享网络 |
container | 容器内网路连通(不建议使用,局限很大) |
测试
# 删除所有容器
docker rm -f $(docker ps -aq)
# 直接启动时 默认参数: --net bridge; 这个就是我们的docker0
docker run -d -P --name tomcat01 --net bridge tomcat
# docker0域名不能访问 --link可以打通连接
# 我们可以自定义一个网络
docker network create --help
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 可以看到自己的网络mynet已经存在
docker network ls
docker network inspect mynet
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat
# 发现不使用--link也可以通过名字 ping通
docker exec -it tomcat-net-01 ping 192.168.0.3
docker exec -it tomcat-net-01 ping tomcat-net-02
我们自定义的网络docker已经帮助我们维护好了对应的关系。推荐使用这种网络。
好处: redis、Mysql集群使用不同的网络,保证
网络连通
# 测试打通不同网段网络
docker network connect mynet tomcat01
# 连通之后就是将tomcat01 放到mynet网络下。一个容器两个IP地址:一个公网、一个私网
docker inspect mynet
docker exec -it tomcat01 ping tomcat-net-01
结论:假设要跨网段连通网络,需要使用docker network connect
命令