Networkpolicy的含意与现状

networkpolicy是k8s在很早就提出的一个抽象概念。它用一个对象来形容一类pod的网络出入站规定。对于networkpolicy的语义能够参考我之前的文章

networkpolicy的作用对象是pod,作用成果包含出站、入站,作用成果拓扑包含IP段、namespace、pod、端口、协定。

与以往IaaS服务场景下,针对虚拟机、网卡对象的平安组规定不同,networkpolicy是k8s原语。因而,在k8s场景下,进行网络安全规定的布局时,用networkpolicy能做到更加的灵便和自动化。举个例子:

有一套工作负载A是做相似数据库代理一类的工作,它只容许代理服务B拜访,不容许其余业务拜访。

  • 在k8s场景下,如果不应用networkpolicy,咱们须要布局好A类pod的部署节点,配置相应的ACL规定,将B类pod的IP予以放行,一旦A/B类pod做了扩缩容,可能要在重新配置一份甚至多份ACL规定。
  • 在k8s场景下,咱们会给A和B类别离配置label,创立好networkpolicy后限度A只放行B类pod,每当A或B扩缩容时,无需做任何额定操作。

网易数帆的networkpolicy反对

网易数帆的云计算业务的内部用户中,基于交付的openshift-sdn计划或calico计划,这些计划都能够原生地反对networkpolicy(下文会介绍)。

但云计算业务的外部用户(应用vpc或bgp CNI)大多是由PE布局治理IP白名单,限度某些网络拜访,除此之外没有做任何跨业务的网络限度(比如说:离线转码业务与领取业务是互不相干的,然而两种业务的pod彼此网络是可通信的)。因而始终没有networkpolicy的需要,而vpc、bgp等外部应用的CNI也还始终没有实现相干性能。

将来随着业务规模的扩充,相似的网络安全策略是必不可少的,因而咱们会在接下来逐渐将networkpolicy enable。

业界的networkpolicy实现

以后社区对于k8s的networkpolicy的实现,不外乎三种计划:

计划依赖案例反对的CNI
基于iptables+ipset实现规定容器流量须要通过宿主机的协定栈calico felixcalico、flannel、terway
基于ovs流表实现规定应用openvswitchopenshift-sdnopenshift-sdn
基于ebpf hook实现规定须要较高版本内核ciliumcilium、flannel、terway

从下面的表格能够看出:

  1. 基于ovs流表实现的计划,典型的就是openshift-sdn,此前咱们分享过一篇openshift-sdn的详解,介绍了外面对ovs table的设计,其中有一个专门的table(tableid=21)就是用来实现networkpolicy的规定。 该计划是间接内建于openshift-sdn我的项目,根本无奈移植。 而openshift-sdn尽管代码开源,但设计上、代码逻辑上与openshift平台耦合还是比拟严密的。比如说:

    1. 公开的openshift-sdn部署计划须要依赖openshift-network-operator
    2. openshift-sdn代码中硬编码了要拜访的容器运行时为crio,不反对dockershim
  2. cilium是最先应用ebpf技术实现网络数据面的CNI,它力求实现大而全的容器网络,封装、加密、全面、高性能等特点包罗万象,它对于networkpolicy的反对也曾经非常欠缺。但ebpf hook的实现形式,依赖较高的内核版本,且在数据面排障时比拟吃力。ebpf技术对于网络性能的晋升很大,将来势必会越来越风行,所以值得关注。
  3. 基于iptables+ipset技术实现的计划,其实在几年前就比拟成熟了calico-felix、romana、kube-router等开源的网络计划都是基于此实现了反对networkpolicy。其中,felix是calico网络计划中的一个组件,官网反对在calico中enable networkpolicy,且可能与flannel配合应用。阿里云的terway便是间接套用felix实现了对networkpolicy的反对(最近还套用了cilium)。这套计划要求容器流量要进过宿主机协定栈,否则包就不会进入内核的netfilter模块,iptables规定就无奈失效。

指标

基于上述现状,咱们心愿基于现有的开源实现计划,进行兼容性调研或革新,适配网易数帆的各种网络计划,如:

  • netease-vpc
  • netease-bgp
  • flannel
  • ...

因为这些网络计划都满足felix的要求,同时felix有较为沉闷的社区和较多的适配案例,因而咱们决定基于felix,实现一套即插即用的networkpolicy addon。本文接下来将会着重介绍该计划的实现。

calico/felix的设计实现

架构

calico在部署架构上做了屡次演进,咱们以最新版本v3.17.1为准。calico的残缺架构包含了若干组件:

  • calico/kube-controllers: calico控制器,用于监听一些k8s资源的变更,从而进行相应的calico资源的变更。例如依据networkpolicy对象的变更,变更相应的calicopolicy对象
  • pod2daemon: 一个initcontainer,用于构建一个Unix Domain Socket,来让Felix程序与Dikastes(calico中反对istio的一种sidecar,详见calico的istio集成)进行加密通信.
  • cni plugin / ipam plugin: 规范的CNI插件,用于配置/解除网络;调配/回收网络配置
  • calico-node calico-node其实是一个数据面工具总成,包含了:

    • felix: 治理节点上的容器网卡、路由、ACL规定;并上报节点状态
    • bird/bird6: 用来建设bgp连贯, 并依据felix配置的路由,在不同节点间散发
    • confd: 依据以后集群数据生成本地brid的配置
  • calicoctl: calico的CLI工具。
  • datastore plugin: 即calico的数据库,能够是独立的etcd,也能够以crd形式记录于所在集群的k8s中
  • typha: 相似于数据库代理,能够尽量少防止有大量的连贯建设到apiserver。实用于超过100个node的集群。

官网给出了calico整体的组件架构图:

原理

在网络连通性(Networking)方面:calico的数据面是非常简单的三层路由转发。路由的学习和散发由bgp协定实现。如果k8s的上层是VPC之类的三层网络环境,则须要进行overlay,calico反对ipip封装实现overlay。

在网络安全性方面:calico思考到其Networking是依赖宿主机协定栈进行路由转发实现的,因而能够基于iptables+ipset进行流量标记、地址集布局、流量解决(放行或DROP),并且基于这些操作能够实现:

  1. networkpolicy的抽象概念
  2. calico自定义的networkpolicy,为了在openstack场景下利用而设计
  3. calico自定义的profile,已废除。

这里所有的iptables规定都作用在:

  1. pod在宿主机namespace中的veth网卡(calico中将之称为workload)
  2. 宿主机nodeIP所在网卡(calico中将之称为host-endpoint,实际上这部分规定不属于k8s的networkpolicy领域)。

次要包含如下几类规定:

  • iptables的INPUT链规定中,会先跳入cali-INPUT 链,在cali-INPUT链中,会判断和解决两种方向的流量:

    • pod拜访node(cali-wl-to-host)实际上这个链中只走了cali-from-wl-dispatch链,如果是利用在openstack中,该链还会容许拜访metaserver;如果应用ipv6,该链中还会容许收回icmpv6的一系列包
    • 来自node的流量(cali-from-host-endpoint)
  • iptables的OUTPUT链中,会首先跳入cali-OUTPUT链,在cali-OUTPUT链中,次要会解决:

    • 拜访node的流量(cali-to-host-endpoint)的流量
  • iptables的FORWARD链中,会首先跳入cali-FORWARD链,在cali-FORWARD链中会解决如下几种流量:

    • 来自node转发的流量cali-from-hep-forward
    • 从pod中收回的流量cali-from-wl-dispatch
    • 达到pod的流量cali-to-wl-dispatch
    • 达到node的转发流量cali-to-hep-forward
    • 纯正的IP段到IP段的转发流量cali-cidr-block

k8s的networkpolicy只须要关注上述流量中与pod相干的流量,因而只须要关怀:

  • cali-from-wl-dispatch
  • cali-to-wl-dispatch

这两个链的规定,对应到pod的egress和ingress networkpolicy。

1. 除了nat表,在raw和mangle表中还有对calico关注的网卡上的收发包进行初始标记的规定,和最终的判断规定。2. 在https://github.com/projectcalico/felix/blob/master/rules/static.go中能够看到残缺的动态iptables表项的设计

