25
2025
06
20:18:31

容器网络——如何为docker添加网卡?

之前我们介绍Network Namespace(以下简称netns)和veth pair时说过docker是使用这些技术来实现的网络隔离,今天我们就来一探究竟,看下docker到底是如何做到的。

启动一个无网络的容器

首先我们使用 --net=none 参数启动一个无网络的容器,为了方便调试,这里我们使用了centos镜像。

docker run -itd --name centos-test --net=none centos

启动成功之后我们进入容器内部确认一下是否无网卡

[root@localhost ~]# docker ps CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES 28dc2e8853df   centos         "/bin/bash"   24 seconds ago   Up 23 seconds             centos-test [root@localhost ~]# docker exec -it 28dc2e8853df bash [root@28dc2e8853df /]# 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

可以看到确实只有一个本地环回网卡。

如何查看docker对应的netns?

当容器启动时,docker内部会自动为这个容器创建一个netns用于网络隔离,但当我们使用 ip netns list 查看时却看不到任何数据,这是因为docker把 netns 创建在了其他地方,而ip netns list命令只能读目录/var/run/netns下面的数据。

我们可以通过以下命令来解决这个问题,方便我们学习docker网络。

# 得到容器对应的进程 pid=docker inspect -f '{{.State.Pid}}' "$container_id" # 手动创建防止文件夹不存在 mkdir -p /var/run/netns/ # 建立软连接 ln -s /proc/$pid/ns/net /var/run/netns/$container_id

将上面的命令修改为和当前环境一致并验证netns中的网卡。

[root@localhost ~]# docker inspect -f '{{.State.Pid}}' "28dc2e8853df" 123624 [root@localhost ~]# mkdir -p /var/run/netns/ [root@localhost ~]# ln -s /proc/123624/ns/net /var/run/netns/28dc2e8853df [root@localhost ~]# ip netns list 28dc2e8853df [root@localhost ~]# ip netns exec 28dc2e8853df 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

可以看到我们成功输出了netns中的网卡信息,并且此信息和从docker容器中看到的一致。

给docker添加网卡

参考前面的Linux Bridge章节,我们首先创建一个网桥,然后创建一对veth pair,一端连接到网桥,一端移动到docker对应的netns中。

# 添加网桥 brctl addbr br0 # 启动网桥 ip link set br0 up # 新增一对veth ip link add veth0-ns type veth peer name veth0-br # 将veth的一端移动到docker对应的netns中 ip link set veth0-ns netns 28dc2e8853df # 将netns中的本地环回和veth启动并配置IP ip netns exec 28dc2e8853df ip link set lo up ip netns exec 28dc2e8853df ip link set veth0-ns up ip netns exec 28dc2e8853df ip addr add 10.0.0.1/24 dev veth0-ns # 将veth的另一端启动并挂载到网桥上 ip link set veth0-br up brctl addif br0 veth0-br

最后验证netnsdocker容器中的网卡信息。

[root@localhost ~]# ip netns exec 28dc2e8853df 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 91: veth0-ns@if90: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000     link/ether 86:29:e6:0a:2a:cb brd ff:ff:ff:ff:ff:ff link-netnsid 0     inet 10.0.0.1/24 scope global veth0-ns        valid_lft forever preferred_lft forever [root@localhost ~]# docker exec -it 28dc2e8853df bash [root@28dc2e8853df /]# 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 91: veth0-ns@if90: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000     link/ether 86:29:e6:0a:2a:cb brd ff:ff:ff:ff:ff:ff link-netnsid 0     inet 10.0.0.1/24 scope global veth0-ns        valid_lft forever preferred_lft forever

可以看出我们在netns中添加的网卡在docker容器中也可以正确的显示出来,由此证明了此netnsdocker容器的对应关系。当我们使用docker命令来创建容器时,docker为我们隐藏了大量细节,轻松使用几条命令便创建好了容器,但这种只知其然不知其所以然的方式对于我们掌握docker并不够,只有了解了底层原理之后才能对其功能掌握的更加深入。

理解docker的几种网络模式

了解了docker添加网卡的原理后再来理解docker的几种网络模式就十分简单明了了,主要区别就在于是否具有独立的netns

网络模式简介
bridge容器具有独立的netns,会将容器连接到 docker0 虚拟网桥,并配置IP地址,默认为该模式。
host容器没有独立的netns,和宿主机共用网络。
none容器具有独立的netns,但并没有对其进行任何网络设置。
container容器和某一个已存在的容器共享netns

新版docker新增了ipvlan、macvlan和overlay类型的网络,主要是为了多台宿主机器上面的docker容器隔离与通信,底层网络复杂了很多,之后我们会单独对其进行介绍。

最后也不要忘记清理实验环境哦。

# 删除网桥 ip link del br0 # 删除veth pair ip link del veth0-br # 删除软连接 rm -rf /var/run/netns/28dc2e8853df # 删除容器 docker rm 28dc2e8853df -f




推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

本文链接:https://www.hqyman.cn/post/11925.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: