之前分析了controller的第一部分,现在接着分析第二部分:管理network。
(二) 管理network
controller和network的联系是通过store进行的,也就是说network是存储在数据库中的,而controller通过store管理network。
controller::NewNetwork()
NewNetwork()可以创建一个新的network。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) { if id != "" { c.networkLocker.Lock(id) defer c.networkLocker.Unlock(id) if _, err := c.NetworkByID(id); err == nil { return nil, NetworkNameError(id) } } if !config.IsValidName(name) { return nil, ErrInvalidName(name) } if id == "" { id = stringid.GenerateRandomID() } network := &network{ name: name, networkType: networkType, generic: map[string]interface{}{netlabel.GenericData: make(map[string]string)}, ipamType: ipamapi.DefaultIPAM, id: id, ctrlr: c, persist: true, drvOnce: &sync.Once{}, } network.processOptions(options...) _, cap, err := network.resolveDriver(networkType, true) if err != nil { return nil, err } if cap.DataScope == datastore.GlobalScope && !c.isDistributedControl() && !network.dynamic { if c.isManager() { return nil, ManagerRedirectError(name) } return nil, types.ForbiddenErrorf("Cannot create a multi-host network from a worker node. Please create the network from a manager node.") } if _, err := network.driver(true); err != nil { return nil, err } err = network.ipamAllocate() if err != nil { return nil, err } defer func() { if err != nil { network.ipamRelease() } }() err = c.addNetwork(network) if err != nil { return nil, err } defer func() { if err != nil { if e := network.deleteNetwork(); e != nil { log.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err) } } }() epCnt := &endpointCnt{n: network} if err = c.updateToStore(epCnt); err != nil { return nil, err } defer func() { if err != nil { if e := c.deleteFromStore(epCnt); e != nil { log.Warnf("couldnt rollback from store, epCnt %v on failure (%v): %v", epCnt, err, e) } } }() network.epCnt = epCnt if err = c.updateToStore(network); err != nil { return nil, err } joinCluster(network) if !c.isDistributedControl() { arrangeIngressFilterRule() } return network, nil }
|
NewNetwork()的流程如下:
- 创建network结构体值;
- 处理传入的options,option为函数,一般可以设置结构体值的某字段,用户可以用来设置某字段值;
- 检查network driver是否存在;
- 调用network的ipamAllocate()设置network的ipam相关信息;
- 调用addNetwork()把创建底层network;
- 初始化epCnt字段;
- 调用updateToStore()存储network到store。
controller::addNetwork()
addNetwork()把network创建底层的network。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func (c *controller) addNetwork(n *network) error { d, err := n.driver(true) if err != nil { return err } if err := d.CreateNetwork(n.id, n.generic, n, n.getIPData(4), n.getIPData(6)); err != nil { return err } return nil }
|
driver的CreateNetwork()实现比较复杂,以后放在driver中分析。
controller::Networks()
Networks()可以从store中获取networks。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| func (c *controller) Networks() []Network { var list []Network networks, err := c.getNetworksFromStore() if err != nil { log.Error(err) } for _, n := range networks { if n.inDelete { continue } list = append(list, n) } return list }
|
controller::WalkNetworks()
WalkNetworks()会返回满足walker()条件的network。
1 2 3 4 5 6 7 8
| func (c *controller) WalkNetworks(walker NetworkWalker) { for _, n := range c.Networks() { if walker(n) { return } } }
|
controller::NetworkByName()
NetworkByName()通过调用WalkNetworks(),其提取函数的功能为提取名为name的network
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| func (c *controller) NetworkByName(name string) (Network, error) { if name == "" { return nil, ErrInvalidName(name) } var n Network s := func(current Network) bool { if current.Name() == name { n = current return true } return false } c.WalkNetworks(s) if n == nil { return nil, ErrNoSuchNetwork(name) } return n, nil }
|
controller::NetworkByID()
NetworkByID()可以依据id直接从store中获取network。
1 2 3 4 5 6 7 8 9 10 11 12
| func (c *controller) NetworkByID(id string) (Network, error) { if id == "" { return nil, ErrInvalidID(id) } n, err := c.getNetworkFromStore(id) if err != nil { return nil, ErrNoSuchNetwork(id) } return n, nil }
|
其他
controller还定义有getNetworkFromStore(),getNetworksForScope(),getNetworksFromStore()这些从store中获取network的方法,这些方法从名字上也比较好理解,不会阻塞controller的”管理network”的代码阅读,所以将放到store中分析。
小结
controller可以创建network,并从数据库获取network。但controller不能直接删除network,删除操作定义在network结构体中。controller的network管理的分析比较简单,因为还没涉及network本身的操作,对network的分析将由单独的系列文档承担。