接着,iptables规定中还会在cali-from-wl-dispatchcali-to-wl-dispatch两个链中依据收包/发包的网卡判断这是哪个pod,走到该pod的egress或ingress链中。每个pod的链中则又设置了对应networkpolicy实例规定的链,以此递归调用。

这样,pod的流量通过INPUT/OUTPUT/FORWARD等链后,递归地走了多个链,每个链都会Drop或者Return,如果把链表走一遍下来始终Return,会Return到INPUT/OUTPUT/FORWARD, 而后执行ACCEPT,也就是说这个流量满足了某个networkpolicy的规定限度。如果过程中被Drop了,就示意受某些规定限度,这个链路不通。

咱们通过一个简略的例子来形容iptables这块的链路程序。

felix实现networkpolicy的案例

假如有如下一个networkpolicy:

  spec:    egress:    - {}    ingress:    - from:      - podSelector:          matchLabels:            hyapp: client1    - from:      - ipBlock:          cidr: 10.16.2.0/24          except:          - 10.16.2.122/32      ports:      - port: 3456        protocol: TCP    podSelector:      matchLabels:        hyapp: server
  • 他作用于有hyapp=server的label的pod
  • 这类pod出方向不限度
  • 这类pod的入站规定中只容许如下几种流量:

    • 来自于有hyapp=client1的label的pod
    • 10.16.2.0/24网段中除了10.16.2.122/32以外的IP能够拜访该类pod的3456 TCP端口。

咱们应用iptables -Liptables-save 命令来剖析机器上的iptables规定。

因为是入站规定,所以咱们能够察看iptables表中的cali-to-wl-dispatch链。另外,该networkpolicy的作用pod只有一个,它的host侧网卡是veth-13dd25c5cb。咱们能够看到如下的几条规定:

Chain cali-to-wl-dispatch (1 references)target     prot opt source               destinationcali-to-wl-dispatch-0  all  --  anywhere             anywhere            [goto]  /* cali:Ok_j0t6AwtLyoFYU */cali-tw-veth-13dd25c5cb  all  --  anywhere             anywhere            [goto]  /* cali:909gC5dwdBI3E96S */DROP       all  --  anywhere             anywhere             /* cali:4M4uUxEEGrRKj1PR */ /* Unknown interface */

留神,这里有一个cali-to-wl-dispatch-0的链,是用来做前缀映射的, 该链的规定下蕴含所有cali-tw-veth-0 这个前缀的链:

Chain cali-to-wl-dispatch-0 (1 references)target     prot opt source               destinationcali-tw-veth-086099497f  all  --  anywhere             anywhere            [goto]  /* cali:Vt4xxuTYlCRFq62M */cali-tw-veth-0ddbc02656  all  --  anywhere             anywhere            [goto]  /* cali:7FDgBEq4y7PN7kMf */DROP       all  --  anywhere             anywhere             /* cali:up42FFMQCctN8FcW */ /* Unknown interface */

这是felix设计上用于缩小iptables规定遍历次数的一个优化伎俩。

咱们通过iptables-save |grep cali-to-wl-dispatch命令,能够发现如下的规定:

cali-to-wl-dispatch -o veth-13dd25c5cb -m comment --comment "cali:909gC5dwdBI3E96S" -g cali-tw-veth-13dd25c5cb

