libnetwork/overlay: remove live-restore support

The overlay driver in Swarm v2 mode doesn't support live-restore, ie.
the daemon won't even start if the node is part of a Swarm cluster and
live-restore is enabled. This feature was only used by Swarm Classic.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This commit is contained in:
Albin Kerouanton 2023-03-06 12:43:40 +01:00
parent e3708a89cc
commit 8aa1060c34
No known key found for this signature in database
GPG key ID: 630B8E1DCBDB1864
4 changed files with 24 additions and 120 deletions

View file

@ -46,7 +46,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
return fmt.Errorf("could not find subnet for endpoint %s", eid)
}
if err := n.joinSandbox(s, false, true); err != nil {
if err := n.joinSandbox(s, true); err != nil {
return fmt.Errorf("network sandbox join failed: %v", err)
}

View file

@ -244,16 +244,15 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
return nil
}
func (n *network) joinSandbox(s *subnet, restore bool, incJoinCount bool) error {
func (n *network) joinSandbox(s *subnet, incJoinCount bool) error {
// If there is a race between two go routines here only one will win
// the other will wait.
networkOnce.Do(networkOnceInit)
n.Lock()
// If non-restore initialization occurred and was successful then
// tell the peerDB to initialize the sandbox with all the peers
// previously received from networkdb. But only do this after
// unlocking the network. Otherwise we could deadlock with
// If initialization was successful then tell the peerDB to initialize the
// sandbox with all the peers previously received from networkdb. But only
// do this after unlocking the network. Otherwise we could deadlock with
// on the peerDB channel while peerDB is waiting for the network lock.
var doInitPeerDB bool
defer func() {
@ -264,8 +263,8 @@ func (n *network) joinSandbox(s *subnet, restore bool, incJoinCount bool) error
}()
if !n.sboxInit {
n.initErr = n.initSandbox(restore)
doInitPeerDB = n.initErr == nil && !restore
n.initErr = n.initSandbox()
doInitPeerDB = n.initErr == nil
// If there was an error, we cannot recover it
n.sboxInit = true
}
@ -276,9 +275,9 @@ func (n *network) joinSandbox(s *subnet, restore bool, incJoinCount bool) error
subnetErr := s.initErr
if !s.sboxInit {
subnetErr = n.initSubnetSandbox(s, restore)
// We can recover from these errors, but not on restore
if restore || subnetErr == nil {
subnetErr = n.initSubnetSandbox(s)
// We can recover from these errors
if subnetErr == nil {
s.initErr = subnetErr
s.sboxInit = true
}
@ -472,26 +471,6 @@ func checkOverlap(nw *net.IPNet) error {
return nil
}
func (n *network) restoreSubnetSandbox(s *subnet, brName, vxlanName string) error {
// restore overlay osl sandbox
ifaces := map[string][]osl.IfaceOption{
brName + "+br": {
n.sbox.InterfaceOptions().Address(s.gwIP),
n.sbox.InterfaceOptions().Bridge(true),
},
}
if err := n.sbox.Restore(ifaces, nil, nil, nil); err != nil {
return err
}
ifaces = map[string][]osl.IfaceOption{
vxlanName + "+vxlan": {
n.sbox.InterfaceOptions().Master(brName),
},
}
return n.sbox.Restore(ifaces, nil, nil, nil)
}
func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error {
if hostMode {
// Try to delete stale bridge interface if it exists
@ -628,7 +607,7 @@ func setDefaultVLAN(sbox osl.Sandbox) error {
}
// Must be called with the network lock
func (n *network) initSubnetSandbox(s *subnet, restore bool) error {
func (n *network) initSubnetSandbox(s *subnet) error {
brName := n.generateBridgeName(s)
vxlanName := n.generateVxlanName(s)
@ -644,14 +623,8 @@ func (n *network) initSubnetSandbox(s *subnet, restore bool) error {
}
}
if restore {
if err := n.restoreSubnetSandbox(s, brName, vxlanName); err != nil {
return err
}
} else {
if err := n.setupSubnetSandbox(s, brName, vxlanName); err != nil {
return err
}
if err := n.setupSubnetSandbox(s, brName, vxlanName); err != nil {
return err
}
s.vxlanName = vxlanName
@ -695,34 +668,23 @@ func (n *network) cleanupStaleSandboxes() {
})
}
func (n *network) initSandbox(restore bool) error {
func (n *network) initSandbox() error {
n.initEpoch++
if !restore {
if hostMode {
if err := addNetworkChain(n.id[:12]); err != nil {
return err
}
if hostMode {
if err := addNetworkChain(n.id[:12]); err != nil {
return err
}
// If there are any stale sandboxes related to this network
// from previous daemon life clean it up here
n.cleanupStaleSandboxes()
}
// In the restore case network sandbox already exist; but we don't know
// what epoch number it was created with. It has to be retrieved by
// searching the net namespaces.
var key string
if restore {
key = osl.GenerateKey("-" + n.id)
} else {
key = osl.GenerateKey(fmt.Sprintf("%d-", n.initEpoch) + n.id)
}
// If there are any stale sandboxes related to this network
// from previous daemon life clean it up here
n.cleanupStaleSandboxes()
sbox, err := osl.NewSandbox(key, !hostMode, restore)
key := osl.GenerateKey(fmt.Sprintf("%d-", n.initEpoch) + n.id)
sbox, err := osl.NewSandbox(key, !hostMode, false)
if err != nil {
return fmt.Errorf("could not get network sandbox (oper %t): %v", restore, err)
return fmt.Errorf("could not get network sandbox: %v", err)
}
// this is needed to let the peerAdd configure the sandbox

View file

@ -7,14 +7,12 @@ package overlay
import (
"fmt"
"net"
"sync"
"github.com/docker/docker/libnetwork/datastore"
"github.com/docker/docker/libnetwork/discoverapi"
"github.com/docker/docker/libnetwork/driverapi"
"github.com/docker/docker/libnetwork/netlabel"
"github.com/docker/docker/libnetwork/osl"
"github.com/docker/docker/libnetwork/types"
"github.com/sirupsen/logrus"
)
@ -69,65 +67,9 @@ func Register(r driverapi.Registerer, config map[string]interface{}) error {
}
}
if err := d.restoreEndpoints(); err != nil {
logrus.Warnf("Failure during overlay endpoints restore: %v", err)
}
return r.RegisterDriver(networkType, d, c)
}
// Endpoints are stored in the local store. Restore them and reconstruct the overlay sandbox
func (d *driver) restoreEndpoints() error {
if d.localStore == nil {
logrus.Warn("Cannot restore overlay endpoints because local datastore is missing")
return nil
}
kvol, err := d.localStore.List(datastore.Key(overlayEndpointPrefix), &endpoint{})
if err != nil && err != datastore.ErrKeyNotFound {
return fmt.Errorf("failed to read overlay endpoint from store: %v", err)
}
if err == datastore.ErrKeyNotFound {
return nil
}
for _, kvo := range kvol {
ep := kvo.(*endpoint)
n := d.network(ep.nid)
if n == nil {
logrus.Debugf("Network (%.7s) not found for restored endpoint (%.7s)", ep.nid, ep.id)
logrus.Debugf("Deleting stale overlay endpoint (%.7s) from store", ep.id)
if err := d.deleteEndpointFromStore(ep); err != nil {
logrus.Debugf("Failed to delete stale overlay endpoint (%.7s) from store", ep.id)
}
continue
}
n.addEndpoint(ep)
s := n.getSubnetforIP(ep.addr)
if s == nil {
return fmt.Errorf("could not find subnet for endpoint %s", ep.id)
}
if err := n.joinSandbox(s, true, true); err != nil {
return fmt.Errorf("restore network sandbox failed: %v", err)
}
Ifaces := make(map[string][]osl.IfaceOption)
vethIfaceOption := make([]osl.IfaceOption, 1)
vethIfaceOption = append(vethIfaceOption, n.sbox.InterfaceOptions().Master(s.brName))
Ifaces["veth+veth"] = vethIfaceOption
err := n.sbox.Restore(Ifaces, nil, nil, nil)
if err != nil {
n.leaveSandbox()
return fmt.Errorf("failed to restore overlay sandbox: %v", err)
}
d.peerAdd(ep.nid, ep.id, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), false, false, true)
}
return nil
}
func (d *driver) configure() error {
// Apply OS specific kernel configs if needed
d.initOS.Do(applyOStweaks)

View file

@ -315,7 +315,7 @@ func (d *driver) peerAddOp(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id)
}
if err := n.joinSandbox(s, false, false); err != nil {
if err := n.joinSandbox(s, false); err != nil {
return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), err)
}