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

Allow to set daemon and server configurations in a file. #18587

Merged
merged 3 commits into from Jan 15, 2016

Conversation

calavera
Copy link
Contributor

Still a work in progress but I thought it could be a good idea to show this now that mostly works.

Read configuration after flags making this the priority:

1- Apply configuration from file.
2- Apply configuration from flags.

Reload configuration when it a signal is received, HUP in Linux:

  • Reload router if the debug configuration changes.
  • Reload daemon labels.
  • Reconfigure and restart cluster discovery.

daemon-config

Closes #17559
Signed-off-by: David Calavera david.calavera@gmail.com

@calavera calavera changed the title [WIP] Add daemon configuration flag. [WIP] Add daemon configuration file. Dec 10, 2015
@calavera calavera changed the title [WIP] Add daemon configuration file. [WIP] Allow to set daemon and server configurations in a file. Dec 10, 2015
@calavera calavera force-pushed the daemon_configuration_file branch 2 times, most recently from 20d7352 to 7255c49 Compare December 11, 2015 00:03
@@ -47,6 +47,9 @@ func NewDaemonCli() *DaemonCli {
daemonConfig := new(daemon.Config)
daemonConfig.LogConfig.Config = make(map[string]string)
daemonConfig.ClusterOpts = make(map[string]string)

daemonFlags.StringVar(&daemonConfig.ConfigurationFile, []string{"-config"}, "", "Daemon configuration file")
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about having a default path, and then doing the fsnotify watch even if it doesn't exist so we can catch creation of the file after the daemon starts up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it makes sense. I'll play with it to see how it feels.

@dhiltgen
Copy link
Contributor

Very cool! Thanks for picking this up! :-)

@duglin
Copy link
Contributor

duglin commented Dec 11, 2015

@calavera I might be misreading your comment, but does the config file flags override the cmd line flags? If so, I think it should be the other way around. I believe, typically, its: process config file, env vars and then cmd line flags - where last one in that list wins.

@calavera
Copy link
Contributor Author

@duglin I think I agree with you. I started implementing it that way but I had some issues with duplicated flags. Definitely worth considering.

@calavera calavera force-pushed the daemon_configuration_file branch 4 times, most recently from 20f3bbc to d7b5f20 Compare December 11, 2015 23:14
}
}()

watcher.Add(configFile)
Copy link
Member

Choose a reason for hiding this comment

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

Note that this can return an error due to things like inotify exhaustion.
This is really where fallback to polling should happen (if you want it to fallback).

@cpuguy83
Copy link
Member

While I like auto-reloading on changes, it seems like it could be dangerous due to partial changes.
I'd go with the safer route of having an explicit way to reload (such as a signal handler and/or an API endpoint).

@thaJeztah
Copy link
Member

We may need a "configcheck" option, so that the configuration can be validated before its applied

@runcom
Copy link
Member

runcom commented Dec 18, 2015

I agree with @duglin the order of configs should be first config file, then flags (elasticsearch for instance works this way IIRC)
The config reload honestly seems like a big plus to me (for an initial config file PR), I might live w/o it and have to restart the daemon :)

@thaJeztah thaJeztah added the status/needs-attention Calls for a collective discussion during a review session label Dec 29, 2015
@calavera
Copy link
Contributor Author

calavera commented Jan 4, 2016

Thank you all for your feedback! 💪

Given what I'm reading in these comments, and that the release freeze is close, I think this is the best plan to approach this feature for 1.10:

  1. Config reading order: file first, flags second
  2. Remove file watcher, use a signal (HUP) to trigger a config reload.
  3. Check configuration before applying reload.

I'd also like to restrict the configuration elements we reload in this first version to only these:

  1. Debug flag: reload logger and server routes to enable/disable debugging without restarting the daemon.
  2. Damon labels: reset these labels with new values. We won't do any diff-ing, it's all or nothing.
  3. Discovery: reset backend, stop advertising in the old backend and advertise in the new backend.

@dhiltgen please, take a look at this, I'd like to make sure you're okay with this initial set of features.

@dhiltgen
Copy link
Contributor

dhiltgen commented Jan 4, 2016

Yes, I think this should work. Thanks!

@calavera calavera added this to the 1.10.0 milestone Jan 5, 2016
@nathanleclaire
Copy link
Contributor

