Kube-OVN 是一款 CNCF 旗下的企业级云原生网络编排系统,将 SDN 的能力和云原生结合, 提供丰富的功能,极致的性能以及良好的可运维性。
Kube-OVN可提供跨云网络管理、传统网络架构与基础设施的互联互通、边缘集群落地等复杂应用场景的能力支持,解除Kubernetes网络面临的性能和安全监控的掣肘,为基于Kubernetes架构原生设计的系统提供最为成熟的网络底座,提升用户对Kubernetes生态Runtime的稳定性和易用性。目前,Kube-OVN已成为开源社区最受欢迎的Kubernetes网络解决方案之一,并已成功实现了上千集群级别的大规模企业级项目、海外项目落地,以及商业化的初步尝试。
丰富的功能:
如果你怀念 SDN 领域丰富的网络能力却在云原生领域苦苦追寻而不得,那么 Kube-OVN 将是你的最佳选择。
借助 OVS/OVN 在 SDN 领域成熟的能力,Kube-OVN 将网络虚拟化的丰富功能带入云原生领域。目前已支持子网管理, 静态 IP 分配,分布式/集中式网关,Underlay/Overlay 混合网络, VPC 多租户网络,跨集群互联网络,QoS 管理, 多网卡管理,ACL 网络控制,流量镜像,ARM 支持, Windows 支持等诸多功能。
极致的性能:
如果你担心容器网络会带来额外的性能损耗,那么来看一下 Kube-OVN 是如何极致的优化性能。
在数据平面,通过一系列对流表和内核的精心优化,并借助 eBPF、DPDK、智能网卡卸载等新兴技术, Kube-OVN 可以在延迟和吞吐量等方面的指标达到近似或超出宿主机网络性能的水平。在控制平面,通过对 OVN 上游流表的裁剪, 各种缓存技术的使用和调优,Kube-OVN 可以支持大规模上千节点和上万 Pod 的集群。
此外 Kube-OVN 还在不断优化 CPU 和内存等资源的使用量,以适应边缘等资源有限场景
良好的可运维性:
如果你对容器网络的运维心存忧虑,Kube-OVN 内置了大量的工具来帮助你简化运维操作。
Kube-OVN 提供了一键安装脚本,帮助用户迅速搭建生产就绪的容器网络。同时内置的丰富的监控指标和 Grafana 面板, 可帮助用户建立完善的监控体系。强大的命令行工具可以简化用户的日常运维操作。通过和 Cilium 结合,利用 eBPF 能力用户可以 增强对网络的可观测性。 此外流量镜像的能力可以方便用户自定义流量监控,并和传统的 NPM 系统对接。
1、最主要的是现有开源方案很难满足我们客户的需求,例如子网划分,IP固定,QoS,VLAN 隔离,流量镜像等等这种在传统网络里很常见的功能在绝大部分的开源网络方案里都是缺失的。造成的结果是,真正落地的时候会发现没有一个开源网络方案能用,只能不断的和网络部、系统部、应用部各个部门扯皮,割舍掉原有的一些网络功能来上容器。我们希望能通过技术的手段丰富现有的容器网络能力,来帮助客户更顺利的落地容器。
2、从我们自身维护容器云的角度来看,容器平台网络相关的问题是最难排查的。一个网络不通的问题可能会涉及 Pod 网络、CNI、Service、Iptables、IPVS、Ingress、DNS、NetworkPolicy、Loadbalancer 等等多个组件,流量的分散导致故障十分难以排查,并且需要运维人员掌握很多组件的原理。我们希望能够把网络流量的数据面进行统一,不要再分散到各个组件上,降低维护方面的复杂度。
3、经过调研我们认为 OVN/OVS 这套网络组件功能上比较齐全,能够实现 OpenStack 的所有网络功能,那么对 Kubernetes 的网络来说能力其实是大幅溢出的,可以实现很多高级功能。此外 OVS 已经是经久考验的虚拟交换机,稳定性是很有保证的,性能方面也有各种 DPDK 和硬件加速方案来托底,真正到要性能的时候我们有应对的方案。此外我们了解到的一些公有容器云厂商内部其实也是用的 OVN 来做容器网络,我们也不算第一个烈士。
综合这些因素我们决定自己开发一个基于 OVN 的网络方案,也就是 Kube-OVN 。一方面能够很好满足客户和我们自己的需求,另一方面开源出来也能帮助社区一同进步。
1、平移 OpenStack 网络的概念和功能到 Kubernetes。OpenStack 的网络已经发展了很多年,很多设计和概念也基本成了 SDN 的标准。我们希望能通过 OVN 不仅仅是引入一些高级功能,还能引入一些比较成熟的网络概念,像 VPC、Subnet、多租户、FIP、SecurityGroup 等等,从整体上增强 Kubernetes 网络的能力。
2、统一网络的数据平面,我们希望把 Kubernetes 作为网络的控制平面,所有数据平面的功能都能通过 OVN 来实现,包括 Service、DNS、NetworkPolicy 都通过 OVN 来实现,简化之后的维护工作。
3、尽可能覆盖其他开源网络方案的功能。对我们来说也不希望同时支持多个网络插件,每个客户都不一样,这样对我们成本也很高。我们自己希望有这么一个跟水桶机一样的网络方案要的功能都覆盖了,还能有些特色,这样是最好的。
4、尽可能的易于安装使用。OVN、OVS 这套东西本身的安装和使用都还是比较复杂,门槛比较高我们希望能进行简化,降低用户使用的门槛。方便交付,也方便更好的推广。
先看一下组件的架构,Kube-OVN 自身的安装 yaml 里包含了 OVN 和 OVS 的安装和配置,Kube-OVN 自身的逻辑主要集中在图中蓝色的部分 kube-ovn-controller,kube-ovn-cni 和 kube-ovn-cniserver。其中最主要的逻辑在 kube-ovn-controller 可以看成是一个 Kubernetes 资源的控制器,它会 watch Kubernetes 内所有和网络相关的资源变化,例如 Pod、Node、Namespace、Service、Endpoint 和 NetworkPolicy。每当资源发生变化 kube-ovn-controller 会计算预期的状态,并将网络对应的变化翻译成 OVN 北向数据库的资源对象。同时 kube-ovn-controller 会将配置具体网络的信息,例如分配的 IP、Mac、网关等信息再以 Annotation 的方式回写到 Kubernetes 的资源里,方便后续的处理。
kube-ovn-cni 本身是很薄的一层,主要工作是适配 CNI 的协议和 Kubelet 对接,将标准的 cni add/del 命令发送到每台机器上的 kube-ovn-cniserver 进行后续处理。而 kube-ovn-cniserver 会根据传入的参数反查 Kubernetes 中资源对应的 Annotation,操作每台机器上的 OVS 以及容器网络。
举一个创建 Pod 的例子,Pod 下发到 apiserver 后 kube-ovn-controller 会 watch 的新生成了一个 Pod,然后调用 ovn-nb 的接口去创建一个虚拟交换机接口,成功后将 OVN 分配的 IP、Mac、GW 等信息反写到这个 Pod 的 Annotation 中。接下来 kubelet 创建 Pod 时会调用 kube-ovn-cni,kube-ovn-cni 将信息传递给 kube-ovn-cniserver。CNIServer 会反查 Pod 的 Annotation 获得具体的 IP 和 Mac 信息来配置本地的 OVS 和容器网卡,完成整个工作流。其他的 Service、NetworkPolicy 的流程也是和这个类似的。
Flannel 和很多网络的实现上都是一个 Node 一个子网,我们发现这种子网模型很不灵活,而且也很难扩展。因此在 Kube-OVN 里我们采用了一个 Namespace 一个子网的模型,子网是可以跨节点的这样比较符合用户的预期和管理。每个子网对应着 OVN 里的一个虚拟交换机,LB、DNS 和 ACL 等流量规则现在也是应用在虚拟交换机上,这样方便我们之后做更细粒度的权限控制,例如实现 VPC,多租户这样的功能。
所有的虚拟交换机目前会接在一个全局的虚拟路由器上,这样可以保证默认的容器网络互通,未来要做隔离也可以很方便的在路由层面进行控制。此外还有一个特殊的 Node 子网,会在每个宿主机上添加一块 OVS 的网卡,这个网络主要是把 Node 接入容器网络,使得主机和容器之间网络可以互通。需要注意的是这里的虚拟交换机和虚拟路由器都是逻辑上的,实现中是通过流表分布在所有的节点上的,因此并不存在单点的问题。
网关负责访问集群外部的网络,目前有两种实现,一种是分布式的,每台主机都可以作为运行在自己上面的 Ood 的出网节点。另一种是集中式的,可以一个 Namespace 配置一个网关节点,作为当前 Namespace 里的 Pod 出网所使用的网关,这种方式所有出网流量用的都是特定的 IP nat 出去的,方便外部的审计和防火墙控制。当然网关节点也可以不做 nat 这样就可以把容器 IP 直接暴露给外网,达到内外网络的直连。
Kube-OVN 是一个符合 CNI 规范的网络组件,其运行需要依赖 Kubernetes 环境及对应的内核网络模块。 以下是通过测试的操作系统和软件版本,环境配置和所需要开放的端口信息。
注意事项:
(1)如果内核版本为 3.10.0-862 内核 netfilter 模块存在 bug 会导致 Kube-OVN 内置负载均衡器无法工作,需要对内核升级,建议使用 CentOS 官方对应版本最新内核保证系统的安全。相关内核 bug 参考 Floating IPs broken after kernel upgrade to Centos/RHEL 7.5 - DNAT not working。
(2)Rocky Linux 8.6 的内核 4.18.0-372.9.1.el8.x86_64 存在 TCP 通信问题 TCP connection failed in Rocky Linux 8.6,请升级内核至 4.18.0-372.13.1.el8_6.x86_64 或更高版本。
(3)如果内核版本为 4.4 则对应的内核 openvswitch 模块存在问题,建议升级或手动编译 openvswitch 新版本模块进行更新
(4)Geneve 隧道建立需要检查 IPv6,可通过 cat /proc/cmdline 检查内核启动参数, 相关内核 bug 请参考 Geneve tunnels don't work when ipv6 is disabled。
Kube-OVN 提供了一键安装脚本,可以帮助你快速安装一个高可用,生产就绪的 Kube-OVN 容器网络,默认部署为 Overlay 类型网络。
下载稳定版本安装脚本
wget https://raw.githubusercontent.com/kubeovn/kube-ovn/release-1.10/dist/images/install.sh
如果对 master 分支的最新功能感兴趣,想使用下面的命令下载开发版本部署脚本:
wget https://raw.githubusercontent.com/kubeovn/kube-ovn/master/dist/images/install.sh
修改配置参数
使用编辑器打开脚本,并修改下列变量为预期值:
REGISTRY="kubeovn" # 镜像仓库地址
VERSION="v1.10.6" # 镜像版本/Tag
POD_CIDR="10.16.0.0/16" # 默认子网 CIDR 不要和 SVC/NODE/JOIN CIDR 重叠
SVC_CIDR="10.96.0.0/12" # 需要和 apiserver 的 service-cluster-ip-range 保持一致
JOIN_CIDR="100.64.0.0/16" # Pod 和主机通信网络 CIDR,不要和 SVC/NODE/POD CIDR 重叠
LABEL="node-role.kubernetes.io/master" # 部署 OVN DB 节点的标签
IFACE="" # 容器网络所使用的的宿主机网卡名,如果为空则使用 Kubernetes 中的 Node IP 所在网卡
TUNNEL_TYPE="geneve" # 隧道封装协议,可选 geneve, vxlan 或 stt,stt 需要单独编译 ovs 内核模块
可使用正则表达式来匹配网卡名,例如 IFACE=enp6s0f0,eth.*
。
执行安装脚本
bash install.sh
sealos 作为 Kubernetes 的一个发行版,通过极简的使用方式和国内的镜像仓库,可以帮助用户快速从零初始化一个容器集群。 通过使用 sealos 用户可以通过一条命令在几分钟内部署出一个安装好 Kube-OVN 的 Kubernetes 集群。
下载安装sealos
wget https://github.com/labring/sealos/releases/download/v4.0.0/sealos_4.0.0_linux_amd64.tar.gz
&& tar zxvf sealos_4.0.0_linux_amd64.tar.gz sealos && chmod +x sealos && mv sealos /usr/bin
部署K8s和kube-ovn
sealos run labring/kubernetes:v1.24.3 labring/kube-ovn:v1.10.5 \
--masters [masters ips seperated by comma] \
--nodes [nodes ips seperated by comma] -p [your-ssh-passwd]
参考资料:
https://kubeovn.github.io/docs/v1.10.x/
https://www.alauda.cn/open/detail/id/377.html
https://cloud.tencent.com/developer/article/1475917