容器网络基础学习

在图中the host是物理机或者vm,enp就是网卡,然后在上面安装 docker,docker相当于一个三层交换机不仅仅有路由功能还有交换功能,在docker和enp之间是三层通过查询路由表进行访问,在docker左边的鲸鱼是二层,默认加入到docker 0 网络中相当于在同一个vlan中。
我们可以手动创建不同的网络也就是不同的网段将不同的docker容器加入,相当于就是不同的vlan。
在手动创建网段的时候还会自动分配dns,默认的不分配dns,他得到的ip地址又是随机不固定的,分配ip地址的时候通过相当于dhcp分配,mac地址由ip地址生成,保证唯一性
在容器的内部的东西不能访问到外部所以还需要将容器的内部端口映射到外部端口-p 80:80

启动容器并且指定网络代码

如果是这种直接部署在机器上的会共享主机的ip地址,可以通过ip地址进行访问。这时没有任何的隔离
命令非常简单,不需要创建网络,也不需要映射端口,只需要加一个参数:--network host。
Bash
注意:这里没有 -p 80:80,因为它不需要(也不能)做端口映射
docker run -d --name stormbreaker --network host nginx

维度,其他容器 (Bridge Mode),Stormbreaker (Host Mode),网工神翻译
IP 地址,有自己的独立 IP (如 172.17.0.2),没有独立 IP,直接共用宿主机的 IP (10.7.1.232),Bridge: 像接在 NAT 路由器下的内网主机。Host: 就像直接跑在路由器 Loopback 口上的进程。
端口占用,端口隔离。容器开 80,宿主机开 8080,互不干扰。,直接抢占。容器开 80,宿主机的 80 端口就被占了。,Host: 如果宿主机本来就跑了个 Nginx 占了 80 口,你再起这个容器,直接报错端口冲突。
转发效率,慢。经过 NAT + 虚拟网桥转发。,极快。没有任何 NAT 损耗,和物理机直接跑进程一样。,Host: 相当于由“硬件转发”降级为“软件转发”的区别(虽然这里是纯软件,但道理一样)。
网络隔离,有独立的 Network Namespace(网络命名空间)。,没有。它和宿主机共享同一个 Network Namespace。,Host: 相当于在交换机上配了 undo port isolation,谁都能看光谁。
为什么 Host 模式(Stormbreaker)不需要 NAT?
因为它就是宿主机“本人”。
当你使用 --network host 时,Docker 不会 为这个容器创建新的 Network Namespace。
- 你可以把它理解为: 这个容器进程,直接运行在宿主机的 Global Routing Table(全局路由表) 里。
- 现状:
- 容器根本没有自己的 IP。
- 容器看到的网卡,就是宿主机物理网卡
enp0s3。 - 容器看到的 IP,就是宿主机的
10.7.1.232。
- 通信过程:
- 容器里的 Nginx 说:“我要监听 80 端口”。
- 这实际上是宿主机的内核直接在
10.7.1.232:80上打开了一个 Socket 监听。 - 外部请求找
10.7.1.232:80,网卡收到包,发现有人在监听,直接交给它。
最上面的是bridge模式也就是桥接模式,现在这种是host模式
接下来是mac vlan模式,也是相当于直接接到物理交换机上有独立的ip和mac,host模式是使用主机的ip和mac

在这种情况下他们都是逻辑连接到同一个端口下,如果开启了端口保护,一个端口只允许有一个mac地址的话就会出现故障

这是时需要开启混杂模式

这时还是有dns功能可以直接ping容器的名称
维度,图片里的代码 (ipvlan_mode=l3),你问的那句话 (ARP 共享)
模式,Layer 3 (路由模式),Layer 2 (交换模式)
ARP 行为,无 ARP。容器不发 ARP,宿主机也不代答。完全靠路由表转发。,代理 ARP / 共享 MAC。宿主机用自己的 MAC 帮所有容器“应答” ARP 请求。
外部访问,必须写静态路由。外部路由器需知道 94.0/24 下一跳是宿主机。,直接二层通。外部直接 ARP 请求容器 IP,宿主机代答。
H3C 类比,ip route-static 192.168.94.0 24 宿主机IP,ip address 10.0.0.2 sub (从IP地址)
mac vlan 有单独的ip,共享在一个端口下有多个mac地址
ip vlan (l2)有单独的ip,共享一个mac地址
ip vlan (l3)每一个区域的docker相当于一个路由器,和其他的区域二层隔离,不能访问外网,无法暴露端口,需要部署静态路由,l3的mac地址相当于没有作用,
-
物理世界的逻辑(你的困惑来源)
在交换机上:
路由器查路由表:下一跳是 192.168.1.2。
路由器查 ARP 表:192.168.1.2 对应 MAC BB:BB。
动作: 路由器必须把 IP 包重新打包,加上 Dst MAC: BB:BB 的帧头。
原因: 因为中间隔着一根网线(物理介质),电信号必须遵循以太网协议才能传过去。 -
虚拟世界的逻辑(IPvlan L3 的真相)
在 Linux 内核里,宿主机和容器之间没有网线,它们共享同一块内存,同一个内核。
当数据包到达宿主机物理网卡后,流程是这样的:
第一步:宿主机收包(L2 终结)
外部发来的包,目的 MAC 是宿主机的物理 MAC。
宿主机网卡收到包,剥掉以太网帧头(L2 Header)。
此刻状态: 手里拿着一个赤裸的 IP 包(sk_buff 结构体),不知道该给谁。
第二步:查路由表(L3 决策)
内核看一眼 IP 头:Dst IP: 192.168.94.2(容器IP)。
内核查自己的 FIB(转发信息表),发现一条特殊的直连路由:
Bash
192.168.94.2 dev eth0.2 scope link <-- 这里的 eth0.2 就是容器的虚拟接口
关键点来了: 内核发现这个 IP 对应的是一个 虚拟设备(Virtual Device),而且这个设备就在我肚子里(关联了某个 Namespace)。
第三步:直接投递(Direct Injection)
不需要 ARP: 内核不需要去问“谁是 192.168.94.2”,因为它自己就知道“192.168.94.2 就在那个内存地址上”。
不需要封装 MAC: 内核直接把这个 sk_buff 数据结构的指针,从宿主机的协议栈队列,直接挂到 容器命名空间的接收队列里。
动作: 这是一次纯粹的内存操作(Function Call),而不是一次网络传输。

浙公网安备 33010602011771号