github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/drivers/overlay/overlay.go (about) 1 package overlay 2 3 //go:generate protoc -I.:../../Godeps/_workspace/src/github.com/gogo/protobuf --gogo_out=import_path=github.com/docker/libnetwork/drivers/overlay,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. overlay.proto 4 5 import ( 6 "fmt" 7 "net" 8 "sync" 9 10 "github.com/Sirupsen/logrus" 11 "github.com/docker/libnetwork/datastore" 12 "github.com/docker/libnetwork/discoverapi" 13 "github.com/docker/libnetwork/driverapi" 14 "github.com/docker/libnetwork/idm" 15 "github.com/docker/libnetwork/netlabel" 16 "github.com/docker/libnetwork/osl" 17 "github.com/docker/libnetwork/types" 18 "github.com/hashicorp/serf/serf" 19 ) 20 21 const ( 22 networkType = "overlay" 23 vethPrefix = "veth" 24 vethLen = 7 25 vxlanIDStart = 256 26 vxlanIDEnd = (1 << 24) - 1 27 vxlanPort = 4789 28 vxlanEncap = 50 29 secureOption = "encrypted" 30 ) 31 32 var initVxlanIdm = make(chan (bool), 1) 33 34 type driver struct { 35 eventCh chan serf.Event 36 notifyCh chan ovNotify 37 exitCh chan chan struct{} 38 bindAddress string 39 advertiseAddress string 40 neighIP string 41 config map[string]interface{} 42 peerDb peerNetworkMap 43 secMap *encrMap 44 serfInstance *serf.Serf 45 networks networkTable 46 store datastore.DataStore 47 localStore datastore.DataStore 48 vxlanIdm *idm.Idm 49 once sync.Once 50 joinOnce sync.Once 51 keys []*key 52 sync.Mutex 53 } 54 55 // Init registers a new instance of overlay driver 56 func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { 57 c := driverapi.Capability{ 58 DataScope: datastore.GlobalScope, 59 } 60 d := &driver{ 61 networks: networkTable{}, 62 peerDb: peerNetworkMap{ 63 mp: map[string]*peerMap{}, 64 }, 65 secMap: &encrMap{nodes: map[string][]*spi{}}, 66 config: config, 67 } 68 69 if data, ok := config[netlabel.GlobalKVClient]; ok { 70 var err error 71 dsc, ok := data.(discoverapi.DatastoreConfigData) 72 if !ok { 73 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 74 } 75 d.store, err = datastore.NewDataStoreFromConfig(dsc) 76 if err != nil { 77 return types.InternalErrorf("failed to initialize data store: %v", err) 78 } 79 } 80 81 if data, ok := config[netlabel.LocalKVClient]; ok { 82 var err error 83 dsc, ok := data.(discoverapi.DatastoreConfigData) 84 if !ok { 85 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 86 } 87 d.localStore, err = datastore.NewDataStoreFromConfig(dsc) 88 if err != nil { 89 return types.InternalErrorf("failed to initialize local data store: %v", err) 90 } 91 } 92 93 if err := d.restoreEndpoints(); err != nil { 94 logrus.Warnf("Failure during overlay endpoints restore: %v", err) 95 } 96 97 // If an error happened when the network join the sandbox during the endpoints restore 98 // we should reset it now along with the once variable, so that subsequent endpoint joins 99 // outside of the restore path can potentially fix the network join and succeed. 100 for nid, n := range d.networks { 101 if n.initErr != nil { 102 logrus.Infof("resetting init error and once variable for network %s after unsuccesful endpoint restore: %v", nid, n.initErr) 103 n.initErr = nil 104 n.once = &sync.Once{} 105 } 106 } 107 108 return dc.RegisterDriver(networkType, d, c) 109 } 110 111 // Endpoints are stored in the local store. Restore them and reconstruct the overlay sandbox 112 func (d *driver) restoreEndpoints() error { 113 if d.localStore == nil { 114 logrus.Warnf("Cannot restore overlay endpoints because local datastore is missing") 115 return nil 116 } 117 kvol, err := d.localStore.List(datastore.Key(overlayEndpointPrefix), &endpoint{}) 118 if err != nil && err != datastore.ErrKeyNotFound { 119 return fmt.Errorf("failed to read overlay endpoint from store: %v", err) 120 } 121 122 if err == datastore.ErrKeyNotFound { 123 return nil 124 } 125 for _, kvo := range kvol { 126 ep := kvo.(*endpoint) 127 n := d.network(ep.nid) 128 if n == nil { 129 logrus.Debugf("Network (%s) not found for restored endpoint (%s)", ep.nid[0:7], ep.id[0:7]) 130 logrus.Debugf("Deleting stale overlay endpoint (%s) from store", ep.id[0:7]) 131 if err := d.deleteEndpointFromStore(ep); err != nil { 132 logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", ep.id[0:7]) 133 } 134 continue 135 } 136 n.addEndpoint(ep) 137 138 s := n.getSubnetforIP(ep.addr) 139 if s == nil { 140 return fmt.Errorf("could not find subnet for endpoint %s", ep.id) 141 } 142 143 if err := n.joinSandbox(true); err != nil { 144 return fmt.Errorf("restore network sandbox failed: %v", err) 145 } 146 147 if err := n.joinSubnetSandbox(s, true); err != nil { 148 return fmt.Errorf("restore subnet sandbox failed for %q: %v", s.subnetIP.String(), err) 149 } 150 151 Ifaces := make(map[string][]osl.IfaceOption) 152 vethIfaceOption := make([]osl.IfaceOption, 1) 153 vethIfaceOption = append(vethIfaceOption, n.sbox.InterfaceOptions().Master(s.brName)) 154 Ifaces[fmt.Sprintf("%s+%s", "veth", "veth")] = vethIfaceOption 155 156 err := n.sbox.Restore(Ifaces, nil, nil, nil) 157 if err != nil { 158 return fmt.Errorf("failed to restore overlay sandbox: %v", err) 159 } 160 161 n.incEndpointCount() 162 d.peerDbAdd(ep.nid, ep.id, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), true) 163 } 164 return nil 165 } 166 167 // Fini cleans up the driver resources 168 func Fini(drv driverapi.Driver) { 169 d := drv.(*driver) 170 171 if d.exitCh != nil { 172 waitCh := make(chan struct{}) 173 174 d.exitCh <- waitCh 175 176 <-waitCh 177 } 178 } 179 180 func (d *driver) configure() error { 181 if d.store == nil { 182 return nil 183 } 184 185 if d.vxlanIdm == nil { 186 return d.initializeVxlanIdm() 187 } 188 189 return nil 190 } 191 192 func (d *driver) initializeVxlanIdm() error { 193 var err error 194 195 initVxlanIdm <- true 196 defer func() { <-initVxlanIdm }() 197 198 if d.vxlanIdm != nil { 199 return nil 200 } 201 202 d.vxlanIdm, err = idm.New(d.store, "vxlan-id", vxlanIDStart, vxlanIDEnd) 203 if err != nil { 204 return fmt.Errorf("failed to initialize vxlan id manager: %v", err) 205 } 206 207 return nil 208 } 209 210 func (d *driver) Type() string { 211 return networkType 212 } 213 214 func validateSelf(node string) error { 215 advIP := net.ParseIP(node) 216 if advIP == nil { 217 return fmt.Errorf("invalid self address (%s)", node) 218 } 219 220 addrs, err := net.InterfaceAddrs() 221 if err != nil { 222 return fmt.Errorf("Unable to get interface addresses %v", err) 223 } 224 for _, addr := range addrs { 225 ip, _, err := net.ParseCIDR(addr.String()) 226 if err == nil && ip.Equal(advIP) { 227 return nil 228 } 229 } 230 return fmt.Errorf("Multi-Host overlay networking requires cluster-advertise(%s) to be configured with a local ip-address that is reachable within the cluster", advIP.String()) 231 } 232 233 func (d *driver) nodeJoin(advertiseAddress, bindAddress string, self bool) { 234 if self && !d.isSerfAlive() { 235 d.Lock() 236 d.advertiseAddress = advertiseAddress 237 d.bindAddress = bindAddress 238 d.Unlock() 239 240 // If there is no cluster store there is no need to start serf. 241 if d.store != nil { 242 if err := validateSelf(advertiseAddress); err != nil { 243 logrus.Warnf("%s", err.Error()) 244 } 245 err := d.serfInit() 246 if err != nil { 247 logrus.Errorf("initializing serf instance failed: %v", err) 248 d.Lock() 249 d.advertiseAddress = "" 250 d.bindAddress = "" 251 d.Unlock() 252 return 253 } 254 } 255 } 256 257 d.Lock() 258 if !self { 259 d.neighIP = advertiseAddress 260 } 261 neighIP := d.neighIP 262 d.Unlock() 263 264 if d.serfInstance != nil && neighIP != "" { 265 var err error 266 d.joinOnce.Do(func() { 267 err = d.serfJoin(neighIP) 268 if err == nil { 269 d.pushLocalDb() 270 } 271 }) 272 if err != nil { 273 logrus.Errorf("joining serf neighbor %s failed: %v", advertiseAddress, err) 274 d.Lock() 275 d.joinOnce = sync.Once{} 276 d.Unlock() 277 return 278 } 279 } 280 } 281 282 func (d *driver) pushLocalEndpointEvent(action, nid, eid string) { 283 n := d.network(nid) 284 if n == nil { 285 logrus.Debugf("Error pushing local endpoint event for network %s", nid) 286 return 287 } 288 ep := n.endpoint(eid) 289 if ep == nil { 290 logrus.Debugf("Error pushing local endpoint event for ep %s / %s", nid, eid) 291 return 292 } 293 294 if !d.isSerfAlive() { 295 return 296 } 297 d.notifyCh <- ovNotify{ 298 action: "join", 299 nw: n, 300 ep: ep, 301 } 302 } 303 304 // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster 305 func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error { 306 var err error 307 switch dType { 308 case discoverapi.NodeDiscovery: 309 nodeData, ok := data.(discoverapi.NodeDiscoveryData) 310 if !ok || nodeData.Address == "" { 311 return fmt.Errorf("invalid discovery data") 312 } 313 d.nodeJoin(nodeData.Address, nodeData.BindAddress, nodeData.Self) 314 case discoverapi.DatastoreConfig: 315 if d.store != nil { 316 return types.ForbiddenErrorf("cannot accept datastore configuration: Overlay driver has a datastore configured already") 317 } 318 dsc, ok := data.(discoverapi.DatastoreConfigData) 319 if !ok { 320 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 321 } 322 d.store, err = datastore.NewDataStoreFromConfig(dsc) 323 if err != nil { 324 return types.InternalErrorf("failed to initialize data store: %v", err) 325 } 326 case discoverapi.EncryptionKeysConfig: 327 encrData, ok := data.(discoverapi.DriverEncryptionConfig) 328 if !ok { 329 return fmt.Errorf("invalid encryption key notification data") 330 } 331 keys := make([]*key, 0, len(encrData.Keys)) 332 for i := 0; i < len(encrData.Keys); i++ { 333 k := &key{ 334 value: encrData.Keys[i], 335 tag: uint32(encrData.Tags[i]), 336 } 337 keys = append(keys, k) 338 } 339 if err := d.setKeys(keys); err != nil { 340 logrus.Warn(err) 341 } 342 case discoverapi.EncryptionKeysUpdate: 343 var newKey, delKey, priKey *key 344 encrData, ok := data.(discoverapi.DriverEncryptionUpdate) 345 if !ok { 346 return fmt.Errorf("invalid encryption key notification data") 347 } 348 if encrData.Key != nil { 349 newKey = &key{ 350 value: encrData.Key, 351 tag: uint32(encrData.Tag), 352 } 353 } 354 if encrData.Primary != nil { 355 priKey = &key{ 356 value: encrData.Primary, 357 tag: uint32(encrData.PrimaryTag), 358 } 359 } 360 if encrData.Prune != nil { 361 delKey = &key{ 362 value: encrData.Prune, 363 tag: uint32(encrData.PruneTag), 364 } 365 } 366 if err := d.updateKeys(newKey, priKey, delKey); err != nil { 367 logrus.Warn(err) 368 } 369 default: 370 } 371 return nil 372 } 373 374 // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster 375 func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error { 376 return nil 377 }