Signed-off-by: Lei Jitang <leijitang@huawei.com>
| ... | ... |
@@ -121,14 +121,6 @@ func New(config Config) (*Cluster, error) {
|
| 121 | 121 |
return c, nil |
| 122 | 122 |
} |
| 123 | 123 |
|
| 124 |
-func (c *Cluster) checkCompatibility() error {
|
|
| 125 |
- info, _ := c.config.Backend.SystemInfo() |
|
| 126 |
- if info != nil && (info.ClusterStore != "" || info.ClusterAdvertise != "") {
|
|
| 127 |
- return fmt.Errorf("swarm mode is incompatible with `--cluster-store` and `--cluster-advertise daemon configuration")
|
|
| 128 |
- } |
|
| 129 |
- return nil |
|
| 130 |
-} |
|
| 131 |
- |
|
| 132 | 124 |
func (c *Cluster) saveState() error {
|
| 133 | 125 |
dt, err := json.Marshal(state{ListenAddr: c.listenAddr})
|
| 134 | 126 |
if err != nil {
|
| ... | ... |
@@ -173,7 +165,7 @@ func (c *Cluster) reconnectOnFailure(ctx context.Context) {
|
| 173 | 173 |
} |
| 174 | 174 |
|
| 175 | 175 |
func (c *Cluster) startNewNode(forceNewCluster bool, listenAddr, joinAddr, secret, cahash string, ismanager bool) (*swarmagent.Node, context.Context, error) {
|
| 176 |
- if err := c.checkCompatibility(); err != nil {
|
|
| 176 |
+ if err := c.config.Backend.IsSwarmCompatible(); err != nil {
|
|
| 177 | 177 |
return nil, nil, err |
| 178 | 178 |
} |
| 179 | 179 |
c.node = nil |
| ... | ... |
@@ -3,6 +3,7 @@ |
| 3 | 3 |
package daemon |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
+ "fmt" |
|
| 6 | 7 |
"net" |
| 7 | 8 |
|
| 8 | 9 |
"github.com/docker/docker/opts" |
| ... | ... |
@@ -120,3 +121,13 @@ func (config *Config) GetAllRuntimes() map[string]types.Runtime {
|
| 120 | 120 |
config.reloadLock.Unlock() |
| 121 | 121 |
return rts |
| 122 | 122 |
} |
| 123 |
+ |
|
| 124 |
+func (config *Config) isSwarmCompatible() error {
|
|
| 125 |
+ if config.IsValueSet("cluster-store") || config.IsValueSet("cluster-advertise") {
|
|
| 126 |
+ return fmt.Errorf("--cluster-store and --cluster-advertise daemon configurations are incompatible with swarm mode")
|
|
| 127 |
+ } |
|
| 128 |
+ if config.LiveRestore {
|
|
| 129 |
+ return fmt.Errorf("--live-restore daemon configuration is incompatible with swarm mode")
|
|
| 130 |
+ } |
|
| 131 |
+ return nil |
|
| 132 |
+} |
| ... | ... |
@@ -30,7 +30,7 @@ var ( |
| 30 | 30 |
getPortMapInfo = container.GetSandboxPortMapInfo |
| 31 | 31 |
) |
| 32 | 32 |
|
| 33 |
-func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libnetwork.Network) ([]libnetwork.SandboxOption, error) {
|
|
| 33 |
+func (daemon *Daemon) buildSandboxOptions(container *container.Container) ([]libnetwork.SandboxOption, error) {
|
|
| 34 | 34 |
var ( |
| 35 | 35 |
sboxOptions []libnetwork.SandboxOption |
| 36 | 36 |
err error |
| ... | ... |
@@ -176,16 +176,19 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libn |
| 176 | 176 |
|
| 177 | 177 |
// Legacy Link feature is supported only for the default bridge network. |
| 178 | 178 |
// return if this call to build join options is not for default bridge network |
| 179 |
- if n.Name() != defaultNetName {
|
|
| 179 |
+ // Legacy Link is only supported by docker run --link |
|
| 180 |
+ if _, ok := container.NetworkSettings.Networks[defaultNetName]; !container.HostConfig.NetworkMode.IsDefault() || !ok {
|
|
| 180 | 181 |
return sboxOptions, nil |
| 181 | 182 |
} |
| 182 | 183 |
|
| 183 |
- ep, _ := container.GetEndpointInNetwork(n) |
|
| 184 |
- if ep == nil {
|
|
| 184 |
+ if container.NetworkSettings.Networks[defaultNetName].EndpointID == "" {
|
|
| 185 | 185 |
return sboxOptions, nil |
| 186 | 186 |
} |
| 187 | 187 |
|
| 188 |
- var childEndpoints, parentEndpoints []string |
|
| 188 |
+ var ( |
|
| 189 |
+ childEndpoints, parentEndpoints []string |
|
| 190 |
+ cEndpointID string |
|
| 191 |
+ ) |
|
| 189 | 192 |
|
| 190 | 193 |
children := daemon.children(container) |
| 191 | 194 |
for linkAlias, child := range children {
|
| ... | ... |
@@ -200,9 +203,9 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libn |
| 200 | 200 |
aliasList = aliasList + " " + child.Name[1:] |
| 201 | 201 |
} |
| 202 | 202 |
sboxOptions = append(sboxOptions, libnetwork.OptionExtraHost(aliasList, child.NetworkSettings.Networks[defaultNetName].IPAddress)) |
| 203 |
- cEndpoint, _ := child.GetEndpointInNetwork(n) |
|
| 204 |
- if cEndpoint != nil && cEndpoint.ID() != "" {
|
|
| 205 |
- childEndpoints = append(childEndpoints, cEndpoint.ID()) |
|
| 203 |
+ cEndpointID = child.NetworkSettings.Networks[defaultNetName].EndpointID |
|
| 204 |
+ if cEndpointID != "" {
|
|
| 205 |
+ childEndpoints = append(childEndpoints, cEndpointID) |
|
| 206 | 206 |
} |
| 207 | 207 |
} |
| 208 | 208 |
|
| ... | ... |
@@ -219,8 +222,8 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libn |
| 219 | 219 |
alias, |
| 220 | 220 |
bridgeSettings.IPAddress, |
| 221 | 221 |
)) |
| 222 |
- if ep.ID() != "" {
|
|
| 223 |
- parentEndpoints = append(parentEndpoints, ep.ID()) |
|
| 222 |
+ if cEndpointID != "" {
|
|
| 223 |
+ parentEndpoints = append(parentEndpoints, cEndpointID) |
|
| 224 | 224 |
} |
| 225 | 225 |
} |
| 226 | 226 |
|
| ... | ... |
@@ -312,7 +315,7 @@ func (daemon *Daemon) updateNetwork(container *container.Container) error {
|
| 312 | 312 |
return nil |
| 313 | 313 |
} |
| 314 | 314 |
|
| 315 |
- options, err := daemon.buildSandboxOptions(container, n) |
|
| 315 |
+ options, err := daemon.buildSandboxOptions(container) |
|
| 316 | 316 |
if err != nil {
|
| 317 | 317 |
return fmt.Errorf("Update network failed: %v", err)
|
| 318 | 318 |
} |
| ... | ... |
@@ -570,7 +573,7 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName |
| 570 | 570 |
} |
| 571 | 571 |
|
| 572 | 572 |
if sb == nil {
|
| 573 |
- options, err := daemon.buildSandboxOptions(container, n) |
|
| 573 |
+ options, err := daemon.buildSandboxOptions(container) |
|
| 574 | 574 |
if err != nil {
|
| 575 | 575 |
return err |
| 576 | 576 |
} |
| ... | ... |
@@ -709,6 +712,9 @@ func (daemon *Daemon) getNetworkedContainer(containerID, connectedContainerID st |
| 709 | 709 |
} |
| 710 | 710 |
|
| 711 | 711 |
func (daemon *Daemon) releaseNetwork(container *container.Container) {
|
| 712 |
+ if daemon.netController == nil {
|
|
| 713 |
+ return |
|
| 714 |
+ } |
|
| 712 | 715 |
if container.HostConfig.NetworkMode.IsContainer() || container.Config.NetworkDisabled {
|
| 713 | 716 |
return |
| 714 | 717 |
} |
| ... | ... |
@@ -146,6 +146,7 @@ func (daemon *Daemon) restore() error {
|
| 146 | 146 |
|
| 147 | 147 |
var migrateLegacyLinks bool |
| 148 | 148 |
restartContainers := make(map[*container.Container]chan struct{})
|
| 149 |
+ activeSandboxes := make(map[string]interface{})
|
|
| 149 | 150 |
for _, c := range containers {
|
| 150 | 151 |
if err := daemon.registerName(c); err != nil {
|
| 151 | 152 |
logrus.Errorf("Failed to register container %s: %s", c.ID, err)
|
| ... | ... |
@@ -178,6 +179,16 @@ func (daemon *Daemon) restore() error {
|
| 178 | 178 |
logrus.Errorf("Failed to restore with containerd: %q", err)
|
| 179 | 179 |
return |
| 180 | 180 |
} |
| 181 |
+ if !c.HostConfig.NetworkMode.IsContainer() {
|
|
| 182 |
+ options, err := daemon.buildSandboxOptions(c) |
|
| 183 |
+ if err != nil {
|
|
| 184 |
+ logrus.Warnf("Failed build sandbox option to restore container %s: %v", c.ID, err)
|
|
| 185 |
+ } |
|
| 186 |
+ mapLock.Lock() |
|
| 187 |
+ activeSandboxes[c.NetworkSettings.SandboxID] = options |
|
| 188 |
+ mapLock.Unlock() |
|
| 189 |
+ } |
|
| 190 |
+ |
|
| 181 | 191 |
} |
| 182 | 192 |
// fixme: only if not running |
| 183 | 193 |
// get list of containers we need to restart |
| ... | ... |
@@ -209,6 +220,10 @@ func (daemon *Daemon) restore() error {
|
| 209 | 209 |
}(c) |
| 210 | 210 |
} |
| 211 | 211 |
wg.Wait() |
| 212 |
+ daemon.netController, err = daemon.initNetworkController(daemon.configStore, activeSandboxes) |
|
| 213 |
+ if err != nil {
|
|
| 214 |
+ return fmt.Errorf("Error initializing network controller: %v", err)
|
|
| 215 |
+ } |
|
| 212 | 216 |
|
| 213 | 217 |
// migrate any legacy links from sqlite |
| 214 | 218 |
linkdbFile := filepath.Join(daemon.root, "linkgraph.db") |
| ... | ... |
@@ -356,6 +371,15 @@ func (daemon *Daemon) SetClusterProvider(clusterProvider cluster.Provider) {
|
| 356 | 356 |
daemon.netController.SetClusterProvider(clusterProvider) |
| 357 | 357 |
} |
| 358 | 358 |
|
| 359 |
+// IsSwarmCompatible verifies if the current daemon |
|
| 360 |
+// configuration is compatible with the swarm mode |
|
| 361 |
+func (daemon *Daemon) IsSwarmCompatible() error {
|
|
| 362 |
+ if daemon.configStore == nil {
|
|
| 363 |
+ return nil |
|
| 364 |
+ } |
|
| 365 |
+ return daemon.configStore.isSwarmCompatible() |
|
| 366 |
+} |
|
| 367 |
+ |
|
| 359 | 368 |
// NewDaemon sets up everything for the daemon to be able to service |
| 360 | 369 |
// requests from the webserver. |
| 361 | 370 |
func NewDaemon(config *Config, registryService registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) {
|
| ... | ... |
@@ -530,11 +554,6 @@ func NewDaemon(config *Config, registryService registry.Service, containerdRemot |
| 530 | 530 |
return nil, err |
| 531 | 531 |
} |
| 532 | 532 |
|
| 533 |
- d.netController, err = d.initNetworkController(config) |
|
| 534 |
- if err != nil {
|
|
| 535 |
- return nil, fmt.Errorf("Error initializing network controller: %v", err)
|
|
| 536 |
- } |
|
| 537 |
- |
|
| 538 | 533 |
sysInfo := sysinfo.New(false) |
| 539 | 534 |
// Check if Devices cgroup is mounted, it is hard requirement for container security, |
| 540 | 535 |
// on Linux. |
| ... | ... |
@@ -912,15 +931,17 @@ func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
|
| 912 | 912 |
} |
| 913 | 913 |
} |
| 914 | 914 |
|
| 915 |
+ if daemon.clusterProvider != nil {
|
|
| 916 |
+ if err := config.isSwarmCompatible(); err != nil {
|
|
| 917 |
+ return err |
|
| 918 |
+ } |
|
| 919 |
+ } |
|
| 920 |
+ |
|
| 915 | 921 |
// check discovery modifications |
| 916 | 922 |
if !modifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, config.ClusterOpts) {
|
| 917 | 923 |
return nil |
| 918 | 924 |
} |
| 919 | 925 |
|
| 920 |
- if daemon.clusterProvider != nil {
|
|
| 921 |
- return fmt.Errorf("--cluster-store and --cluster-advertise daemon configurations are incompatible with swarm mode")
|
|
| 922 |
- } |
|
| 923 |
- |
|
| 924 | 926 |
// enable discovery for the first time if it was not previously enabled |
| 925 | 927 |
if daemon.discoveryWatcher == nil {
|
| 926 | 928 |
discoveryWatcher, err := initDiscovery(newClusterStore, newAdvertise, config.ClusterOpts) |
| ... | ... |
@@ -947,7 +968,7 @@ func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
|
| 947 | 947 |
if daemon.netController == nil {
|
| 948 | 948 |
return nil |
| 949 | 949 |
} |
| 950 |
- netOptions, err := daemon.networkOptions(daemon.configStore) |
|
| 950 |
+ netOptions, err := daemon.networkOptions(daemon.configStore, nil) |
|
| 951 | 951 |
if err != nil {
|
| 952 | 952 |
logrus.Warnf("Failed to reload configuration with network controller: %v", err)
|
| 953 | 953 |
return nil |
| ... | ... |
@@ -964,7 +985,7 @@ func isBridgeNetworkDisabled(config *Config) bool {
|
| 964 | 964 |
return config.bridgeConfig.Iface == disableNetworkBridge |
| 965 | 965 |
} |
| 966 | 966 |
|
| 967 |
-func (daemon *Daemon) networkOptions(dconfig *Config) ([]nwconfig.Option, error) {
|
|
| 967 |
+func (daemon *Daemon) networkOptions(dconfig *Config, activeSandboxes map[string]interface{}) ([]nwconfig.Option, error) {
|
|
| 968 | 968 |
options := []nwconfig.Option{}
|
| 969 | 969 |
if dconfig == nil {
|
| 970 | 970 |
return options, nil |
| ... | ... |
@@ -999,6 +1020,11 @@ func (daemon *Daemon) networkOptions(dconfig *Config) ([]nwconfig.Option, error) |
| 999 | 999 |
|
| 1000 | 1000 |
options = append(options, nwconfig.OptionLabels(dconfig.Labels)) |
| 1001 | 1001 |
options = append(options, driverOptions(dconfig)...) |
| 1002 |
+ |
|
| 1003 |
+ if daemon.configStore != nil && daemon.configStore.LiveRestore && len(activeSandboxes) != 0 {
|
|
| 1004 |
+ options = append(options, nwconfig.OptionActiveSandboxes(activeSandboxes)) |
|
| 1005 |
+ } |
|
| 1006 |
+ |
|
| 1002 | 1007 |
return options, nil |
| 1003 | 1008 |
} |
| 1004 | 1009 |
|
| ... | ... |
@@ -113,7 +113,7 @@ func configureKernelSecuritySupport(config *Config, driverName string) error {
|
| 113 | 113 |
return nil |
| 114 | 114 |
} |
| 115 | 115 |
|
| 116 |
-func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) {
|
|
| 116 |
+func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
|
|
| 117 | 117 |
return nil, nil |
| 118 | 118 |
} |
| 119 | 119 |
|
| ... | ... |
@@ -627,8 +627,8 @@ func configureKernelSecuritySupport(config *Config, driverName string) error {
|
| 627 | 627 |
return nil |
| 628 | 628 |
} |
| 629 | 629 |
|
| 630 |
-func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) {
|
|
| 631 |
- netOptions, err := daemon.networkOptions(config) |
|
| 630 |
+func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
|
|
| 631 |
+ netOptions, err := daemon.networkOptions(config, activeSandboxes) |
|
| 632 | 632 |
if err != nil {
|
| 633 | 633 |
return nil, err |
| 634 | 634 |
} |
| ... | ... |
@@ -638,16 +638,24 @@ func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkC |
| 638 | 638 |
return nil, fmt.Errorf("error obtaining controller instance: %v", err)
|
| 639 | 639 |
} |
| 640 | 640 |
|
| 641 |
+ if len(activeSandboxes) > 0 {
|
|
| 642 |
+ logrus.Infof("There are old running containers, the network config will not take affect")
|
|
| 643 |
+ return controller, nil |
|
| 644 |
+ } |
|
| 645 |
+ |
|
| 641 | 646 |
// Initialize default network on "null" |
| 642 |
- if _, err := controller.NewNetwork("null", "none", "", libnetwork.NetworkOptionPersist(false)); err != nil {
|
|
| 643 |
- return nil, fmt.Errorf("Error creating default \"null\" network: %v", err)
|
|
| 647 |
+ if n, _ := controller.NetworkByName("none"); n == nil {
|
|
| 648 |
+ if _, err := controller.NewNetwork("null", "none", "", libnetwork.NetworkOptionPersist(true)); err != nil {
|
|
| 649 |
+ return nil, fmt.Errorf("Error creating default \"null\" network: %v", err)
|
|
| 650 |
+ } |
|
| 644 | 651 |
} |
| 645 | 652 |
|
| 646 | 653 |
// Initialize default network on "host" |
| 647 |
- if _, err := controller.NewNetwork("host", "host", "", libnetwork.NetworkOptionPersist(false)); err != nil {
|
|
| 648 |
- return nil, fmt.Errorf("Error creating default \"host\" network: %v", err)
|
|
| 654 |
+ if n, _ := controller.NetworkByName("host"); n == nil {
|
|
| 655 |
+ if _, err := controller.NewNetwork("host", "host", "", libnetwork.NetworkOptionPersist(true)); err != nil {
|
|
| 656 |
+ return nil, fmt.Errorf("Error creating default \"host\" network: %v", err)
|
|
| 657 |
+ } |
|
| 649 | 658 |
} |
| 650 |
- |
|
| 651 | 659 |
if !config.DisableBridge {
|
| 652 | 660 |
// Initialize default driver "bridge" |
| 653 | 661 |
if err := initBridgeDriver(controller, config); err != nil {
|
| ... | ... |
@@ -183,7 +183,7 @@ func TestNetworkOptions(t *testing.T) {
|
| 183 | 183 |
}, |
| 184 | 184 |
} |
| 185 | 185 |
|
| 186 |
- if _, err := daemon.networkOptions(dconfigCorrect); err != nil {
|
|
| 186 |
+ if _, err := daemon.networkOptions(dconfigCorrect, nil); err != nil {
|
|
| 187 | 187 |
t.Fatalf("Expect networkOptions success, got error: %v", err)
|
| 188 | 188 |
} |
| 189 | 189 |
|
| ... | ... |
@@ -193,7 +193,7 @@ func TestNetworkOptions(t *testing.T) {
|
| 193 | 193 |
}, |
| 194 | 194 |
} |
| 195 | 195 |
|
| 196 |
- if _, err := daemon.networkOptions(dconfigWrong); err == nil {
|
|
| 196 |
+ if _, err := daemon.networkOptions(dconfigWrong, nil); err == nil {
|
|
| 197 | 197 |
t.Fatalf("Expected networkOptions error, got nil")
|
| 198 | 198 |
} |
| 199 | 199 |
} |
| ... | ... |
@@ -189,8 +189,8 @@ func configureMaxThreads(config *Config) error {
|
| 189 | 189 |
return nil |
| 190 | 190 |
} |
| 191 | 191 |
|
| 192 |
-func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) {
|
|
| 193 |
- netOptions, err := daemon.networkOptions(config) |
|
| 192 |
+func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
|
|
| 193 |
+ netOptions, err := daemon.networkOptions(config, nil) |
|
| 194 | 194 |
if err != nil {
|
| 195 | 195 |
return nil, err |
| 196 | 196 |
} |
| ... | ... |
@@ -59,6 +59,9 @@ func (daemon *Daemon) GetNetworkByID(partialID string) (libnetwork.Network, erro |
| 59 | 59 |
// GetNetworkByName function returns a network for a given network name. |
| 60 | 60 |
func (daemon *Daemon) GetNetworkByName(name string) (libnetwork.Network, error) {
|
| 61 | 61 |
c := daemon.netController |
| 62 |
+ if c == nil {
|
|
| 63 |
+ return nil, libnetwork.ErrNoSuchNetwork(name) |
|
| 64 |
+ } |
|
| 62 | 65 |
if name == "" {
|
| 63 | 66 |
name = c.Config().Daemon.DefaultNetwork |
| 64 | 67 |
} |
| ... | ... |
@@ -68,6 +71,9 @@ func (daemon *Daemon) GetNetworkByName(name string) (libnetwork.Network, error) |
| 68 | 68 |
// GetNetworksByID returns a list of networks whose ID partially matches zero or more networks |
| 69 | 69 |
func (daemon *Daemon) GetNetworksByID(partialID string) []libnetwork.Network {
|
| 70 | 70 |
c := daemon.netController |
| 71 |
+ if c == nil {
|
|
| 72 |
+ return nil |
|
| 73 |
+ } |
|
| 71 | 74 |
list := []libnetwork.Network{}
|
| 72 | 75 |
l := func(nw libnetwork.Network) bool {
|
| 73 | 76 |
if strings.HasPrefix(nw.ID(), partialID) {
|