意思就是:在cali-to-wl-dispatch链中,依据pod在host侧网卡的名字,会执行cali-tw-veth-13dd25c5cb链, 咱们再看这条链:

   Chain cali-tw-veth-13dd25c5cb (1 references)   target     prot opt source               destination1  ACCEPT     all  --  anywhere             anywhere             /* cali:RvljGbJwZ8z9q-Ee */ ctstate RELATED,ESTABLISHED2  DROP       all  --  anywhere             anywhere             /* cali:krH_zVU1BetG5Q5_ */ ctstate INVALID3  MARK       all  --  anywhere             anywhere             /* cali:Zr20J0-I__oX_Y2w */ MARK and 0xfffeffff4  MARK       all  --  anywhere             anywhere             /* cali:lxQlOdcUUS4hyf-h */ /* Start of policies */ MARK and 0xfffdffff5  cali-pi-_QW8Cu1Tr3dYs2pTUY0-  all  --  anywhere             anywhere             /* cali:d2UTZGk8zG6ol0ME */ mark match 0x0/0x200006  RETURN     all  --  anywhere             anywhere             /* cali:zyuuqgEt28kbSlc_ */ /* Return if policy accepted */ mark match 0x10000/0x100007  DROP       all  --  anywhere             anywhere             /* cali:DTh9dO0o6NsmIQSx */ /* Drop if no policies passed packet */ mark match 0x0/0x200008  cali-pri-kns.default  all  --  anywhere             anywhere             /* cali:krKqEtFijSLu5oTz */9  RETURN     all  --  anywhere             anywhere             /* cali:dgRtRf38hD2ZVmC7 */ /* Return if profile accepted */ mark match 0x10000/0x1000010 cali-pri-ksa.default.default  all  --  anywhere             anywhere             /* cali:NxmrZYbhCNLKgL6O */11 RETURN     all  --  anywhere             anywhere             /* cali:zDbjbrN6JPMZx9S1 */ /* Return if profile accepted */ mark match 0x10000/0x1000012 DROP       all  --  anywhere             anywhere             /* cali:d-mHGbHkL0VRl6I6 */ /* Drop if no profiles matched */
  • 第1、2条:如果ct表中能检索到该连贯的状态,咱们间接依据状态来确定这个流量的解决形式,这样能够省略很大一部分工作。
  • 第3条:先对包进行标记(将第17地位0),在本链的规定执行结束后,会判断标记是否match(判断第17位是否有被置1),不匹配(没有被置1)就DROP;
  • 第4条:如果该网卡对应的pod有相干的networkpolicy,要再打一次mark,与之前的mark做与计算后目前mark应该是0xfffcffff(17、18位为0);
  • 第5条:如果包mark match 0x0/0x20000(第18位为0), 执行cali-pi-_QW8Cu1Tr3dYs2pTUY0-链进入networkpolicy的判断。
  • 第6、7条:如果networkpolicy查看通过,会对包进行mark批改, 所以查看是否mark match 0x10000/0x10000, 匹配阐明通过,间接RETURN,不再查看其余的规定;如果mark没有批改,与原先统一,视为没有任何一个networkpolicy容许该包通过,间接DROP
  • 第8、9、10、11条:当没有任何相干的networkpolicy时(即第4~7条不存在)才会被执行,执行calico的profile策略,分成namespace维度和serviceaccount维度,如果在这两个策略里没有对包的mark做任何批改,就示意通过。这两个策略是calico的概念,且为了不与networkpolicy混同,曾经被弃用了。因而此处都是空的。
  • 第12条:如果包没有进入 上述两个profile链,DROP。

接着看networkpolicy的链cali-pi-_QW8Cu1Tr3dYs2pTUY0-,只有在这个链里执行Return前有将包打上mark使其match 0x10000/0x10000,就示意匹配了某个networkpolicy规定,包容许放行:

