Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add builtin nodes discovery #16229

Merged
merged 2 commits into from Sep 28, 2015
Merged

Add builtin nodes discovery #16229

merged 2 commits into from Sep 28, 2015

Conversation

icecrime
Copy link
Contributor

Use pkg/discovery to provide nodes discovery between daemon instances.

The functionality is driven by two different command-line flags:
--discovery-backend and --discovery-address. It can be used in two
ways by interested components:

  1. Externally by calling the /info API and examining the discovery
    backend. The pkg/discovery package can then be used to hit the same
    endpoint and watch for appearing or disappearing nodes. That is the
    method that will for example be used by Swarm.
  2. Internally by using the Daemon.discoveryWatcher instance. That is
    the method that will for example be used by libnetwork.

Ping @abronan @mavenugo @vieux.

@duglin
Copy link
Contributor

duglin commented Sep 10, 2015

@icecrime is there a design doc that describes how this works? In particular, what is relationship with swarm? I wasn't aware that we were headed towards a single daemon knowing about other daemons.

}

// Watch is exported
func (s *Discovery) Watch(stopCh <-chan struct{}) (<-chan discovery.Entries, <-chan error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know if it's overengineering for this case, but we could use inotify to avoid polling the file (at least on Linux).

https://godoc.org/golang.org/x/exp/inotify

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or fsnotify which is cross-platform and already vendored... but still need to fallback to polling as I've seen multiple people with issues on docker logs -f which is using inotify.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, but can be done in a separate PR as the engine won't use file (only swarm uses it)

@icecrime icecrime force-pushed the discovery branch 2 times, most recently from ff3626d to 1454028 Compare September 11, 2015 00:19
return []string{pattern}
}

template := re.ReplaceAllString(pattern, "%d")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this will break with a pattern that matches the regexp multiple times. It will also behave strangely if the pattern includes a % character or a printf directive. I feel it's better to avoid using Sprintf with a user-controlled format string.

@icecrime
Copy link
Contributor Author

@duglin Unfortunately, I don't have a design doc: let me try to summarize in a few sentences.

Both Swarm and mutihost networking require nodes discovery. On the Swarm side, this is nicely done with a well delimited discovery package. The idea here is to take in this package at the Engine level, thus providing a single nodes discovery mechanism to rely on:

  • Swarm can query the Engine on the /info endpoint and learn about the discovery backend in use. By instantiating a discovery itself, it can then watch for nodes membership changes.
  • Libnetwork can use the daemon.discoveryWatcher field and watch for nodes membership changes.

This is an quick and easy way to provide such facility in the Engine. In the future, we could imagine exposing nodes membership changes as part of the /events API, or provide a new endpoint to get the list of known neighbor nodes.

@icecrime icecrime force-pushed the discovery branch 2 times, most recently from 7bf0ad4 to b60e7ad Compare September 11, 2015 01:22
@icecrime
Copy link
Contributor Author

This is broken because ./hack/vendor.sh magic is removing the stretchr/testify dependency. Go figure. (ping @jfrazelle)

@jessfraz
Copy link
Contributor

I know how to fix PR will come when I get home

On Thursday, September 10, 2015, Arnaud Porterie notifications@github.com
wrote:

