基础
容器网络基于namespace中的networknamespace(此外还有pid、mount、user、ipc、UTS(hostname)、cgroup)
- 单独
networkns中包括独立的网络设备、路由表、iptables规则 - 网络设备无论是虚拟的还是实体,可以从一个
ns移动到另外一个ns
docker网络
docker分为四种网络
bridge(default),建立docker0网桥设备,所有docker container连接在网桥上container,加入一个已经存在的container的nsNONE,不设置网络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设备发给某个宿主机iphost-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-iovipam部分可以自研
优点:
- 性能好,充分利用现有网络
- 可定制化高
劣势:
- 需要时间长,每次都需要进行容器虚拟化
underlay属于外部网络,所以svc的cluster-ip不会通,需要做些工作- 依赖底层网络实现