Kubernetes网络

Kubernetes网络模型

  • IP-per-Pod,每个Pod都拥有一个独立IP地址,Pod内所有容器共享一个网络命名空间
  • 集群内所有Pod都在一个直接连通的扁平网络中,可通过IP直接访问
    • 所有容器之间无需NAT就可以直接互相访问
    • 所有Node和所有容器之间无需NAT就可以直接互相访问
    • 容器自己看到的IP跟其他容器看到的一样
  • Service cluster IP尽可在集群内部访问,外部请求需要通过NodePort、LoadBalance或者Ingress来访问

官方插件

目前,Kubernetes支持以下两种插件:

  • kubenet:这是一个基于 CNI bridge 的网络插件(在 bridge 插件的基础上扩展了 port mapping 和 traffic shaping ),是目前推荐的默认插件
  • CNI:CNI 网络插件,需要用户将网络配置放到/etc/cni/net.d目录中,并将 CNI 插件的二进制文件放入/opt/cni/bin
  • exec:通过第三方的可执行文件来为容器配置网络,已在v1.6中移除,见kubernetes#39254

kubenet

kubenet 是一个基于 CNI bridge 的网络插件,它为每个容器建立一对 veth pair 并连接到 cbr0 网桥上。kubenet在 bridge 插件的基础上拓展了很多功能,包括

  • 使用 host-local IPAM 插件为容器分配 IP 地址, 并定期释放已分配但未使用的 IP 地址

  • 设置 sysctl net.bridge.bridge-nf-call-iptables = 1

  • 为 Pod IP 创建 SNAT 规则

    • -A POSTROUTING ! -d 10.0.0.0/8 -m comment --comment "kubenet: SNAT for outbound traffic from cluster" -m addrtype ! --dst-type LOCAL -j MASQUERADE
  • 开启网桥的 hairpin 和 promisc 模式,允许 Pod 访问它自己所在的 Service IP(即通过 NAT后再访问 Pod 自己)

    1. -A OUTPUT -j KUBE-DEDUP
    2. -A KUBE-DEDUP -p IPv4 -s a:58:a:f4:2:1 -o veth+ --ip-src 10.244.2.1 -j ACCEPT
    3. -A KUBE-DEDUP -p IPv4 -s a:58:a:f4:2:1 -o veth+ --ip-src 10.244.2.0/24 -j DROP
  • HostPort管理以及设置端口映射

  • Traffic shaping,支持通过 kubernetes.io/ingress-bandwidthkubernetes.io/egress-bandwidth 等 Annotation 设置 Pod 网络带宽限制

未来 kubenet 插件会迁移到标准的 CNI 插件(如ptp),具体计划见这里

CNI plugin

安装CNI:

  1. cat <<EOF > /etc/yum.repos.d/kubernetes.repo
  2. [kubernetes]
  3. name=Kubernetes
  4. baseurl=http://yum.kubernetes.io/repos/kubernetes-el7-x86_64
  5. enabled=1
  6. gpgcheck=1
  7. repo_gpgcheck=1
  8. gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
  9. https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
  10. EOF
  11. yum install -y kubernetes-cni

配置CNI brige插件:

  1. mkdir -p /etc/cni/net.d
  2. cat >/etc/cni/net.d/10-mynet.conf <<-EOF
  3. {
  4. "cniVersion": "0.3.0",
  5. "name": "mynet",
  6. "type": "bridge",
  7. "bridge": "cni0",
  8. "isGateway": true,
  9. "ipMasq": true,
  10. "ipam": {
  11. "type": "host-local",
  12. "subnet": "10.244.0.0/16",
  13. "routes": [
  14. { "dst": "0.0.0.0/0" }
  15. ]
  16. }
  17. }
  18. EOF
  19. cat >/etc/cni/net.d/99-loopback.conf <<-EOF
  20. {
  21. "cniVersion": "0.3.0",
  22. "type": "loopback"
  23. }
  24. EOF

更多CNI网络插件的说明请参考CNI 网络插件

Flannel

Flannel是一个为Kubernetes提供overlay network的网络插件,它基于Linux TUN/TAP,使用UDP封装IP包来创建overlay网络,并借助etcd维护网络的分配情况。

  1. kubectl create -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel-rbac.yml
  2. kubectl create -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel.yml

Weave Net

Weave Net是一个多主机容器网络方案,支持去中心化的控制平面,各个host上的wRouter间通过建立Full Mesh的TCP链接,并通过Gossip来同步控制信息。这种方式省去了集中式的K/V Store,能够在一定程度上减低部署的复杂性,Weave将其称为“data centric”,而非RAFT或者Paxos的“algorithm centric”。

数据平面上,Weave通过UDP封装实现L2 Overlay,封装支持两种模式,一种是运行在user space的sleeve mode,另一种是运行在kernal space的 fastpath mode。Sleeve mode通过pcap设备在Linux bridge上截获数据包并由wRouter完成UDP封装,支持对L2 traffic进行加密,还支持Partial Connection,但是性能损失明显。Fastpath mode即通过OVS的odp封装VxLAN并完成转发,wRouter不直接参与转发,而是通过下发odp 流表的方式控制转发,这种方式可以明显地提升吞吐量,但是不支持加密等高级功能。

  1. kubectl apply -f https://git.io/weave-kube

Calico

Calico 是一个基于BGP的纯三层的数据中心网络方案(不需要Overlay),并且与OpenStack、Kubernetes、AWS、GCE等IaaS和容器平台都有良好的集成。

Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息像整个Calico网络内传播——小规模部署可以直接互联,大规模下可通过指定的BGP route reflector来完成。 这样保证最终所有的workload之间的数据流量都是通过IP路由的方式完成互联的。Calico节点组网可以直接利用数据中心的网络结构(无论是L2或者L3),不需要额外的NAT,隧道或者Overlay Network。

此外,Calico基于iptables还提供了丰富而灵活的网络Policy,保证通过各个节点上的ACLs来提供Workload的多租户隔离、安全组以及其他可达性限制等功能。

  1. kubectl apply -f http://docs.projectcalico.org/v2.1/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml

OVS

https://kubernetes.io/docs/admin/ovs-networking/提供了一种简单的基于OVS的网络配置方法:

  • 每台机器创建一个Linux网桥kbr0,并配置docker使用该网桥(而不是默认的docker0),其子网为10.244.x.0/24
  • 每台机器创建一个OVS网桥obr0,通过veth pair连接kbr0并通过GRE将所有机器互联
  • 开启STP
  • 路由10.244.0.0/16到OVS隧道

Kubernetes网络 - 图1

OVN

OVN (Open Virtual Network) 是OVS提供的原生虚拟化网络方案,旨在解决传统SDN架构(比如Neutron DVR)的性能问题。

OVN为Kubernetes提供了两种网络方案:

  • Overaly: 通过ovs overlay连接容器
  • Underlay: 将VM内的容器连到VM所在的相同网络(开发中)

其中,容器网络的配置是通过OVN的CNI插件来实现。

Contiv

Contiv是思科开源的容器网络方案,主要提供基于Policy的网络管理,并与主流容器编排系统集成。Contiv最主要的优势是直接提供了多租户网络,并支持L2(VLAN), L3(BGP), Overlay (VXLAN)以及思科自家的ACI。

Romana

Romana是Panic Networks在2016年提出的开源项目,旨在借鉴 route aggregation的思路来解决Overlay方案给网络带来的开销。

OpenContrail

OpenContrail是Juniper推出的开源网络虚拟化平台,其商业版本为Contrail。其主要由控制器和vRouter组成:

  • 控制器提供虚拟网络的配置、控制和分析功能
  • vRouter提供分布式路由,负责虚拟路由器、虚拟网络的建立以及数据转发

其中,vRouter支持三种模式

  • Kernel vRouter:类似于ovs内核模块
  • DPDK vRouter:类似于ovs-dpdk
  • Netronome Agilio Solution (商业产品):支持DPDK, SR-IOV and Express Virtio (XVIO)

Juniper/contrail-kubernetes 提供了Kubernetes的集成,包括两部分:

  • kubelet network plugin基于kubernetes v1.6已经删除的exec network plugin
  • kube-network-manager监听kubernetes API,并根据label信息来配置网络策略

Midonet

Midonet是Midokura公司开源的OpenStack网络虚拟化方案。

  • 从组件来看,Midonet以Zookeeper+Cassandra构建分布式数据库存储VPC资源的状态——Network State DB Cluster,并将controller分布在转发设备(包括vswitch和L3 Gateway)本地——Midolman(L3 Gateway上还有quagga bgpd),设备的转发则保留了ovs kernel作为fast datapath。可以看到,Midonet和DragonFlow、OVN一样,在架构的设计上都是沿着OVS-Neutron-Agent的思路,将controller分布到设备本地,并在neutron plugin和设备agent间嵌入自己的资源数据库作为super controller。
  • 从接口来看,NSDB与Neutron间是REST API,Midolman与NSDB间是RPC,这俩没什么好说的。Controller的南向方面,Midolman并没有用OpenFlow和OVSDB,它干掉了user space中的vswitchd和ovsdb-server,直接通过linux netlink机制操作kernel space中的ovs datapath。

Host network

最简单的网络模型就是让容器共享 Host 的 network namespace,使用宿主机的网络协议栈。这样,不需要额外的配置,容器就可以共享宿主的各种网络资源。

优点

  • 简单,不需要任何额外配置
  • 高效,没有NAT等额外的开销

缺点

  • 没有任何的网络隔离
  • 容器和Host的端口号容易冲突
  • 容器内任何网络配置都会影响整个宿主机

注意:HostNetwork 是在 Pod 配置文件中设置的,kubelet 在启动时还是需要配置使用 CNI 或者 kubenet 插件(默认kubenet)。

其他

ipvs

Kubernetes v1.8已经支持ipvs负载均衡模式(alpha版)。

Canal

Canal是Flannel和Calico联合发布的一个统一网络插件,提供CNI网络插件,并支持network policy。

kuryr-kubernetes

kuryr-kubernetes是OpenStack推出的集成Neutron网络插件,主要包括Controller和CNI插件两部分,并且也提供基于Neutron LBaaS的Service集成。

Cilium

Cilium是一个基于eBPF和XDP的高性能容器网络方案,提供了CNI和CNM插件。

项目主页为https://github.com/cilium/cilium

kope

kope是一个旨在简化Kubernetes网络配置的项目,支持三种模式:

  • Layer2:自动为每个Node配置路由
  • Vxlan:为主机配置vxlan连接,并建立主机和Pod的连接(通过vxlan interface和ARP entry)
  • ipsec:加密链接

项目主页为https://github.com/kopeio/kope-routing