Cool @calavera . Like @cpuguy83 mentioned, what's the reasoning for watching the file and reloading automatically when something changes? Some things to consider in this regard:

  • Why violate existing convention of tools such as HAproxy and nginx doing "hot reload" of configuration using UNIX signals? (e.g. SIGHUP instructs nginx to reload configuration http://nginx.org/en/docs/beginners_guide.html#control)
  • What happens if an operator saves the file in an incomplete or invalid state?
  • What happens if the editor or method of modifying the file (e.g. a tool like Ansible) happens to end up sending a lot of write events? Yes there is a mutex, but the daemon could still potentially trigger an order of magnitude more reloads than required.

@calavera
Copy link
Contributor Author

calavera commented Jan 5, 2016

@nathanleclaire read my latest comment (before this one)

@nathanleclaire
Copy link
Contributor

@calavera Ah OK I didn't see. That seems reasonable -- thanks!

@thaJeztah
Copy link
Member

ping @vdemeester @MHBauer @jamtur01 for review <3

## Daemon configuration file

The `--config-file` option allows you to set any configuration option for the daemon
in a JSON format. This file uses the flag names as keys to set documentation. By
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file uses the flag names as keys to set documentation

no idea what this means, looking for alternatives.

@vdemeester
Copy link
Member

@calavera you need to update man/docker-daemon.8.md too 😝

to restart the process. We use SIGHUP in Linux to reload and a global event
in Windows with the key `Global\docker-daemon-config-$PID`. The options can
be modified in the configuration file but still will check for conflicts with
the provided flags. The daemon fails to reconfigure itself if there are conflicts
Copy link
Contributor Author

Choose a reason for hiding this comment

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

conflicts but

conflicts, but

@calavera calavera force-pushed the daemon_configuration_file branch 2 times, most recently from 5993f86 to 961de3c Compare January 14, 2016 19:20
@calavera
Copy link
Contributor Author

@vdemeester done, thanks!

@vdemeester
Copy link
Member

@calavera another question about the output when there is conflicts. With 2 conflicts, I ended up with that :

unable to configure the Docker daemon with file /etc/docker/daemon.json: the following directives are specified both as a flag and in the configuration file: debug
: (from flag: true, from file: true), labels: (from flag: [bar=foo], from file: [foo=bar])

I think it would be a clearer if we put one conflict by line (carriage return, etc..), something like :

unable to configure the Docker daemon with file /etc/docker/daemon.json: 
the following directives are specified both as a flag and in the configuration file: 
- debug: (from flag: true, from file: true)
- labels: (from flag: [bar=foo], from file: [foo=bar])

wdyt ? 😝 👼

@calavera
Copy link
Contributor Author

I think it would be a clearer if we put one conflict by line (carriage return, etc..), something like

that option was discarded after @cpuguy83's comment

### Configuration reloading

Some options can be reconfigured when the daemon is running without requiring
to restart the process. We use SIGHUP in Linux to reload, and a global event
Copy link
Member

Choose a reason for hiding this comment

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

Maybe SIGHUP 😝

Copy link
Contributor

Choose a reason for hiding this comment

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

or: "We use the SIGHUP signal"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed with "We use the SIGHUP signal"`

@vdemeester
Copy link
Member

small nit but docs LGTM 🐮

Read configuration after flags making this the priority:

1- Apply configuration from file.
2- Apply configuration from flags.

Reload configuration when a signal is received, USR2 in Linux:

- Reload router if the debug configuration changes.
- Reload daemon labels.
- Reload cluster discovery.

Signed-off-by: David Calavera <david.calavera@gmail.com>
@thaJeztah
Copy link
Member

docs LGTM \o/

@tiborvass
Copy link
Contributor

@thaJeztah
Copy link
Member

It's greeeeeeen!

thaJeztah added a commit that referenced this pull request Jan 15, 2016
Allow to set daemon and server configurations in a file.
@thaJeztah thaJeztah merged commit e44364e into moby:master Jan 15, 2016
@calavera calavera deleted the daemon_configuration_file branch January 15, 2016 02:54
@neg3ntropy
Copy link

This looks cool, but its potential is far from delivered. It's still totally undocumented at https://docs.docker.com/engine/admin/configuring/ and a user has no idea of what settings are supported and what is the syntax.

I will say that config file is the way to go by default for packaged docker: it's way easier than overriding the systemd unit.
Possibly yaml (with plenty of comments) is a better file format than json. A lot of unix services come with a well documented config file and most of the time it's enough to read through it and uncomment/change lines. It saves many trips to the web.

Other than SIGHUP, I would also consider a docker daemon --reload-config or similar.

@thaJeztah
Copy link
Member

@soulrebel agreed that the documentation for configuring the daemon needs to be touched up (in general as well, because the docs is now spread over several locations)

For using this file by default, see this issue #20151, which I opened to discuss that.

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