flannel源码分析---初始化部分

// main.go

1、func main()

  • .....
  • 首先调用sm, err := newSubnetManager()创建subnet manager
  • ....
  • 调用ctx, cancel := context.WithCancel(context.Background())
  • 调用nm, err := network.NewNetworkManager(ctx, sm)
  • 创建runFunc = func(ctx context.Context) {

     nm.Run(ctx)

  }

  • 创建一个goroutine,其中调用runFunc(ctx)

// main.go

2、func newSubnetManager() (subnet.Manager, error)

  • 当opts.kubeSubnetMgr为true时,调用return kube.NewSubnetManager()
  • 否则,创建cfg := &etcdv2.EtcdConfig{...}
  • 最后return etcdv2.NewLocalManager(cfg)

subnet.Manager数据结构如下所示:

type Manager interface {
  GetNetworkConfig(ctx context.Context, network string) (*Config, error)
  AcquireLease(ctx context.Context, network string, attrs *LeaseAttrs) (*Lease, error)
  RenewLease(ctx context.Context, network string, lease *Lease) error
  RevokeLease(ctx context.Context, network string, sn ip.IP4Net) error
  WatchLease(ctx context.Context, network string, sn ip.IP4Net, cursor interface{}) (LeaseWatchResult, error)
  WatchLeases(ctx context.Context, network string, cursor interface{}) (LeaseWatchResult, error)
  WatchNetworks(ctx context.Context, cursor interface{}) (NetworkWatchResult, error)

  AddReservation(ctx context.Context, network string, r *Reservation) error
  RemoveReservation(ctx context.Context, network string, subnet ip.IP4Net) error
  ListReservations(ctx context.Context, network string) ([]Reservation, error)
}

  

// subnet/etcdv2/local_manager.go

func NewLocalManager(config *EtcdConfig) (Manager, error)

  • 首先调用r, err := newEtcdSubnetRegistry(config, nil)
  • 再调用return newLocalManager(r), nil --> newLocalManager的作用仅仅只是返回一个&LocalManager{register: r}

LocalManager的结构如下所示:

type LocalManager struct {
  registry Registry
}

  

// subnet/etcdv2/registry.go

func newEtcdSubnetRegistry(config *EtcdConfig, cliNewFunc etcdNewFunc) (Registry, error)

  • 创建r := &etcdSubnetRegistry{

    etcdCfg:     config,

    networkRegex:  regexp.MustCompile(config.Prefix + `/([^/]*)(/|/config)?$`),

  }

  • 当cliNewFunc不为空时,设置c.cliNewFunc为cliNewFunc,否则设置r.cliNewFunc为newEtcdClient
  • 调用r.cli, err = r.cliNewFunc(config)
  • 最后返回return r, nil

etcdSubnetRegistry结构如下所示:

type etcdSubnetRegistry struct {
  cliNewFunc    etcdNewFunc
  mux        sync.Mutex
  cli        etcd.KeysAPI
  etcdCfg      *EtcdConfig
  networkRegex    *regexp.Regexp
}

  

// subnet/etcdv2/registry.go

func newEtcdClien(c *EtcdConfig) (etcd.KeysAPI, error)

  • 该函数根据EtcdConfig中的配置,和etcd集群建立连接,创建一个client对象,最后调用etcd.NewKeysAPI(cli)返回对于etcd集群操作的主要的API:包括Get,Set,Delete等等

// network/manager.go

func NewNetworkManager(ctx context.Context, sm subnet.Manager) (*Manager, error)

  • 调用extIface, err := lookupExtIface(opts.iface),其中iface是用于宿主机直接通信的网卡
  • 调用bm := backend.NewManager(ctx, sm, extIface)
  • 创建manager := &Manager{

    ctx:          ctx,

    sm:          sm,

    bm:          bm,

    allowedNetworks:    make(map[string]bool),

    networks:         make(map[string]*Network),

    watch:         opts.watchNetworks,

    ipMasq:         opts.ipMasq,

    extIface:        extIface,

  }

  • 遍历opts.networks,将对应的manager.allowedNetworks[name]都置为true
  • 最后,返回return manager, nil

// network/manager.go

func lookupExtIface(ifname string) (*backend.ExternalInterface, error)

  • 若ifname不为空则:

    • 先调用ifaceAddr = net.ParseIP(ifname),若ifaceAddr不为空,则调用iface, err = ip.GetInterfaceByIP(ifaceAddr),否则调用iface, err = net.InterfaceByName(ifname)
  • 否则,调用iface, err = ip.GetDefaultGatewayIface()
  • 若ifaceAddr为nil,则调用ifaceAddr, err = ip.GetIfaceIP4Addr(iface)
  • 若用户指定了opts.publicIP则尝试将extAddr设置为它,否则默认将external address设置为ifaceAddr
  • 最后返回&backend.ExternalInterface{

    Iface:    iface,

    IfaceAddr:  ifaceAddr,

    ExtAddr:   extAddr,

  }, nil

