关注分享主机优惠活动
国内外VPS云服务器

k8s与网络--flannel源码分析(k8s informer原理)

总结:目前我们主要做版本源码分析。 外部接口的定义如下。 创建子网管理员负责子网的创建、更新、添加、删除、监控等。 主要处理更新定义。 到期前,子网管理器调用该方法进行续订。

简介

上一篇文章《K8s与网络--解读Flannel》主要围绕我讲解了Flannel的整体工作原理。关于它。 。 今天我们主要分析Flannel v0.10.0版本的源码。 首先,您需要了解三个重要概念:

网络:分配给 Flannel 进行集群范围管理的网络地址范围。

子网:Flannel 所在的网络中每个主机都有一个子网、子网掩码和范围。是可配置的。

Backend:使用的后端网络模型类型,例如默认UDP或VXLAN。

源码分析

整体代码结构如下。

除了可执行入口main.go之外,还有几个与代码相关的文件夹。 后端、网络、包、子网等。

网络主要和iptables相关。 主要是根据你的配置设置MasqRules和ForwardRules规则的main函数。

pkg主要是一个抽象封装的IP函数库。

backed主要是后端实现,目前支持udp、vxlan、host-gw等。

子网 子网管理。 它主要支持两种实现:etcdv2和k8s。

启动参数

名称 默认值 描述
etcd-端点 http://127.0.0.1:4001,http://127.0.0.1:2379 etcd终端节点列表
etcd-前缀 /coreos.com/network etcd 前缀
etcd-密钥文件 SSL密钥文件
etcd-certfile SSL证书文件
etcd-cafile SSL证书颁发机构文件
etcd-用户名 通过 BasicAuth 访问 etcd 的用户名
etcd-密码 通过BasicAuth访问etcd的密码
iface 完整网卡名称或IP地址
iface-regex 网卡作为正则表达式名称或IP地址
subnet-file /run/flannel/subnet.env 运行时所需的变量要保存的文件名(子网、MTU等)
public-ip 主机 IP
子网 - 租用e-续订-保证金 60分钟 租约到期前的持续时间
ip [ k4 ]masq false 是否对覆盖网络外的流量设置IP伪装规则
kube-subnet-mgr false 是否使用k8s作为子网的实现方式
kube-api -url "" Kubernetes API 服务器 URL。 如果部署在集群中,则无需配置。 只需完成rbac认证即可。
kubeconfig-file "" kubeconfig 文件的位置。 如果部署在集群中,则无需配置。 只需完成rbac认证即可。
healthz-ip 0.0.0.0 需要监控的healthz服务器IP地址
healthz -port 0 要监控的 healthz 服务器端口。 0表示禁用

分析

从主函数开始分析。 主要步骤是:

1. 检查子网-租用-续订-保证金

如果 opts.subnetLeaseRenewMargin > = 24*60 ||   opts.subnetLeaseRenewMargin <= 0 { log.Error("无效子网-租用-通道w-margin 可选,超出范围") os.Exit(1) }

必须小于或等于 24 小时且大于 0。

2. 网络使用计算接口

如果主机有多个网卡,Flannel 应该使用哪一个?
这就是前面提到的 iface 和 iface-regex 相关的两个可能的规格。按以下优先顺序选择:
1) 如果既没有指定“--iface”也没有指定“--iface-regex”,则默认路由中使用的那个。 直接选择输出网卡。

2)如果“-iface”参数不为空,则会依次遍历每个实例,直到找到与网卡名称或IP匹配的实例。

3)如果“-iface-regex”参数不为空,则操作与2)相同,唯一的区别是使用正则表达式进行匹配。

最后,还可以通过启动参数“-public-ip”指定集群之间通信的公共IP。 否则,将使用上面获取的网卡IP作为公网IP。

外部接口的定义为:

 typeExternalInterface struct { Iface *net.Interface IfaceAddr net.IP ExtAddr net.IP}

3 . 创建 SubnetManager

func newSubnetManager() (subnet.Manager, error) { if opts .kubeSubnetMgr { return kube.NewSubnetManager(opts.kubeApiUrl, opts.kubeConfigFil)e) } cfg := &etcdv2.EtcdConfig{ 端点:strings.Split(opts.etcdEndpoints, ","),密钥文件:opts.etcdKeyfile,证书文件:opts.etcdCertfile,CA 文件:opts.etcdCAFile,前缀:opts。 etcdPrefix, Username: opts.etcdUsername, Password: opts.etcdPassword, } // 尝试续订由subnetFile指定的子网的租约 prevSubnet := ReadSubnetFromSubnetFile(opts.subnetFile) return etcdv2.NewLocalManager(cfg, prevSubnet )}

子网管理员创建、更新、添加、删除和监控子网。 主要处理etcd。 定义:

type Manager接口{ GetNetworkConfig(ctx context.Context) (*Config, error) AcquireLease(ctx context.Context, attrs *LeaseAttrs) (*Lease, error) RenewLease(ctx context.Context,租赁 *Lease) 错误 WatchLease(ctx context.Context, sn ip.IP4Net, 游标接口 {}) (LeaseWatchResult, error) WatchLeases(ctx context.Context, 游标接口 {}) (LeaseWatchResult, error) Name() string}

RenewLease 刷新 . 子网管理器调用此方法在租约到期之前续订租约。

GetNetworkConfig 检索本地计算机的子网配置并执行一些初始化任务。

4. 获取网络配置

config, err := getConfig(ctx, sm) if err == errCanceled { wg.Wait() os.Exit(0) }

此配置主要是管理网络配置,必须在 flannel 启动之前写入 etcd。 示例:

{ "Network": "10.0.0.0/8", "SubnetLen": 20, "SubnetMin": "10.10.0.0", "SubnetMax": "10.99.0.0", " Backend ": { "Type": "udp", "Port": 7890 }}

/coreos.com/network/config 存储上述网络配置数据。
详细说明:

SubnetLen表示分配给每个主机的子网大小。 您可以在初始化期间指定它。 否则,使用默认配置。 在默认配置中,如果集群的网络地址空间大于/24,则 SubnetLen 将配置为 24。 否则,它将比集群网络地址空间减一,例如集群的大小。如果是/25,则SubnetLen的大小是/26。

SubnetMin是集群网络地址空间内可以分配的最小子网,可以手动指定。 否则,默认配置是群集网络地址空间中的第一个可分配子网。 子网。

SubnetMax表示可以分配的最大子网。

BackendType 是使用的后端类型。 如果未指定,则默认为“udp”。

后端包含有关后端的附加信息。 例如,如果后端是vxlan,则存储VTEP设备的MAC地址。

5.创建后端管理器,用它创建后端,注册网络,然后执行run方法。

 bm := backend.NewManager(ctx, sm, extIface) be, err := bm.GetBackend(config.BackendType) if err != nil { log.Errorf("获取后端时出错: %s " , err) cancel() wg.Wait() os.Exit(1) } bn, err := be.RegisterNetwork(ctx, config) if err != nil { log.Errorf("网络注册错误: % s" , err) cancel() wg.Wait() os.Exit(1) }...log.Info ("正在运行后端。") wg.Add(1) go func() { bn .Run(ctx) wg.完毕 () }()

后端管理器

type manager struct { ctx context.Context smsubnet.Manager extIface *ExternalInterface muxsync.Mutex active map[string]Backend wgsync.WaitGroup } 

主要提供GetBackend(backendType string)(Backend, error)方法,根据配置文件中设置的后端标志生成对应的后端。
请注意此处

 go func() { <-bm.ctx.Done() // TODO(eyakubovich):这显然引入了一场竞赛。   // 此处可能会调用 GetBackend()。   // 但是,当前所有后端仅在退出时执行 // 在关闭时 bm.mux.Lock() delete(bm.active, betype) bm.mux.Unlock() bm.wg.Done() } ( )

后端生成后,flanneld 完成之前,启动一个协程,对激活的后端映射执行删除操作。

 func (n * root network)。Run(ctx context.Context) { wg :=sync.WaitGroup{} log.Info("监控新子网租用") evts := make(chan []subnet.Event) wg.Add(1) go func() { subnet.WatchLeases(ctx, n.SM, n.SubnetLease, evts) wg.Done() }() n.routes = make([]netlink.Route, 0, 10) wg.Add(1) go func( ) { n.routeCheck(ctx) wg.Done() }() defer wg.Wait() for { select { case evtBatch := <-evts: n.handleSubnetEvents(evtBatch) case <- ctx.Done ( ): return } }}

run方法主要执行以下内容。

子网与etcd交互,将etcd中的信息转换为flannel子网数据结构,并运行etcd。 监控子网和网络。

后端接收来自子网的监控事件并进行相应处理。

事件主要是subnet.EventAdded和subnet.EventRemoved。
发生子网添加事件时采取的步骤:检查参数是否正常,根据参数构建路由表条目,为主机添加路由表条目,为自己的数据添加路由表条目我会。从结构上来说。

发生子网删除事件时采取的步骤:检查参数是否正常,根据参数构建路由表项,从主机中删除路由表项,管理从主机中删除路由表项目标主机。 数据结构

p>6.其他

除了上面的核心逻辑之外,还有一些iptables规则和SubnetFile相关操作。

// 根据需要配置 ipMasq if opts.ipMasq { go network.SetupAndEnsureIPTables(network.MasqRules(config.Network, bn.Lease())) } // 始终设置转发规则启用。  对于 Docker 版本 > 1.13 是必需的 (https://docs.docker.com/engine/userguide/networking/default_network/container-communication/#container-communication- Between-hosts) //在 Docker 1.12 之前,默认的 FORWARD 链策略是 ACCEPT。   // 从 Docker 1.13 开始,Docker 将 FORWARD 链的默认策略设置为 DROP。   go network.SetupAndEnsureIPTables(network.ForwardRules(config.Network.String()))

可以看到SetupAn主要是在网络文件里面被调用。dEnsureIPTables 方法。
补充说明
从 Docker 1.13 开始,Docker 将 FORWARD 的默认策略设置为 drop,因此 flannel 需要做一些工作。

未经允许不得转载:主机频道 » k8s与网络--flannel源码分析(k8s informer原理)

相关推荐

评论 抢沙发

评论前必须登录!