This is broken because ./hack/vendor.sh magic is removing the
stretchr/testify dependency. Go figure. (ping @jfrazelle
https://github.com/jfrazelle)


Reply to this email directly or view it on GitHub
#16229 (comment).

@LK4D4
Copy link
Contributor

LK4D4 commented Sep 11, 2015

Is pkg/discovery copy of some package or what? Why it uses testify at first place?

@vieux
Copy link
Contributor

vieux commented Sep 11, 2015

@LK4D4 this package is in swarm, we use testify in swarm.
As the ownership of this pkg is going to shift toward the engine, I'm fine with rewriting the test to look like the other docker/docker/pkg

As soon as it's moved, we are going to remove it from swarm and vendor this one.

@LK4D4
Copy link
Contributor

LK4D4 commented Sep 11, 2015

Maybe we should look to releasing some cool libs under docker organization. Because as I see pkg is still unnoticed by community. Same for distribution/context btw.

@cpuguy83
Copy link
Member

+1 for under a separate repo.

@duglin
Copy link
Contributor

duglin commented Sep 11, 2015

@LK4D4 +1 to a spot for generic packages

@icecrime
Copy link
Contributor Author

  • Agree we need a better place for generic packages (I think @duglin had ideas about that).
  • I took the Swarm discovery package as it is with a few interface changes: the file, node, and token strategies are actually not used by the Engine. Do we have to fix as part of this PR?

PR is update and rebased to fix the broken tests (thanks @jfrazelle)!

@abronan
Copy link
Contributor

abronan commented Sep 11, 2015

As part of the concern on keeping this under pkg, we can still incubate this here and move this in a reasonable time frame under its own repository. We did this for swarm and libkv and it worked pretty well. This lets the time to migrate the tests and see how it works for both swarm and libnetwork.

@icecrime
Copy link
Contributor Author

+1 @abronan

Tests are still broken, probably related to vendor pruning (reping @jfrazelle, sorry).

@mavenugo
Copy link
Contributor

+1 @abronan.

@mavenugo
Copy link
Contributor

@icecrime the test failures are due to the invalid kv-store configuration outside of the experimental. this requires a fix from libnetwork to be vendored-in. I will push a PR to vendor-in latest libnetwork and that will unblock this PR.

Absorb Swarm's discovery package in order to provide a common node
discovery mechanism to be used by both Swarm and networking code.

Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
@icecrime
Copy link
Contributor Author

Updated to take last discussions into account. Also rebased: with latest libkv/libnetwork change the tests should hopefully be green.


// Creates a new store, will ignore options given
// if not supported by the chosen store
s.store, err = libkv.NewStore(s.backend, addrs, nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My hunch is this will probably have to come in a subsequent change, but it would be nice to support configuration settings for libkv. In particular, in multi-host environments, being able to set up ClientTLS configuration based on docker/libkv@e7f836c would be beneficial.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dhiltgen yes. this will come as a subsequent PR. also, we need to work with Darren on the PR to make this a 1-time dynamic configuration.

Use `pkg/discovery` to provide nodes discovery between daemon instances.

The functionality is driven by two different command-line flags: the
experimental `--cluster-store` (previously `--kv-store`) and
`--cluster-advertise`. It can be used in two ways by interested
components:

1. Externally by calling the `/info` API and examining the cluster store
   field. The `pkg/discovery` package can then be used to hit the same
   endpoint and watch for appearing or disappearing nodes. That is the
   method that will for example be used by Swarm.
2. Internally by using the `Daemon.discoveryWatcher` instance. That is
   the method that will for example be used by libnetwork.

Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
@abronan
Copy link
Contributor

abronan commented Sep 26, 2015

LGTM, let's address enhancements and documentation in other PRs (like for the /join and /leave endpoints).

@mavenugo
Copy link
Contributor

Thanks @icecrime. LGTM.

@mavenugo
Copy link
Contributor

@aluzzardi if you agree, we should merge this and that will unblock the dependent PRs. As discussed, the backend updates can be taken up in subsequent PRs.

@vieux
Copy link
Contributor

vieux commented Sep 26, 2015

LGTM as well

@aluzzardi
Copy link
Member

LGTM

aluzzardi added a commit that referenced this pull request Sep 28, 2015
@aluzzardi aluzzardi merged commit 9324b15 into moby:master Sep 28, 2015
@vieux
Copy link
Contributor

vieux commented Sep 28, 2015

\o/

// ClusterStore is the storage backend used for the cluster information. It is used by both
// multihost networking (to store networks and endpoints information) and by the node discovery
// mechanism.
ClusterStore string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically, the convention in Go is to identify stringly-typed network endpoint fields with Addr. This should be ClusterStoreAddr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet