8000 Configuration files for services by aaronlehmann · Pull Request #32336 · moby/moby · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Configuration files for services #32336

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

Merged
merged 6 commits into from
May 11, 2017
Merged

Configuration files for services #32336

merged 6 commits into from
May 11, 2017

Conversation

aaronlehmann
Copy link
Contributor
@aaronlehmann aaronlehmann commented Apr 4, 2017

This adds a docker config subcommand and related APIs that allows "config" objects to be attached to services. Config files can be mounted inside services' containers, avoiding the need to bake configuration into images.

Configuration files are similar to secrets, and in fact the CLI and API show few differences between the two. The principal differences so far are:

  • Secrets are always redacted at the API level, so the payload cannot be obtained through an API call after they are created.
  • Secrets are restricted to the /run/secrets directory inside the container, as a design choice. Config files can be mounted anywhere.

We are expecting to introduce some additional features for configs in the future that may cause the feature to diverge further from secrets. Although secrets and configs are very similar right now, we decided that creating a parallel API and subcommand was better than overloading secrets for use by things that do not have the same confidentiality requirements.

I suspect one thing that will come up in the review process is duplication of code between secrets and configs. This is definitely an issue, and I would have liked to reduce the level of duplication. However, with separate APIs and CLI subcommands, a certain amount of code duplication is unavoidable. Since the APIs use different types, and Go doesn't support generics, it's difficult to reuse code between the two implementations. Also, I didn't want to prematurely refactor things, since it's very possible that configs and secrets will diverge more soon (perhaps even during the review process). But if there are any suggestions for easy wins on reducing duplicated code, they are certainly welcome.

This feature is wanted for 17.05.

Marked WIP because this depends on moby/swarmkit#2036 (which should be merged shortly).

ping @dhiltgen @dnephin @aluzzardi @diogomonica

@dnephin
Copy link
Member
dnephin commented Apr 5, 2017

I would rather see secrets implemented as a --secret flag on config to enable the "secret behaviour". Having two objects that are nearly identical is really unfortunate. I'm not sure what we do about this now that secrets already exist. Maybe docker secrets becomes a hidden alias for docker config which sets that flag?

Secrets are always redacted at the API level, so the payload cannot be obtained through an API call after they are created.

Unless I run this ?

docker service create --secret foo --name printsecrets alpine:3.5 cat /run/secrets/foo
docker service logs printsecrets

Secrets are restricted to the /run/secrets directory inside the container, as a design choice. Config files can be mounted anywhere.

Do you know where I can learn more about this design choice?

@diogomonica
Copy link
Contributor

@dnephin there are a lot of things packed in there. Ultimately we want to make sure people deal with sensitive data in a different way than they deal with configs.

  • Having two distinct cmd-line arguments and two distinct APIs allows us to separate the roles of managing secrets from managing configs. It's easy to imagine a team being in charge of secrets and another team just being responsible for their own configs.
  • Making secrets restrictive where they can be found creates consistency of where they live across containers, and allows security teams to reason better about permissions/access to sensitive material inside of the container.
  • Configs will diverge significantly from secrets. It doesn't make a lot of sense to template a secret, but it makes sense to template a config, for example. Also it allows us to have different experiences to deal with sensitive data (secret data is never returned to the user after set), than we have with configs (you can always inspect the material inside.

I agree that a lot of these reasons are nuanced, but we feel like separating them is the right way to move forward.

8000

@@ -168,6 +169,21 @@ func (container *Container) SecretMountPath() string {
return filepath.Join(container.Root, "secrets")
}

// ConfigsDirPath returns the path to the directory where configs are stored on
// disk.
func (container *Container) ConfigsDirPath() string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't this be /configs/?

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 is where they are stored on the host filesystem, for mounting into the container.

}

