大家读完觉得有意义和帮助记得关注和点赞!!!
目录
1. 问题和要求
1.1 当前组网方案的局限性
1.2 重新审视当前解决方案
2. 云原生 L3 网络
2.1 行业主流组网解决方案
Neutron+OVS 大型 L2 网络
印花布/法兰绒
纤毛
2.2 云原生解决方案
3. 定制
3.1. 跨主机联网
3.1.1 本地:使用 Cilium+Bird 进行直接路由
3.1.2 AWS:具有自定义配置的 ENI 模式
3.2. 自定义功能:固定 IP statefulset
3.3. 监控和警报
3.4. 纤毛 etcd
3.5. 部署
3.5.1 带外部署:docker-compose + salt
3.5.2 在一个 K8S 集群中同时运行两个组网方案
3.6. 更多自定义配置
4. 当前部署状态
引用
1. 问题和要求
1.1 当前组网方案的局限性
正如在上一篇文章中所解释的,对于 出于一些实际原因,我们将基于 Neutron 的网络堆栈扩展到 支持容器平台(Mesos、Kubernetes),因此我们有一个网络 组件同时服务于三个平台:
- OpenStack
- 裸机(内部开发的系统)
- Kubernetes(之前为 Mesos)
图 1-1.单一网络服务 (Neutron) 支持 3 个平台:OpenStack、Baremetal 和 Kubernetes
虽然这在从虚拟机转换的过程中受益匪浅 对于容器来说,当集群变大时,它就会成为性能瓶颈, 例如,总实例数 (VM+Container+BM) 超过 .在这样的规模下,分配 一个 IP 地址可能需要甚至更多。40K
10s
尽管我们在优化方面投入了大量精力,但这减少了 API 响应时间提高了两个数量级,整体性能依然 un-satisfactory,尤其是考虑到 NOT 遥远的未来。从本质上讲,这是因为 Neutron 是一种用于 虚拟机平台,其规模要小得多(就实例而言) 并且对 -level API 响应感到满意。seconds
为了最终解决这些问题,我们必须重新审视当前的 问题和要求。
1.2 重新审视当前解决方案
经过多次迭代,当前问题回顾以及未来 需要澄清,我们列出了我们网络的五个关键问题/要求:
图 1-2.问题和要求
- 作为中央 IPAM,Neutron 禁止 Kubernetes 集群增长 甚至更大。
- 大型 L2 网络具有固有的硬件瓶颈,例如在 3 层中 分层拓扑,核心路由器/交换机必须保持转发 条目,并且这具有硬件限制(例如 有效条目 [5])。这意味着此物理网络中的 total 实例不能 exceed - 对于 Kubernetes 来说,这确实是一个坏消息。
64K*70% = 48K
48K
- 当前的网络解决方案是非 K8S 原生的,因此它不支持 Kubernetes Service (ClusterIP) 等功能,因此应用程序众多 (例如 Spinnaker、Istio)无法部署或迁移到容器平台。
- 缺乏主机级防火墙 - 或 K8S 中的网络策略。所有规则 应用于 HW FW,这是一个很大的负担并且变得无法维护。
- 本地和 AWS 的独立解决方案,结果很高 开发和维护成本。
2. 云原生 L3 网络
基于上述分析,我们开始调查和评估下一代 网络解决方案。针对上述问题,我们的新解决方案 应提供:
- De-centralized IPAM:每个节点上的本地 IPAM
- 无硬件瓶颈:主机之间使用 L3 组网
- K8S 原生:原生支持所有 K8S 功能
- 网络策略:每个节点上的主机或应用程序级别的网络安全规则
- 单一解决方案同时涵盖本地和 AWS
2.1 行业主流组网解决方案
看看过去 10 年的一些主流网络解决方案。
图 2-1.网络演变
Neutron+OVS 大型 L2 网络
在 2010 年代,随着“云计算”的概念,OpenStack 迅速 成为开源社区中占主导地位的虚拟化平台。以及 这种趋势是它的网络堆栈:基于 Neutron+OVS 的大型第 2 层网络。
在这个大型第 2 层网络中,跨主机网络有两种选择:
- tunnling(软件 VxLAN):这不涉及物理网络的感知, 但遇到性能问题
- 直接转发(提供商网络模型):需要物理网络的 感知,在底层物理网络中的 HW 路由器上配置的所有网关
如果您像我们一样使用“提供商网络模型”,您可能会遇到上述情况 当集群非常大时(例如 实例)。50K+
印花布/法兰绒
自 ~2005 年以来,容器平台变得越来越流行。 K8s 原生解决方案(如 Flannel 和 Calico)也随着这一趋势而发展。 与 OpenStack 中的中央 IPAM 模型相比,容器平台偏爱 本地 IPAM - 每个主机上一个 IPAM。
但是,当集群运行时,此解决方案会遇到严重的性能问题 真的很大 [1]。从本质上讲,这是因为这些解决方案基于 ,这是一个链式设计,因此具有复杂性,而且 当每个 iptables 上都有数以万计的 iptables 规则时,很难进行故障排除 节点。iptables
O(n)
因此,有一些优化的解决方案可以缓解这个问题。 其中就有纤毛。
纤毛
Cilium 也是一个 K8s 原生解决方案,但通过以下方式解决性能问题 利用新的内核技术:eBPF。eBPF 规则基于哈希,因此具有复杂性。O(1)
图 2-2.eBPF 杀死 iptables,图像来源 [6]
您可以在 Cilium 的博客网站中找到更详细的性能比较。
经过多次 POC 验证后,我们决定采用 Cilium 作为我们的下一代 网络解决方案。就网络堆栈而言,这对我们来说是一个 10 年的飞跃。
图 2-3.网络演变
2.2 云原生解决方案
基于大量研究和真实环境测试,我们决定采用 Cilium 作为我们的下一代网络计划。
高级拓扑如下所示:
图 2-4.新解决方案的高级拓扑
- 对于主机内联网:所有实例都连接到 Cilium
- 用于主机间联网
- 本地:使用 BGP 进行直接路由
- AWS:使用 ENI(Cilium 原生支持)
该解决方案的优势:
- 分散式 IPAM,无中央 IPAM 性能瓶颈
- 无硬件瓶颈 - 用 L3 网络取代大型 L2 网络
- K8s 原生:可部署新的云原生应用
- 安全性:网络策略
- 适用于本地和 AWS 的单一解决方案
3. 定制
如果没有任何 更改/自定义,尤其是当您已经拥有具有 关键业务在它们上运行多年。因此,我们花了很多时间在 识别我们的业务与网络之间的耦合,尽最大努力 使业务用户不知道底层更改。
此外,我们还探索了自己的高效部署、升级和 维护。
以下是我们的一些配置/自定义,可能与原版不同 Cilium 部署。
3.1. 跨主机联网
3.1.1 本地:使用 Cilium+Bird 进行直接路由
我们使用 BGP 进行主机间通信,并选择 Bird [2](版本)作为 BGP 代理。2.x
Cilium 官方文档推荐作为 BGP 代理,而 一个很好的自动引导代理,相比之下,它的功能有限 与 bird,例如 BFD、ECMP,这在考虑高级时非常重要 功能和性能问题。kube-router
对于度量收集,我们使用 bird_exporter [3],但我们在 3 个度量 进行一些更改并构建了我们自己的 Docker 镜像,并用于部署它。 此外,我们还创建了自己的监控仪表板和警报。daemonset
3.1.2 AWS:具有自定义配置的 ENI 模式
在 AWS 上,我们使用 ENI 模式部署 Cilium,但也进行了一些自定义。
例如,Cilium 代理会在代理启动时创建一个 CRD,但是 default 配置会保留 ENI 规范( 中的 字段 ) empty,这会导致代理任意选择一个 subnetTag 来创建 ENI 并预先分配 IP。这给我们带来了问题,因为某些子网不是 供 Pod 使用,例如出站子网。CiliumNode
ENI
struct NetConf
幸运的是,Cilium 提供了一种解决此问题的方法(但没有提供详细的 documentation 中,我们遍历了源代码并最终完成了一些事情 work) 的以下是我们的解决方法::(
- 将 costom ENI 配置添加到 CNI conf 文件 (
/etc/cni/net.d/xx-cilium-cni-eni.conf
) - 指定显式加载此 conf 文件
--read-eni-configuration <file>
通过这两个步骤,代理将为 ENI/IP 分配选择正确的子网。
这种方式还允许我们永久指定 min-allocate/pre-allocate/etc 参数。相比之下,在默认的 设置,则 Runtime 值将在 Agent 时被默认值覆盖 重新启动。
3.2. 自定义功能:固定 IP statefulset
我们为特殊情况添加了固定 IP 功能(仅适用于 statefulset)——一个 对于某些应用程序,中间步骤是真正的云原生。
这段代码有点脏,但是它与上游代码松散耦合, 因此,我们只需使用 .git rebase <tag>
但是这个功能目前依赖于 sticky scheduler,也就是一个简单的 k8s scheduler 实现的 scheduler(您也可以找到类似的 scheduler 在 GitHub 上),因此此功能尚未准备好被其他用户广泛使用。
3.3. 监控和警报
Cilium 官方推荐 Grafana + Prometheus 进行监控,并且 alerting,并提供 YAML 文件来创建这些基础设施。这很容易 开始使用。
但是我们重新使用了我们的实时监控和警报基础设施,那就是 快速相似但内部优化:
- 内部优化的 Grafana
- 内部开发的公制采集代理
- 内部优化的 VictoriaMetrics(与 prometheus 兼容)
此外,我们还根据这些指标创建了自己的控制面板。下面列出了一些 其中(调整页面大小以更清楚地看到它们):
图 3-1.所有支持 Cilium 的集群(遗留节点 + cilium 节点)的指标
图 3-2.单集群指标
图 3-3.单个集群中按各种指标排名前 N 的节点
3.4. 纤毛 etcd
我们为 Cilium 设置了独立的 etcd 集群,它不依赖 K8S。
3.5. 部署
嗯,这与社区有很大不同。
3.5.1 带外部署:docker-compose + salt
我们不希望 Cilium 依赖 K8s - 至少目前是这样。Cilium 是一种底层 服务,而不是相反。(更重要的是,我们甚至可能会考虑支持 带有 Cilium 的 OpenStack - 但不要感到惊讶,我们还没有决定)。
所以,我们使用 + 进行部署,它不依赖 K8S。 这使我们能够:docker-compose
salt
- 有效地 “容忍所有污点” (K8S daemonset 不支持)
- 使我们能够完全控制滚动更新过程(可能跨越 对于非常大的 PROD 集群,需要数周的时间)根据我们的需求
与 daemonset 相比,docker-compose 的另一个好处是我们可以拥有不同的 cilium-agent 的节点级配置,而后者使用 configmap, 这仅限于集群级别。
更重要的是,我们有意使 docker-compose 文件与 上游映像 - 这意味着,例如,如果节点不需要固定 IP 功能,我们可以只用 cilium agent 群落纤毛图像。docker-compose up
3.5.2 在一个 K8S 集群中同时运行两个组网方案
我们在现有集群中添加了新的 cilium 驱动的节点,因此实际上有 两种类型的节点协同工作:
- 具有传统网络解决方案的节点:基于
Neutron + OVS + Neutron-OVS-Agent + CustomCNI
- 使用 Cilium 网络解决方案的节点:(本地)
Cilium+Bird
我们设法让这两种类型的节点上的 Pod 彼此可以访问。 我们的下一个计划是将 Pod 从旧节点迁移到新的 Cilium 节点。
3.6. 更多自定义配置
- 本地和AWS:关闭,使PodIP可在k8s集群之外路由
masqurade
- 本地:在 Controller Manager 中关闭 Auto Allocate Node CIDR () 中,我们将节点 CIDR (PodCIDR) 显式分配给 每个节点
--allocate-node-cidrs=false
- 本地:基于 Cilium+BGP 的自定义/简单 L4LB,实现 K8S externalIP 功能
4. 当前部署状态
几个月来,我们已经在生产环境中稳定地运行 Cilium。
现在我们在 Cilium 上有了 pod,它们跨越了 PROD 和 UAT/FAT,以及 本地和 AWS。6K+
此外,我们在 Cilium 上也有 GitlabCI 作业 日,每个 Job 都会启动一个新的 Pod(并在 Job 完成后终止它)。10K+
这只占我们总 Pod 的很小一部分,并且 在 2020 年,我们将开始将这些旧版 Pod 迁移到 Cilium。
引用
- 扩展 Kubernetes 以支持 50,000 项服务
- BIRD Internet 路由守护程序项目
- Github: bird_exporter
- Github: VictoriaMetrics
- Cisco Nexus 7700 F3 系列 24 端口 40 Gb 以太网模块
- Cilium 1.0:将 BPF 革命引入 Kubernetes 网络和安全