首页 > 解决方案 > 网桥`docker0`在k8s with flannel中起什么作用

问题描述

k8s版本:v1.10.4
flannel版本:v0.10.0 docker
版本v1.12.6

当我在节点上使用命令brctl show时,它显示如下:

[root@node03 tmp]# brctl show
bridge name bridge id       STP enabled interfaces
cni0        8000.0a580af40501   no      veth39711246
                                        veth591ea0bf
                                        veth5b889fed
                                        veth61dfc48a
                                        veth6ef58804
                                        veth75f5ef36
                                        vethc162dc8a
docker0     8000.0242dfd605c0   no
它显示 vethXXX 绑定在名为 cni0 的网桥上,但是当我使用命令 `ip addr` 时,它显示:
[root@node03 tmp]# ip addr |grep veth
6: veth61dfc48a@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP 
7: veth591ea0bf@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP 
9: veth6ef58804@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP 
46: vethc162dc8a@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP 
55: veth5b889fed@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP 
61: veth75f5ef36@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP 
78: veth39711246@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP
这些 veth 都绑定在 `if3` 上,但 `if3` 不是 cni0。它是 `docker0`
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 

似乎网桥docker0没用,但ip addr显示所有veth设备都绑定在它上面。网桥docker0在k8s中用flannel起什么作用?谢谢

标签: kubernetesflannel

解决方案


这里有 Docker 和 Kubernetes 两种网络模型。

码头工人模型

默认情况下,Docker 使用主机私有网络。它创建一个默认调用的虚拟网桥,并从RFC1918中为该网桥docker0定义的私有地址块之一分配一个子网。对于 Docker 创建的每个容器,它都会分配一个连接到网桥的虚拟以太网设备(称为 )。veth使用 Linux 命名空间映射为在容器中显示。容器内接口被赋予一个来自网桥地址范围的 IP 地址。vetheth0eth0

结果是 Docker 容器只有在同一台机器上(因此是同一个虚拟网桥)上的其他容器才能与其他容器通信。不同机器上的容器无法相互访问——事实上,它们最终可能具有完全相同的网络范围和 IP 地址。

Kubernetes 模型

Kubernetes 对任何网络实现都提出了以下基本要求(除非任何有意的网络分段策略):

  • 所有容器都可以在没有 NAT 的情况下与所有其他容器通信
  • 所有节点都可以在没有 NAT 的情况下与所有容器通信(反之亦然)
  • 容器认为自己的 IP 与其他人认为的 IP 相同

Kubernetes 在 Pod 范围内应用 IP 地址 - Pod 共享其网络命名空间中的容器 - 包括它们的 IP 地址。这意味着一个容器内的容器都 Pod 可以到达彼此的端口 localhost。这确实意味着容器中的容器 Pod 必须协调端口的使用,但这与 VM 中的进程没有什么不同。这称为“IP-per-pod”模型。这是使用 Docker 作为“pod 容器”实现的,它保持网络命名空间打开,而“应用容器”(用户指定的东西)通过 Docker 的 --net=container:<id> 功能加入该命名空间。

与 Docker 一样,可以请求主机端口,但这被简化为非常小众的操作。在这种情况下,将在主机上分配一个端口, Node 并将流量转发到 Pod. 它 Pod 本身对主机端口的存在或不存在视而不见。

为了将平台与底层网络基础设施集成,Kubernetes 提供了一个称为容器网络接口 (CNI)的插件规范。如果满足 Kubernetes 的基本要求,供应商可以随意使用网络堆栈,通常使用覆盖网络来支持多子网可用集群。

下面展示了如何通过流行的CNI Flannel实现覆盖网络。

绒布

您可以在此处阅读有关其他 CNI 的更多信息。Kubernetes 方法在集群网络文档中进行了解释。我还建议阅读Kubernetes 很难:为什么 EKS 让网络和安全架构师更容易,它解释了Flannel的工作原理,也是Medium 的另一篇文章

希望这能回答你的问题。


推荐阅读