时间: 2024-11-09 00:16:33

flannel源码分析---初始化部分的相关文章

flannel源码分析(一) 概述

随着docker社区的不断壮大, CoreOS.Kubernetes.Hashicorp等项目蓬勃发展. flannel作为一款专为容器打造的开源网络组件, 也吸引了工程师的关注.flannel简单易用, 只需要同属CoreOS家族的etcd作为一致性存储, 便可配置multi-host的网络连接. 下图为flanned的网络原理图, 源自https://github.com/coreos/flannel . 可以看到flannel为每台host划分了subnet, 这样就保证多台主机上的多个容

linux调度器源码分析 - 初始化(二)

本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 上期文章linux调度器源码分析 - 概述(一)已经把调度器相关的数据结构介绍了一遍,本篇着重通过代码说明调度器在系统启动初始化阶段是如何初始化和工作的.通过上期文章我们知道,在多核CPU和SMP系统中,每个CPU(多核COU中的每个核)都有自己的struct rq队列,而rq队列中又有着自己的struct cfs_rq和struct rt_rq.在初始化时就是对这三个结构进行初始化. init_tas

linux中断源码分析 - 初始化(二)

本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 本篇文章主要讲述源码中是如何对中断进行一系列的初始化的. 回顾 在上一篇概述中,介绍了几个对于中断来说非常重要的数据结构,分别是:中断描述符表,中断描述符数组,中断描述符,中断控制器描述符,中断服务例程.可以说这几个结构组成了整个内核中断框架主体,所以内核对整个中断的初始化工作大多集中在了这几个结构上. 在系统中,当一个中断产生时,首先CPU会从中断描述符表中获取相应的中断向量,并根据中断向量的权限位判断是否

flannel源码分析---backend为vxlan

// backend/vxlan/vxlan.go func (be *VXLANBackend) RegisterNetwork(ctx context.Context, network string, config *subnet.Config) (backend.Network, error) 创建cfg变量,它的结构体中包含VIN int, Port int, GBP bool三个字段,其中VNI设置为默认的defaultVNI = 1,并且调用json.Unmarshal(config

wifidog源码分析 - 初始化阶段

Wifidog是一个linux下开源的认证网关软件,它主要用于配合认证服务器实现无线路由器的认证放行功能. wifidog是一个后台的服务程序,可以通过wdctrl命令对wifidog主程序进行控制. 本文解释wifidog在启动阶段所做的初始化主要工作(代码片段1.1) 初始化配置(先将配置结构体初始化为默认值,在读取配置文件修改配置结构体) 初始化已连接客户端列表(如果是通过wdctrl重启wifidog,将会读取之前wifidog的已连接客户端列表 代码片段1.2 代码片段1.3) 如无特

linux中断源码分析 - 中断发生(三)

本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 回顾 上篇文章linux中断源码分析 - 初始化(二)已经描述了中断描述符表和中断描述符数组的初始化,由于在初始化期间系统关闭了中断(通过设置CPU的EFLAGS寄存器的IF标志位为0),当整个中断和异常的初始化完成后,系统会开启中断(设置CPU的EFLAGS寄存器的IF标志位为1),此时整个系统的中断已经开始可以使用了.本篇文章我们具体研究一次典型中断发生时的运行流程. 中断产生 我们需要先明确一下,中断控

Nouveau源码分析(六):NVIDIA设备初始化之nouveau_drm_load (3)

Nouveau源码分析(六) 上一篇中我们暂时忽略了两个函数,第一个是用于创建nvif_device对应的nouveau_object的ctor函数: // /drivers/gpu/drm/nouveau/core/engine/device/base.c 488 static struct nouveau_ofuncs 489 nouveau_devobj_ofuncs = { 490 .ctor = nouveau_devobj_ctor, 491 .dtor = nouveau_devo

MyBatis源码分析-MyBatis初始化流程

MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录.如何新建MyBatis源码工程请点击MyBatis源码分析-IDEA新建MyBatis源码工程. MyBatis初始化的过程也就是创建Configura

dubbox源码分析(一)-服务的启动与初始化

程序猿成长之路少不了要学习和分析源码的.最近难得能静得下心来,就针对dubbox为目标开始进行源码分析. [服务提供方] 步骤 调用顺序 备注 容器启动 com.alibaba.dubbo.container.Main.main(args);dubbo.properties -> dubbo.container -> container.start()container -> spring, log4j, jetty... [dubbo-container-spring] SpringC