OCP4.6目前已经发布。在这个版本OCP中,正式支持OVN-Kubernets。大魏认为这是一个重大进步和提升。进步和提升在哪?灵魂拷问x5一下。


拷问1:OVN-Kubernets对于OCP是否正式可用,优势在哪?

可用!

OpenShift 4.6默认支持两种网络模式:OpenShift SDN和OVN-Kubernetes。下表总结了两种模式当前功能支持:

OVN,你究竟对OpenShift做了啥!灵魂拷问x5_java

上图中OVN不支持的egress router的功能,本身在OCP4中也基本不用了。所以说,OVN可以覆盖生产上对OpenShift SDN方面的需求。


关于优势,先说结论:

1. OCP4.6上的OVN-Kubernetes 可以完全替代原有的OpenShift-SDN。 

2.OVN-K8S可以设置通过GENEVE实现overlay而不是VxLAN的方式,这样大幅提升了封包解包效率。 

3. OVN中的Service实现,不再需要Iptables,而是使用OVN LBs,效率提升。

4.OVN中的NAT,不需要通过Iptables实现,通过OVN LBs实现,效率提升。

OVN,你究竟对OpenShift做了啥!灵魂拷问x5_java_02



拷问2:OVN究竟咋来的。

OVN(即Open Virtual Network)是一款支持虚拟网络抽象的软件系统。OVN在OVS现有功能的基础上原生支持虚拟网络抽象,例如虚拟L2,L3覆盖网络以及完全组。诸如DHCP,DNS的服务也是其关注的内容。说简单点,OVN为OVS提供了一个控制平面:


相比于在OCP上,OVN较早在OpenStack上使用。OVN也是红帽绝对主导的一个开源项目。


OpenStack不是大魏的专攻领域,不展开讨论。


需要注意的是,ovn 跟 openstack 没有必然联系,这俩货没有紧耦合,ovn 跟 openstack 也是通过 plugin/driver 的方式集成在一起的。





拷问3:如何在OCP上使用OVN-Kubernetes ?

两个方法:

1.安装OCP的时候,在install.yaml文件中写明

2.OCP安装后,修改network operator


安装OCP的时候,在install.yaml中增加进行配置:

defaultNetwork:

  type: OVNKubernetes 

  ovnKubernetesConfig: 

    mtu: 1400 

    genevePort: 6081 


如果OCP已经安装完,请用如下步骤将OpenShift-SDN更换成OVN-Kubernetes(大魏已验证步骤,准确可用):

首先备份现有OVS的配置,输入以下命令:

[root@lb.weixinyucluster ~]# oc get Network.config.openshift.io cluster -o yaml > cluster-openshift-sdn.yaml


启用迁移,通过如下命令修改Cluster Network Operator 配置对象上设置注释:

[root@lb.weixinyucluster ~]# oc annotate Network.operator.openshift.io cluster \

>   'networkoperator.openshift.io/network-migration'=""

network.operator.openshift.io/cluster annotated



更改默认的CNI网络提供商,输入以下命令:

[root@lb.weixinyucluster ~]# oc patch Network.config.openshift.io cluster \

>   --type='merge' --patch '{ "spec": { "networkType": "OVNKubernetes" } }'

network.config.openshift.io/cluster patched


要确认迁移已禁用OpenShift SDN默认的CNI网络提供程序并删除了所有OpenShift SDN Pod,openshift-sdn中的pod会自动删除:

[root@lb.weixinyucluster ~]#  oc get pod -n openshift-sdn

No resources found in openshift-sdn namespace.



集群中的节点重新引导后,请确认迁移成功,如下命令行输出必须为OVNKubernetes:

[root@lb.weixinyucluster ~]# oc get network.config/cluster -o jsonpath='{.status.networkType}{"\n"}'

OVNKubernetes


确认没有error状态的pod:

[root@lb.weixinyucluster ~]# oc get pods --all-namespaces -o wide --sort-by='{.spec.nodeName}' |grep -i error



从“Cluster Network Operator”配置对象中删除迁移注释,输入以下命令:

[root@lb.weixinyucluster ~]# oc annotate Network.operator.openshift.io cluster \

>   networkoperator.openshift.io/network-migration-

network.operator.openshift.io/cluster annotated


删除openshift-sdn ns:

oc delete namespace openshift-sdn


查看OVN组件:


拷问4:GENEVE实现overlay而不是VxLAN的方式,有啥好处?怎么设置GENEVE模式?

首先说,OVN同时支持VxLAN和GENEVE的overlay实现方式。如果想讲OCP设置成GENEVE模式,需要在安装时进行设置(参加拷问3步骤),安装以后,就没法修改了。