Chain cali-pi-_QW8Cu1Tr3dYs2pTUY0- (1 references)target     prot opt source               destinationMARK       all  --  anywhere             anywhere             /* cali:fdm8p72wShIcZesY */ match-set cali40s:9WLohU2k-3hMTr5j-HlIcA0 src MARK or 0x10000RETURN     all  --  anywhere             anywhere             /* cali:63L9N_r1RGeYN8er */ mark match 0x10000/0x10000MARK       all  --  anywhere             anywhere             /* cali:xLfB_tIU4esDK000 */ MARK xset 0x40000/0xc0000MARK       all  --  10.16.2.122          anywhere             /* cali:lUSV425ikXY6zWDE */ MARK and 0xfffbffffMARK       tcp  --  10.16.2.0/24         anywhere             /* cali:8-qnPNq_KdC2jrNT */ multiport dports 3456 mark match 0x40000/0x40000 MARK or 0x10000RETURN     all  --  anywhere             anywhere             /* cali:dr-rzJrx0I6Vqfkl */ mark match 0x10000/0x10000
  • 第1、2条:如果src ip match ipset:cali40s:9WLohU2k-3hMTr5j-HlIcA0 ,将包 mark or 0x10000, 并查看是否match,match就RETUR。 咱们能够在机器上执行ipset list cali40s:9WLohU2k-3hMTr5j-HlIcA0 , 能够看到这个ipset里蕴含的就是networkpolicy中指明的、带有hyapp=client1这个label的两个pod的ip。
  • 第3、4、5、6条则是针对networkpolicy中的第二局部规定,先对包设置正向标记,而后将要隔离的src IP/IP段进行判断并做反向标记,接着判断src段是否在准入范畴,如果在,并且目标端口匹配,并且标记为正向,就再对包进行MARK or 0x10000 , 这样,最终判断match了就会Return。
  • 实际上咱们能够看到,这里就算不match,这个链执行完了也还是会RETURN的,所以这个链执行的后果是通过mark返回给上一级的,这就是为什么调用该链的上一级,会在调用结束后要判断mark并确认是否ACCEPT。

至此,一个残缺的networkpolicy的实现链路就实现了。

egress规定与上述ingress规定相似。 能够参考下图:

通用的felix插件设计

如果你看了上文calico/felix的设计实现,你就会发现原理其实非常简单,这个设计齐全能够利用到任何一个“基于三层路由转发”的网络计划中。但理论利用过程中咱们还是遇到了一些问题。

问题1:networkpolicy-only

咱们晓得,较新版本的felix都是集成到calico-node组件中运行。calico-node默认状况下会实现容器网络和networkpolicy两块工作,如何部署一个只负责实现networkpolicy规定的calico-node呢?

能够参考calico官网提供的canal计划是如何适配flannel的。从canal的部署模板中咱们能够根本确认,只有部署好kube-controllers,pod2daemon,calico-node并且通过环境变量管制calico-nodeCALICO_NETWORKING环境变量为"false"(禁止配置容器网络)即可。

问题2:网卡名映射

咱们尝试在轻舟k8s集群(应用网易云VPC作为容器网络)中尝试以这样的形式部署一套calico套件,部署后,咱们会发现calico-node的日志里定期报错,提醒:找不到cali****的网卡,无奈配置iptables规定。 有用过calico的同学应该看得明确,cali是calico计划在宿主机侧生成的网卡名前缀。而咱们基于网易云VPC设计的容器网络计划,会以veth-为容器hostveth前缀。如果calico是基于前缀来找到容器网卡的,那么是否有参数能够指定前缀呢?

官网的felix配置文档中提到:能够应用InterfacePrefix参数或FELIX_INTERFACEPREFIX环境变量,决定felix要检索的host侧网卡前缀。一开始看到这个阐明令人欣喜万分。然而当咱们理论配置了之后,会发现,calico-node还是会报错,提醒: 找不到veth-*****的网卡,这个网卡名超过了linux内核的常数限度(15个字符)

咱们依照日志里打印的网卡名去找,的确找不到这个网卡,看来必须要搞清楚calico是如何给host侧的网卡进行命名的。

calico为pod的veth命名的规定实现在libcalico-go我的项目中,存在如下的一个接口

type WorkloadEndpointConverter interface {    VethNameForWorkload(namespace, podName string) string    PodToWorkloadEndpoints(pod *kapiv1.Pod) ([]*model.KVPair, error)}

这个接口用用来实现pod映射到workload的,同时还能依据pod的信息,推导pod的hostveth网卡名是啥,该接口只有一种实现:defaultWorkloadEndpointConverter, 其中VethNameForWorkload的实现如下:

