docker0 和 br-xxxxxx 有什么区别?

最近遇到了 docker 的虚拟网卡和虚拟机网络冲突的问题,所以研究一下 docker 的网络

图片.png

有一个 docker0 和很多 br 开头的『虚拟网卡』

有什么区别?什么时候会用 docker0 ?什么时候会用 br 开头的『虚拟网卡』?


有些奇怪的地方:
有的容器,使用 docker exec -it xxx bash,进去之后,使用 ip a 命令查看

有的容器的 eth0 的 ip 是 172.17.0.2 这样的格式,是 docker0 (docker0 是 172.17.0.1)下面的

root@a86fb0e6881d:/code# ip a
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
291: eth0@if292: <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
       valid_lft forever preferred_lft forever

但是有的容器内,却是 172.24.0.2,和 docker0 不相关了

root@e792db534caa:/code# ip a
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
40: eth0@if41: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:18:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.24.0.2/16 brd 172.24.255.255 scope global eth0
       valid_lft forever preferred_lft forever

但是我都可以通过 docker exec -it xxxx bash 进入容器,为什么会有这样的 ip 差异?

阅读 3.1k
1 个回答

docker0 是默认的桥接网络。是运行了 docker 这个软件就会有 docker0

veth 开头是 docker0 的儿子

br 开头是 docker-compose 创建的网络

至于 br 算不算 docker0 的儿子,还是和 docker0 是并列关系?br 就是 bridge 的缩写,因为 docker0 也是 bridge,所以是并列关系。可参考:Docker0网络及原理探究

动手实测一下,实践出真知

什么时候创建容器,会使用 veth

然后当我们使用类似 docker run -it --rm python:3.10-buster bash 跑一个容器的时候,就会在宿主机创建一个 veth (同时跑 4次,同时起四个容器,就会创建四个 veth,而不是公用一个 veth)

在容器内使用 ip a 命令查看容器内的网络配置,如下所示:

╰─➤  docker run -it --rm python:3.10-buster bash                                                                                        
root@7a62c7811e2f:/# ip a
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
55: eth0@if56: <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
       valid_lft forever preferred_lft forever

172.17.0.1 是 docker0,而我们的 python 容器的 ip 就是 172.17.0.2

使用 docker inspect hopeful_haibt 查看关于网络配置的内容,验证了我们的想法,此时我们的 python 容器使用的网络模式是 桥接(bridge),并且网关是 docker0

图片.png

得出结论:每次创建一个新容器的时候,Docker 从可用的地址段中选择一个空闲的 IP 地址分配给容器的 eth0 端口。使用本地主机上 docker0 接口的 IP 作为所有容器的默认网关。

图片.png

同时宿主机上多出来了 veth 开头的虚拟网卡,因为我同时运行了 4 个 docker run -it --rm python:3.10-buster bash,所以有 54、56、58、60 这四个 veth 开头的虚拟网卡

这意味着,我们 run 创建一个新容器的时候,如果不指定 network 等等参数,用默认的网络配置。那么这个新容器就是挂载到 docker0 下面去的,同时会在宿主机创建一个 veth 开头的虚拟网卡

什么时候创建容器,会使用 br

当然是跑 docker run 命令的时候,使用相关的网络配置参数喽,但是因为从来不会只用 docker run 直接跑容器,所以,我并不想去关心参数是什么

我都用 docker-compose 来创建和管理容器

问题就出在 docker-compose 上,通过 dokcer-compose 创建的容器在宿主机看到的虚拟网卡都是 br 开头的。(br 就是 bridge 的缩写)

如果一个 docker-compose.yaml 下面有 10 个 service,那是创建 10 个 br 虚拟网卡,还是创建 1 个 br 虚拟网卡呢?这个答案是 1,而不是 10。可参考: Docker Compose 网络设置

每跑一个 docker-compose.yaml 都会创建一个 br 虚拟网卡

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