kubernetes - 网桥`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起什么作用?谢谢
解决方案
这里有 Docker 和 Kubernetes 两种网络模型。
码头工人模型
默认情况下,Docker 使用主机私有网络。它创建一个默认调用的虚拟网桥,并从RFC1918中为该网桥
docker0
定义的私有地址块之一分配一个子网。对于 Docker 创建的每个容器,它都会分配一个连接到网桥的虚拟以太网设备(称为 )。veth使用 Linux 命名空间映射为在容器中显示。容器内接口被赋予一个来自网桥地址范围的 IP 地址。veth
eth0
eth0
结果是 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 的另一篇文章
希望这能回答你的问题。
推荐阅读
- c++ - 对不同大小的 N 个数组的每个元素应用相同的函数
- ionic-framework - 如何在 Ionic 中动态更改离子范围颜色?
- r - 将数字添加到 R 中列表内的向量
- python - django 中未解决的导入“博客”
- javascript - 有没有人在 PhoneGap 构建中使用过 OneSignal sendtag?
- java - 麻烦正确使用布尔方法以及使用递归方法
- r - 具有置换 p 值的自举 t 检验
- django - 如何使用 msg.send() 在 django 的 html 电子邮件模板中传递用户名
- php - 在 Woocommerce 3.5 中将付款方式标题添加到管理订单列表
- c# - C# MySQLDataReader 为所有行返回相同的字符串