// VethNameForWorkload returns a deterministic veth name// for the given Kubernetes workload (WEP) name and namespace.func (wc defaultWorkloadEndpointConverter) VethNameForWorkload(namespace, podname string) string {    // A SHA1 is always 20 bytes long, and so is sufficient for generating the    // veth name and mac addr.    h := sha1.New()    h.Write([]byte(fmt.Sprintf("%s.%s", namespace, podname)))    prefix := os.Getenv("FELIX_INTERFACEPREFIX")    if prefix == "" {        // Prefix is not set. Default to "cali"        prefix = "cali"    } else {        // Prefix is set - use the first value in the list.        splits := strings.Split(prefix, ",")        prefix = splits[0]    }    log.WithField("prefix", prefix).Debugf("Using prefix to create a WorkloadEndpoint veth name")    return fmt.Sprintf("%s%s", prefix, hex.EncodeToString(h.Sum(nil))[:11])}

能够看到,calico依据pod的namespace和name进行hash,而后依据FELIX_INTERFACEPREFIX环境变量的值决定网卡名前缀,将前缀与hash的前11个字符拼凑起来。 libcalico-go是所有calico组件的lib库,也就是说,不论是calico-cni去创立veth,还是felix去依据pod查找对应的网卡, 都是基于这个逻辑去匹配的。

显然这个代码破绽很大!calico没有对前缀做长度查看,这里要填充hash的前11位,齐全是因为默认的前缀是四个字符的cali

问题十分明确了,要想在本人的网络计划下无痛享受felix,就得本人实现一个WorkloadEndpointConverter接口,并编译出定制化的calico-node镜像。

案例1: canal如何接入

从canal的部署模板中咱们就能够看得出来,canal计划中应用的CNI plugin实际上也是calico,只不过calico只负责创立veth对,配置IP和路由等工作,veth的命名交给calico来做,天然就依照calico的官网配置来命名了,理论应用过程中就能够看到,canal计划下容器在宿主机上的veth名称也是cali前缀。

案例2:阿里云terway如何接入

阿里云的ACK应用其自研的terway来作为容器网络计划。terway中反对两种容器网卡虚拟化计划:

  • veth
  • ipvlan L2

veth计划下会应用felix来实现networkpolicy,而ipvlan下则应用cilium。咱们此处次要关注veth计划。

veth计划下felix是如何应用的呢?terway在部署时,间接基于社区v3.5.8版本的felix代码进行编译(编译前还往代码中退出了一个terway自定义的patch),将编译进去的felix二进制文件丢到terway的docker镜像中, daemonset里启动三个terway镜像容器,别离用于装置cni插件;运行agent;运行felix。

terway是如何实现兼容felix的呢?上文提到的网卡名的问题,它如何解决呢?

通过浏览terway的源码 ,咱们发现terway做得比拟暴力——间接复用了calico代码中的网卡命名形式,对host侧的veth进行命名,网卡前缀为硬编码的cali

案例3:网易云k8s如何接入

网易云的场景中,host侧网卡命名是以某个前缀加上pod的sandbox容器id来命名的(起因见下文)。因而咱们即使把前缀改成cali或者其余长度4以内的字符串,felix也无奈基于calico的那套逻辑找到网卡。

因而咱们改写了该接口。实现了一个sandboxWorkloadEndpointConverter, 将VethNameForWorkload做了另一种实现:

  1. 依据felix参数感知自定义的网卡名前缀,这里为了防止prefix太长,导致网卡名抵触,对prefix长度进行限度,倡议不超过5个字符,至多给后缀保留10个字符(咱们已经在线上环境呈现过同一个节点的两个podsandbox容器id前9位完全相同的状况)
  2. 依据pod信息获取到他对应的sandbox容器ID,取其15-len(prefix)位作为后缀。
  3. 通过前缀与sandboxID后缀形成workload的网卡名。

将来咱们会尝试对这部分代码做更通用化的革新,反对多种前缀,并反对主动选用网卡命名办法。

为什么咱们要以podsandbox容器id来命名网卡?

因为理论应用过程中咱们发现,kubelet对于sandbox容器的解决并不一定是有序的,可能呈现如下场景:

  1. 为poda创立出sandbox1, 调用CNI ADD失败,但veth曾经创立;
  2. 为poda创立出sandbox2, 调用 CNI ADD胜利,间接应用了上一次创立的veth;
  3. 删除此前曾经失败的sandbox1,调用 CNI DEL。 将第2步创立的veth删除,导致poda的网络异样

