之前分析了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
// NewNetwork creates a new network of the specified network type. The options
// are network specific and modeled in a generic way.
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()
}
// Construct the network object
//***network包含controller***//
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{},
}
//***处理option***//
//***option是一个函数,可以对network中的字段进行处理***//
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() {
// For non-distributed controlled environment, globalscoped non-dynamic networks are redirected to Manager
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.")
}
// Make sure we have a driver available for this network type
// before we allocate anything.
//***确定driver存在***//
if _, err := network.driver(true); err != nil {
return nil, err
}
//***设置ipam相关信息***//
err = network.ipamAllocate()
if err != nil {
return nil, err
}
defer func() {
if err != nil {
network.ipamRelease()
}
}()
//***调用addNetwork()方法***//
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)
}
}
}()
// First store the endpoint count, then the network. To avoid to
// end up with a datastore containing a network and not an epCnt,
// in case of an ungraceful shutdown during this function call.
//***生成epCnt,并存储***//
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***//
network.epCnt = epCnt
if err = c.updateToStore(network); err != nil {
return nil, err
}
joinCluster(network)
if !c.isDistributedControl() {
arrangeIngressFilterRule()
}
return network, nil
}

NewNetwork()的流程如下:

  1. 创建network结构体值;
  2. 处理传入的options,option为函数,一般可以设置结构体值的某字段,用户可以用来设置某字段值;
  3. 检查network driver是否存在;
  4. 调用network的ipamAllocate()设置network的ipam相关信息;
  5. 调用addNetwork()把创建底层network;
  6. 初始化epCnt字段;
  7. 调用updateToStore()存储network到store。

controller::addNetwork()

addNetwork()把network创建底层的network。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//***创建network***//
func (c *controller) addNetwork(n *network) error {
d, err := n.driver(true)
if err != nil {
return err
}
// Create the network
//***调用driver的CreateNetwork()***//
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
//***从network store中获取network列表***//
networks, err := c.getNetworksFromStore()
if err != nil {
log.Error(err)
}
for _, n := range networks {
//***inDelete标记network是否处理正在删除状态***//
if n.inDelete {
continue
}
list = append(list, n)
}
return list
}

controller::WalkNetworks()

WalkNetworks()会返回满足walker()条件的network。

1
2
3
4
5
6
7
8
//***遍历所有network,对每个network执行walker(),当walker()返回true时,表示结束***//
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的分析将由单独的系列文档承担。