// 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