文章

Kubernetes 网络

Kubernetes 网络

基础

容器网络基于namespace中的networknamespace(此外还有pid、mount、user、ipc、UTS(hostname)、cgroup)

  • 单独networkns中包括独立的网络设备、路由表、iptables规则
  • 网络设备无论是虚拟的还是实体,可以从一个ns移动到另外一个ns

docker网络

docker分为四种网络

  • bridge(default),建立docker0网桥设备,所有docker container连接在网桥上
  • container,加入一个已经存在的container的ns
  • NONE,不设置网络
  • host,使用所在宿主机网络

网络设备

  • bridge,虚拟交互机,可以发送arp,获取相应ip的mac地址
  • veth-pair,连接不同ns,一般一端在容器内,一端在宿主机上(网桥上)
  • tun设备,连接内核态和用户态

通用

容器与node通信

veth-pair使得容器内流量到达宿主机,通过路由表查询,到达其他node

容器与同node内容器通信

veth-pair使得容器内流量到达宿主机,通过路由表查询,同node内容器可直达,由于所有容器链接在网桥上,网桥可以作为虚拟交换机进行arp,获取mac

容器与不同node间容器通信

需要一个网线,而开源的网络方案用了不同的方式来实现这根网线

K8S网络方案

大体分为overlay、路由、underlay、

Flannel

udp
  • 流量从用户态进程->内核态
  • 通过子网记录获取某个网段的ip在某个node上
  • 流量通过路由表,指定某个网段的流量通过某个设备发出,这里是flannel0,这是一个tun设备,用于链接内核态和用户态,使得流量从内核态->flannel用户态
  • 每台node上的flannel都监听指定端口8285,通过flannel进程封装udp包,以用户态包发往指定node的flannel
  • 对端flannel接受到包后,直接给flannel0 tun设备处理,完成从用户态->内核态,然后内核态包查询路由表交给相应的网桥设备处理
  • 三次用户态和内核态装换,效率较低
vxlan
  • 不再通过flannel进程传递
  • 流量不再发往flannel0,而是flannel.1,这是一个vtep隧道设备
  • 查询路由表知道,某个段的ip的网关是对应node上的vtep设备ip
  • 如何知道对端vtep设备的mac,由flannel维护,会写入一个arp记录,记录某个ip的vtep设备的mac地址是啥
  • 这里获取都是内部网络的ip和mac,如何获取宿主机ip
  • 同时会写fdb,记录的是发往某个mac地址需要从flannel.1设备发给某个宿主机ip
host-gw
  • 写路由表
  • 某个ip段的包的网关,就是那个ip段容器所在宿主机某个设备的ip
  • 要求通过ip可以直接查到相应mac

calico

支持network-policy
与host-gw模式类似,会写入多条路由规则

  • 某个ip段的路由网关是某个宿主机的ip
  • 本机容器的路由规则是:容器ip对应的设备是某个veth-pair的一端
ipip
  • 如果宿主机不再同一网段下,需要通过ipip模块建立隧道来通信
  • 这样bgp用来路由发现,但是宿主机间通信通过隧道
bgp
  • 可以建立少数几个routerreflector,也可以和交换机建立

underlay

依赖底层网络
容器虚拟化部分,可以用ipvlan、macvlan、sr-iov
ipam部分可以自研

优点:

  • 性能好,充分利用现有网络
  • 可定制化高

劣势:

  • 需要时间长,每次都需要进行容器虚拟化
  • underlay属于外部网络,所以svc的cluster-ip不会通,需要做些工作
  • 依赖底层网络实现
本文由作者按照 CC BY 4.0 进行授权