Geneve(Generic Network Virtualization Encapsulation,RFC Draft)是NVo3工作组对VxLAN、NvGRE和STT进行总结后提出的一种网络虚拟化技术,希望形成一种通用的封装格式,以便支持数据中心中隧道机制的后续演化。Geneve是于2015年提出的,很多的vSwitch已经对Geneve提供了支持,一些SmartNIC也能够实现Geneve的硬件卸载。


对于Overlay技术,我们最关心的是性能,那么Geneve和VxLAN性能谁高谁低?如果单纯比较Geneve和VxLAN的性能,那和网卡是否支持对这两种技术的offload有关:


某些offload功能实际上并不是VXLAN特有的。例如,通常所说的“ tx-udp_tnl-segmentation”offload同事适用于VXLAN和Geneve。


可以使用ethtool查看NIC是否支持“ tx-udp_tnl-segmentation”。例如,在不支持的主机上:

[root@lb.weixinyucluster ~]# ethtool -k eth0 | grep tnl-segmentation

tx-udp_tnl-segmentation: off [fixed]


关于两者的性能对比,可以参照下文:

https://blog.russellbryant.net/2017/05/30/ovn-geneve-vs-vxlan-does-it-matter/


大魏抽几个图出来,整体上看:Geneve的网络性能高于VxLAN。

结合OVN,我们建议使用Geneve而不是VxLAN。




拷问5:为啥说OVN中的Service实现,不再需要Iptables,而是使用OVN LBs,怎么证明?

本质上说,OCP/K8S中的Iptables,是被kube-proxy引入的!

Kube-proxy,即Kubernetes network proxy。Kube-proxy部署在每个Node节点上,它是实现KubernetesService的通信与负载均衡机制的重要组件; Kube-proxy负责为Pod创建代理服务,从kube-apiserver获取所有Service信息,并根据Service信息创建代理服务,实现Service到Pod的请求路由和转发,从而实现Kubernetes层级的虚拟转发网络。

也就是说,如果用了OVN下图中用红圈圈起来这一坨,就不存在了,换成OVN实现了(ovn不用安装kube-proxy,也就不用再讨论使用用ipvs替换iptables实现svc的问题了!)。



    

我们分析一下kube-proxy在OpenShift-SDN什么位置:

那么,OCP节点上的kube-proxy是以什么方式运行的呢?


直接从oc get pods --all-namespaces 是grep不出来的。


登录到master节点:

[root@master-0 ~]# ps -ef |grep -i kube-proxy

root     3412213 3412200  0 Jul06 ?        00:04:26 /usr/bin/openshift-sdn-node --proxy-config=/config/kube-proxy-config.yaml --v=2



查到以kube-proxy最终以openshift-sdn-node二进制文件+yaml配置文件实现。但这还不是运行时。



而openshift-sdn-node这个进程,是由名为kubepods-burstable.slice控制的:

[root@master-0 ~]# systemctl status kubepods-burstable.slice |grep -i kube-proxy-config.yaml

           │ │ └─3412213 /usr/bin/openshift-sdn-node --proxy-config=/config/kube-proxy-config.yaml --v=2


我们通过systemctl命令查看到这个进程对用的pod和crio如下(后者是container id):


 ├─kubepods-burstable-pod18c8ff9b_22dc_4cba_8b5a_e81dd4782734.slice

           │ ├─crio-143c9806ad2791bb4170c53566ca6bedb99d0efbc53cc98391cac0e82115ee82.scope

           │ │ └─3412213 /usr/bin/openshift-sdn-node --proxy-config=/config/kube-proxy-config.yaml --v=2



而kubepods-burstable.slice又是kubepods.slice这个systemd的一部分:

[root@master-0 ~]# systemctl status kubepods.slice |grep -i kubepods-burstable.slice

           └─kubepods-burstable.slice


在系统层面通过查看执行二进制文件进程的父进程,也能找到container id:

[root@master-0 ~]# ps -ef |grep -i 3412200

root     2190284 2186215  0 05:56 pts/1    00:00:00 grep --color=auto -i 3412200

root     3412200       1  0 Jul06 ?        00:00:01 /usr/libexec/crio/conmon -s -c 143c9806ad2791bb4170c53566ca6bedb99d0efbc53cc98391cac0e82115ee82 -n k8s_sdn_sdn-9tw2h_openshift-sdn_18c8ff9b-22dc-4cba-8b5a-e81dd4782734_1 -u 143c9806ad2791bb4170c53566ca6bedb99d0efbc53cc98391cac0e82115ee82 -r /usr/bin/runc -b /var/run/containers/storage/overlay-containers/143c9806ad2791bb4170c53566ca6bedb99d0efbc53cc98391cac0e82115ee82/userdata --persist-dir /var/lib/containers/storage/overlay-containers/143c9806ad2791bb4170c53566ca6bedb99d0efbc53cc98391cac0e82115ee82/userdata -