// ConfigFilePath returns the path to the on-disk location of a config.
func (container *Container) ConfigFilePath(configRefTarget *swarmtypes.ConfigReferenceFileTarget) (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Weren't configs supposed to be mountable anywhere?

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 is referring to the path on the host. It gets bind-mounted at the target path inside the container.

@aaronlehmann aaronlehmann changed the title [WIP] Configuration files for services Configuration files for services Apr 5, 2017
@aaronlehmann
Copy link
Contributor Author

moby/swarmkit#2036 was merged upstream. Updated to incorporate proper swarmkit vendor. No longer marked WIP.

@dnephin
Copy link
Member
dnephin commented Apr 6, 2017

secret data is never returned to the user after set

Sure it is, we've just made it slightly inconvenient.

docker service create --secret foo --name printsecrets alpine:3.5 cat /run/secrets/foo
docker service logs printsecrets

@diogomonica
Copy link
Contributor

@dnephin I think you would agree those are separate concerns. Not allowing accidental secret retrieval by using the API (specially on the list secrets endpoint, which would return all secrets in plaintext), is not the same thing as a user intentionally deploying services with legitimate secret access to exfiltrate them.

@aaronlehmann
Copy link
Contributor Author

I've rebased and marked configs as an experimental feature. The API endpoints, CLI subcommand, flags for service create / service update, and integration tests only run in experimental mode. PTAL

@dnephin
Copy link
Member
dnephin commented Apr 7, 2017

@dnephin I think you would agree those are separate concerns.

Sorry, separate from what? I was responding to this statement "secret data is never returned to the user after set", which I believe I've demonstrated to be incorrect. We do allow secret data to be returned, we've just made it (afaik unnecessarily) inconvenient.

Not allowing accidental secret retrieval by using the API (specially on the list secrets endpoint, which would return all secrets in plaintext)

Why would the list endpoint returns secret text? Most list endpoints do not return full data. They only return "summary data". I don't think the "list secret" endpoint needs to change. It would be equally appropriate for a "list configs" endpoint as it is now.

... is not the same thing as a user intentionally deploying services with legitimate secret access to exfiltrate them.

I agree, but how accidental is docker secret inspect foo ? That seems like it's just as intentional.

This was just a response to "Also it allows us to have different experiences to deal with sensitive data", which is what I'm challenging.

I think for many users the distinction between a config and a secret is not clear. Many popular web frameworks expect credentials to be read from their config file. If users have passwords in their config files they should be using secrets, but they may also want to template that same config file. So I think it's quite possible that users will want to template secrets as well.

Having two distinct cmd-line arguments and two distinct APIs allows us to separate the roles of managing secrets from managing configs.

Even if this was a common case, it does not require two separate API endpoints or cmd-line arguments. Users are free to implement whatever process makes sense to them.

Configs will diverge significantly from secrets

So far I don't see an argument for this:

  • hiding them from the user - easily bypassed with a service create/logs, so not really significant (unless I'm misunderstanding this point)
  • templating - just as easily applied to "configs" that contain sensitive data , which would be considered "secrets"

@dnephin
Copy link
Member
dnephin commented Apr 7, 2017

Another issue that came up during the maintainers PR review session (that I guess wasn't mentioned here yet) is that docker config doesn't really do what you would expect. I would have expected that command to configure docker or dockerd, not just services.

Couldn't we just use secrets as they are now. Add a proper secret inspect and if/when the implementation actually requires some significant difference between these types we can add --sensitive=false (or some similar flag) to change the behaviour? Maybe that's already the case with the path restrictions?

@aluzzardi
Copy link
Member

Couldn't we just use secrets as they are now. Add a proper secret inspect and if/when the implementation actually requires some significant difference between these types we can add --sensitive=false (or some similar flag) to change the behaviour? Maybe that's already the case with the path restrictions?

  • Secrets and Configs are going to diverge more and more
  • Configs will be supporting templates and things like that
  • Secrets will support types
  • Having config secrets doesn't make sense. We could have had secret configs, but it's way too late now.

@aaronlehmann
Copy link
Contributor Author

Added config CLI unit tests inspired by #32289.

@cpuguy83
Copy link
Member
cpuguy83 commented Apr 7, 2017

Having these as experimental I think makes sense. It gives us time to let people test the feature before 17.06-stable and potentially pull it if it's not quite right.
Other than object/subcommand naming, I think it's good.

One suggestion made by @thaJeztah I think was docker stash (though that's a verb I would expect to be docker sash <name> -< <data>).
Not sure what else to call it.

@diogomonica
Copy link
Contributor

Sorry, separate from what? I was responding to this statement "secret data is never returned to the user after set", which I believe I've demonstrated to be incorrect. We do allow secret data to be returned, we've just made it (afaik unnecessarily) inconvenient.

No, you demonstrated that you can deploy an app that can exfiltrate secrets that have been handed to it, you didn't demonstrate the API allows you to leak secrets. That is what I mean by separate concerns.

If you really want to protect your swarm from maliciously deployed containers, you'll have to deploy an AuthZ plugin that only runs signed code and segment the concerns.

I agree, but how accidental is docker secret inspect foo ? That seems like it's just as intentional.

Minimizing the ways secrets can get leaked from your swarm is a worth goal.

I think for many users the distinction between a config and a secret is not clear. Many popular web frameworks expect credentials to be read from their config file. If users have passwords in their config files they should be using secrets, but they may also want to template that same config file. So I think it's quite possible that users will want to template secrets as well.

This is why we would like to template configs, so you can include secrets in them without having to handle configs themselves as sensitive.

This was just a response to "Also it allows us to have different experiences to deal with sensitive data", which is what I'm challenging.

You're absolutely entitled to have your opinion; ours (secrets team) has been that production setups always have distinct treatment/confidentiality/apis/control around what they deem to be secret data, and therefore, we should keep them separate.

@vieux vieux changed the title Configuration files for services [experimental] Configuration files for services Apr 7, 2017
@vieux vieux added this to the 17.05.0 milestone Apr 7, 2017
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
@aaronlehmann
Copy link
Contributor Author

Rebased

@vieux
Copy link
Contributor
vieux commented May 11, 2017

LGTM

@mavenugo
Copy link
Contributor

Janky failure (TestSwarmClusterRotateUnlockKey) is unrelated and this PR has gone through multiple rebases and I think it is time to put it out of its misery and merge the PR :)

@vieux vieux merged commit 69c35da into moby:master May 11, 2017
@vieux
Copy link
Contributor
vieux commented May 11, 2017

@aaronlehmann 🎉 🎉

albers added a commit to albers/docker-cli that referenced this pull request Jul 3, 2017
This adds bash completion for
- docker#45
- moby/moby#32336

Signed-off-by: Harald Albers <github@albersweb.de>
albers added a commit to albers/docker-cli that referenced this pull request Jul 7, 2017
This adds bash completion for
- docker#45
- moby/moby#32336

Signed-off-by: Harald Albers <github@albersweb.de>
thaJeztah pushed a commit to thaJeztah/docker-ce that referenced this pull request Jul 25, 2017
This adds bash completion for
- docker/cli#45
- moby/moby#32336

Signed-off-by: Harald Albers <github@albersweb.de>
(cherry picked from commit c40952b3058db3c6e44bca8c518d888b83878ce5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
alshabib pushed a commit to alshabib/cli that referenced this pull request Aug 1, 2017
This adds bash completion for
- docker#45
- moby/moby#32336

Signed-off-by: Harald Albers <github@albersweb.de>
riyazdf pushed a commit to riyazdf/cli that referenced this pull request Aug 2, 2017
This adds bash completion for
- docker#45
- moby/moby#32336

Signed-off-by: Harald Albers <github@albersweb.de>
silvin-lubecki pushed a commit to silvin-lubecki/docker-ce that referenced this pull request Jan 29, 2020
This adds bash completion for
- docker/cli#45
- moby/moby#32336

Signed-off-by: Harald Albers <github@albersweb.de>
(cherry picked from commit c40952b3058db3c6e44bca8c518d888b83878ce5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
silvin-lubecki pushed a commit to silvin-lubecki/cli-extract that referenced this pull request Jan 30, 2020
This adds bash completion for
- docker/cli#45
- moby/moby#32336

Signed-off-by: Harald Albers <github@albersweb.de>
(cherry picked from commit c40952b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
kolyshkin pushed a commit to kolyshkin/moby that referenced this pull request May 4, 2020
Replicate relevant mutations to the in-memory ACID store. Readers will
then be able to query container state without locking.

Signed-off-by: Fabio Kung <fabio.kung@gmail.com>
(cherry picked from commit eed4c7b)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>

Conflicts:
 - daemon/daemon.go: missing moby#33241
 - container/container_unix.go: missing moby#32336
 - container/container_windows.go, daemon/container_operations.go: minor conflicts

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
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.

0