基础
容器网络基于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
不会通,需要做些工作- 依赖底层网络实现