docker与k8s网络模型学习
之前围绕阿里云的容器服务,内部做了一次阿里云基于k8s服务治理的总结。这次系统地学习了docker与k8s的网络模型,并从kubelet出发研究了kubelet -> dockershim -> cni -> flannel的调用链路,对cni项目的源码做了些许分析。Docker网络模型K8S网络模型同POD网络同NODE网络不同NODE网络CNI分析D...
之前围绕阿里云的容器服务,内部做了一次阿里云基于k8s服务治理的总结。这次系统地学习了docker与k8s的网络模型,并从kubelet出发研究了kubelet -> dockershim -> cni -> flannel的调用链路,对cni项目的源码做了些许分析。
- Docker网络模型
- K8S网络模型
- 同POD网络
- 同NODE网络
- 不同NODE网络
- CNI分析
Docker网络模型
根据docker官方对于network的介绍,网络方案可以分为以下几种:
- bridge
用于单个host上多个容器之间通信,bridge也是docker的默认网络方案 - overlay
基于docker swarm,用于不同容器在多个host上进行通信 - host
移除容器的网络隔离性,直接使用host上的网络命名空间 - macvlan
自定义容器的mac地址,将容器作为硬件设备。最佳实践是想将容器直接连接到物理网络时,可以考虑使用macvlan的方案 - none
容器没有网络联通需求时,可以不配置
容器体系应用的网络架构如下:
k8s网络模型
k8s同pod
同一个pod内的容器共用一个网络命名空间,直接访问本地的端口就能通信
k8s同node
同一个主机上的不同pod之间,通过docker0网络进行通信,接入同一个网桥内的容器属于相同的网段。
k8s不同node,分布式网络
分布式的网络模型,常见的解决方案有Coreos的flannel与calico。阿里云的k8s容器服务就是使用flannel对接Ali VPC接口完成的。
参考:
CNI分析
CNI是Container Network Interface的缩写,简单地说,就是一个标准的,通用的接口。已知我们现在有各种各样的容器平台:docker,kubernetes,mesos,我们也有各种各样的容器网络解决方案:flannel,calico,weave,并且还有各种新的解决方案在不断涌现。
如果每出现一个新的解决方案,我们都需要对两者进行适配,那么由此带来的工作量必然是巨大的,而且也是重复和不必要的。事实上,只要提供一个标准的接口,更准确的说是一种协议,就能完美地解决上述问题。一旦有新的网络方案出现,只要它能满足这个标准的协议,那么它就能为同样满足该协议的所有容器平台提供网络功能,而CNI正是这样的一个标准接口协议。
源码结构
仓库:cni
repo主要组成
|- cnitool (cni命令行工具)
|- libcni (cni的interface申明与默认CNIConfig实现)
|- pkg (调用插件的方法库及网络定义相关的结构)
|- scripts(打包编译脚本与执行脚本)
###源码
type CNI interface {
//network list
AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
DelNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
//network
AddNetwork(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
CheckNetwork(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
DelNetwork(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
//Validation
ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
}
核心配置主要有RuntimeConf与NetworkConfig
RuntimeConf
type RuntimeConf struct {
ContainerID string //在cnitool里containerID是根据net namespace做sha512得到
NetNS string //network namespace
IfName string //网卡名
Args [][2]string //执行命令行参数,底层是转换为环境变量
CapabilityArgs map[string]interface{} //用于网络插件执行的输入参数
CacheDir string
}
NetworkConf
type NetworkConfig struct {
Network *types.Netconf
Bytes []byte
}
type NetworkConfigList struct {
Name string
CNIVersion string
DisableCheck bool
Plugins []*NetworkConfig
Bytes []byte
}
type NetConf struct {
CNIVersion string
Name string
Type string
Capabilities map[string]bool
IPAM IPAM
DNS DNS
RawPrevResult map[string]interface{}
PrevResult Result
}
默认没有自定义plugin执行器时,cni默认的exec为CNIConfig{},Exec是interface类型,默认有ExecPlugin、FindInPath与Decode三个函数。
执行逻辑
以AddNetwork为例
CNI.AddNetwork ->
addNetwork ->
exec.FindInPath ->
buildOneConfig(network config) ->
ExecPluginWithResult ->
setCachedResult
参考:
- CNI源码:https://github.com/containernetworking/cni
- k8s网络原理:http://www.youruncloud.com/blog/131.html
…(img-3U65HuYc-1586319883545)]
参考:
- CNI源码:https://github.com/containernetworking/cni
- k8s网络原理:http://www.youruncloud.com/blog/131.html
- K8S-CNI https://feisky.gitbooks.io/kubernetes/network/cni/
更多推荐
所有评论(0)