因而,如果kubelet调用CNI是以sandbox为粒度,那么咱们创立的资源就理当也以sandbox为粒度。

编译与构建

目前咱们将通用的felix基于calico/node的v3.17分支构建, 并将它援用的libcalico-gofork到网易云的github organization我的项目:163yun/libcalico-go,并建设分支tag:v1.7.2-nks.1

这样,咱们能够间接拉取社区代码,进行编译:

cd $GOPATH/srcmkdir -p github.com/projectcalicocd github.com/projectcalicogit clone https://github.com/projectcalico/nodecd node# 批改依赖包,改为援用咱们批改过后的libcalico-gogo mod edit -replace=github.com/projectcalico/libcalico-go=github.com/163yun/libcalico-go@v1.7.2-nks.1# 编译出calico/node的docker  imagemake calico/nodedocker tag calico/node:latest-amd64 $EXPECTED_IMAGE_PATH:$EXPECTED_IMAGE_TAG

编译构建过程中可能呈现一些网络起因导致编译阻塞:

  • 编译过程中会在容器里进行go build,为了不便执行go module,所以倡议在Makefile、以及执行make时下载的长期版本Makefile.common.v***文件中的局部地位注入环境变量:GOPROXY=https://goproxy.cn
  • 编译结束后构建docker image时,会在根底镜像中下载安装多个依赖工具,可能呈现yum源无奈解析等问题,倡议在Makefile文件中调用docker build的语句里追加参数--network=host

测试方法

首先咱们要筹备好网易轻舟k8s集群,并应用vpc或bgp网络计划,并额定部署felix套件(参考上图)。

咱们应用sonobuoy工具进行测试工作,该工具也能够素来进行k8s集群的conformance认证。下载该工具的二进制文件,而后执行:

sonobuoy  run --e2e-focus="\[Feature:NetworkPolicy\]" --e2e-skip="" --image-pull-policy IfNotPresent 

即可在以后集群里进行networkpolicy相干的e2e测试(并且测试过程创立的pod的imagePullPolicy都是IfNotPresent)。

执行命令后能够查看集群中的pods,会看到sonobuoy的pod以及它创立进去的一些e2e相干的pod,如果有pod阻塞于ImagePullBackoff,能够尝试在pod所在节点上拉取备用镜像并批改成所需镜像:

docker pull hub.c.163.com/combk8s/conformance:v1.19.3docker tag hub.c.163.com/combk8s/conformance:v1.19.3 k8s.gcr.io/conformance:v1.19.3docker pull hub.c.163.com/combk8s/e2e-test-images/agnhost:2.20docker tag hub.c.163.com/combk8s/e2e-test-images/agnhost:2.20 k8s.gcr.io/e2e-test-images/agnhost:2.20

测试结束后,实践上所有e2e前缀的pod都会被删除,此时执行sonobuoy retrieve命令, 会在当前目录生成一个tar.gz文件,解压该文件,并读取plugins/e2e/results/global/e2e.log , 就能够看到整个e2e测试的执行后果。 也能够通过plugins/e2e/sonobuoy_results.yaml文件查看,但这个文件内容包含了未执行的用例,可读性可能不太好。

简要的e2e测试后果如下:

root@pubt2-nks-for-dev6:/home/hzhuangyang1/plugins/e2e/results/global# tail -n 10 e2e.logJUnit report was created: /tmp/results/junit_01.xml{"msg":"Test Suite completed","total":29,"completed":29,"skipped":5204,"failed":0}Ran 29 of 5233 Specs in 4847.335 secondsSUCCESS! -- 29 Passed | 0 Failed | 0 Pending | 5204 SkippedPASSGinkgo ran 1 suite in 1h20m48.75547671sTest Suite Passed

总结

本文介绍了networkpolicy的特点和劣势,并剖析了当下支流的networkpolicy实现计划——calico-felix,摸索了calico-felix通用化革新的计划和落地。随着calico-felix的引入,用户能同时享受到vpc的易扩展性和networkpolicy的灵活性。

将来咱们还将着力引入cilium实现高内核版本下、基于ebpf实现的networkpolicy,并实现networkpolicy拓扑可视化。