通过 crictl查看container与pod的对应关系(取container名称的前几位)

[root@master-0 ~]# crictl ps - List containers |grep -i 143c9806ad279

143c9806ad279       04783aad75c195935333357d0bd9fdb9341e51e48fee2c520d5871ee6cd47c8c   26 hours ago        Running             sdn                                           1                   ace4388462740


也就是说,每个OpenShift节点的kube-proxy,通过sdn pod运行在各自的节点上。

OVN,你究竟对OpenShift做了啥!灵魂拷问x5_java_03


我们查看一个sdn pod的日志,这正好印证了上面推断的正确性(标黄部分),sdn二进制文件读取/config/kube-proxy-config.yaml在节点启动kube-proxy。

[root@lb.weixinyucluster ~]# oc logs -f sdn-rtwdr

I0706 04:17:47.444754 3209083 cmd.go:123] Reading proxy configuration from /config/kube-proxy-config.yaml

I0706 04:17:47.448591 3209083 feature_gate.go:243] feature gates: &{map[]}

I0706 04:17:47.448712 3209083 cmd.go:227] Watching config file /config/kube-proxy-config.yaml for changes

I0706 04:17:47.448789 3209083 cmd.go:227] Watching config file /config/..2020_07_06_04_17_45.051553485/kube-proxy-config.yaml for changes

I0706 04:17:47.538621 3209083 node.go:147] Initializing SDN node of type "redhat/openshift-ovs-networkpolicy" with configured hostname "worker-1" (IP "192.168.91.21")


我们将OpenShift-SDN换成OVN以后,sdn pod就都被删除了。OVN的在OCP上的具体实现如下:

查看OVN组件:

我从上图看出,OVN结构分为三部分:ovnkube-master(运行在三个master上)、ovnkube-node(运行在所有OCP节点上)、ovs-node(运行在所有OCP节点上)。OVN的组件是以daemonset.apps的方式部署的:


我们对比OVN的架构图:


我们查看ovnkube-master pod(运行在3个master上)包含的容器,我们看一下,这几个容器,不正是上图的CMD相关组件么?


我们查看ovnkube-node(运行在所有OCP节点上)包含的容器,对应OVN架构图中的ovn controller(下图kube-rbac-proxy是个权限的proxy,不是我们之前的kube-proxy实现。。):


ovs-node(运行在所有OCP节点上),实际上对用ovs的实现:



回到拷问题目,我怎么知道OCP现在用的是OVN LB?好办,通过命令行就能看到:

登录ovnkube-node pod的ovn-controller容器,执行(结果太长太长,只列一部分,我我们可以看到所有OCP节点的域名、和所有pod的IP、应用的路由等信息!):

ovn-nbctl list load-balancer

switch e751ee40-d944-435c-a541-e4b378a404fc (ext_worker-2.weixinyucluster.bluecat.ltd)

    port etor-GR_worker-2.weixinyucluster.bluecat.ltd

        type: router

        addresses: ["52:54:17:8a:f3:00"]

        router-port: rtoe-GR_worker-2.weixinyucluster.bluecat.ltd

    port br-ex_worker-2.weixinyucluster.bluecat.ltd

        type: localnet

        addresses: ["unknown"]

switch 7acf5030-9cbe-4b52-97c9-2e9ad9231ed5 (worker-2.weixinyucluster.bluecat.ltd)

    port openshift-marketplace_certified-operators-766bcd6f65-6mjvz

        addresses: ["0a:58:0a:82:02:07 10.130.2.7"]

    port openshift-marketplace_community-operators-7c895d7b67-crzb4

        addresses: ["0a:58:0a:82:02:09 10.130.2.9"]

    port openshift-monitoring_grafana-5d7b5b575b-qwch2

        addresses: ["0a:58:0a:82:02:0c 10.130.2.12"]

    port k8s-worker-2.weixinyucluster.bluecat.ltd

        addresses: ["a6:69:cf:72:11:13 10.130.2.2"]

    port openshift-monitoring_thanos-querier-79d844d9fd-46c77

        addresses: ["0a:58:0a:82:02:0a 10.130.2.10"]

    port openshift-operators_istio-operator-6cfc889cf-p2pgw

        addresses: ["0a:58:0a:82:02:0d 10.130.2.13"]