理解Docker0网卡

问题: docker 是如何处理容器网络访问的?
- 我们通过命令查看某一个容器的内部ip 可以看出容器内部的ip和docker0网卡是在同一网段的
- 并且宿主机和容器之间是可以相互ping通的
docker exec -it tomcat1 ip addr

原理
- 每启动一个容器, docker就会给容器分配一个ip. 只要安装了docker 就会有一个docker0的网卡
- docker0的网卡和真实的物理网卡之间是桥接模式
- 使用的技术是 evth-pair技术
evth-pair 技术
- 当我们启动容器的时候就会生成一对网卡
- evth-pair 就是一对虚拟设备接口, 他们都是成对出现的 一段连着协议, 一段彼此相连
- 有了这种特性 evth-pair 充当一个桥梁,连接各种虚拟设备


画图理解

结论
- tomcat01 和 tomcat02 是公用一个路由器 docker0
- 容器在不指定网络的情况下, 都是走docker0 路由的 docker会给容器分配一个默认的ip
- Docker中所有的网络接口都是虚拟的

容器互联 --link
- 通过上面我们会发现容器之间可以通过ip地址是可以ping通的
- 那么再某些情况下不用ip 我们可不可以用容器名的方式 ping通?
- 可以使用 --link 来解决上面的问题
# 我们重新启动一个tomcat 并且 --link tomcat1
docker run -d -P --link tomcat tomcat
# 完成之后我们就可以ping通了
docker exec -it jovial_chebyshev ping tomcat1
PING tomcat1 (172.17.0.4) 56(84) bytes of data.
64 bytes from tomcat1 (172.17.0.4): icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from tomcat1 (172.17.0.4): icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from tomcat1 (172.17.0.4): icmp_seq=4 ttl=64 time=0.069 ms
--- tomcat1 ping statistics ---
- 这样做有一个弊端就是 反向 ping 是不通的
- 原理就是在 jovial_chebyshev 容器中的 /etc/host 中有写
docker exec -it jovial_chebyshev 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.4 tomcat1 612aeb07e2e7
172.17.0.2 e7613df5b961
- --link 就是在我们 hosts 中增加了一条虚拟域名
自定义网络
查看所有的docker网络
docker network ls
NETWORK ID NAME DRIVER SCOPE
ea834618e218 bridge bridge local
2da75ecdb782 host host local
d7c3fa26b1bd none null local
网络模式
- bridge : 桥接模式(docker默认)
- none : 不配置网络
- host : 和宿主机共享网络
- container : 容器网络连通(用的少, 局限很大)
创建自定义网络
- --subnet 子网
- --gateway 网关
- --driver 默认桥接模式 不写也可以
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
查看自己创建的网络
- 命令: docker network inspect mynet
[
{
"Name": "mynet",
"Id": "6eb44c49b01928fd5c010c72c2738980814855e372a215eac422d35bdb1c70c4",
"Created": "2020-09-22T05:58:08.319032125Z",
"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": {}
}
]
使用自己创建的网络
docker run -d -P --net mynet --name tomcat-net-01 tomcat
再次测试
- 使用自己的网络创建两个容器并且相互ping 都是可以ping通的
- 比之前的 --link 要好很多
docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.063 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.063 ms
#反向ping 也是可以的
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.100 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.078 ms
网络连通
容器在不同的网段内如何实现互通?
示意图

docker exec -it tomcat01 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
- 所以需要使用 --network connect 命令
连通
docker network connect mynet tomcat01
查看
docker network inspect mynet
[
{
"Name": "mynet",
.....
.....
...
"Containers": {
"0796e3b7250d5c49372183e28266de528dfe072bb884220aeff9f0ccab4521a7": {
"Name": "tomcat-net-01",
"EndpointID": "e53cde49134bf3fb72f9bcd801ac73e208705b8cae416b689a726511b1125d49",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"2a187f1b05a15d33c5cc382c2b84d0b93fa4748f3e2ce4daed0ca0bc7a4d0500": {
"Name": "tomcat01",
"EndpointID": "652193a8312425944682a4b48f2f1a1d35ec5e4cea6806fbe0d5be11380627e8",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
.....
},
"Options": {},
"Labels": {}
}
]
- 连通之后我们可以看到 tomcat01 容器直接放到了 mynet的网络下
- 这就是一个容器两个ip地址
- 这样我们就可以ping通了
docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.074 ms