Skip to content

Adds a devadd cli command and a native/lxc backend implementation#6369

Closed
calfonso wants to merge 4 commits intomoby:masterfrom
calfonso:device_add
Closed

Adds a devadd cli command and a native/lxc backend implementation#6369
calfonso wants to merge 4 commits intomoby:masterfrom
calfonso:device_add

Conversation

@calfonso
Copy link
Copy Markdown
Contributor

This commit is dependent upon #6134 being merged

@calfonso
Copy link
Copy Markdown
Contributor Author

This PR is also dependent upon a couple libcontainer PRs being merged and vendored. Those pull requests are:
docker-archive/libcontainer#6
docker-archive/libcontainer#7

@vbatts
Copy link
Copy Markdown
Contributor

vbatts commented Jun 24, 2014

@calfonso what are the use cases? links to docs or requirements?

@calfonso
Copy link
Copy Markdown
Contributor Author

Just to add some context of why we want to add a device at runtime...
Although this API is useful in general, it specifically gives us the ability to have OpenStack Nova APIs call the docker container hypervisor plugin to dynamically attach and detach a volume. In order for us to add the hypervisor plugin to OpenStack, the hypervisor plugin needs to implement certain features - including a runtime attaching/detaching of storage.

@calfonso
Copy link
Copy Markdown
Contributor Author

@shykes thoughts on this?

@SvenDowideit
Copy link
Copy Markdown
Contributor

@calfonso this PR will need documentation added - both to cli.md and to the dcos/man pages - you can wait til you've had confirmation from the core devs, or use it as an opportunity to explain the feature's intentions :)

calfonso added a commit to calfonso/nova-docker that referenced this pull request Jun 26, 2014
* This commit is dependent on several pull requests being merged into
docker and libcontainer that expose the devadd and devrm API.
moby/moby#6369
docker-archive/libcontainer#6
docker-archive/libcontainer#7

Change-Id: I6dcd7d809027bfe6ddcd9d521e519656a1ad526a
@calfonso
Copy link
Copy Markdown
Contributor Author

calfonso commented Jul 2, 2014

@SvenDowideit Thanks for the heads up. I've added a commit for the docs to this PR.

@SvenDowideit
Copy link
Copy Markdown
Contributor

@calfonso you're missing the DCO on the last commit - There is a githook in the CONTRIBUTING.md that will do it for you...

@ibuildthecloud
Copy link
Copy Markdown
Contributor

I'm opposed to this. I do not believe volume attach/detach is a useful operation for a container. I feel this is the side effect of trying to shove containers into a VM model. If you want to treat a container as a VM then just use libvirt-lxc.

@calfonso
Copy link
Copy Markdown
Contributor Author

calfonso commented Jul 4, 2014

@ibuildthecloud would you mind elaborating a bit on the lack of usefulness? It is useful to be able to attach storage to a running container in that a service doesn't need to be terminated to attach storage.

@SvenDowideit
Copy link
Copy Markdown
Contributor

I'm curious to see if this set of PR's (including the closed unmerged one in libcontainer) will help @jpetazzo and me do some slightly cool and dubious things with sharing mounts made from inside a container to another container

@calfonso
Copy link
Copy Markdown
Contributor Author

calfonso commented Jul 5, 2014

@SvenDowideit ewindisch has done a bit of research on using libseccomp to do a secure mount, which is not part of this patch set. These patches will enable sharing devices though!

@SvenDowideit
Copy link
Copy Markdown
Contributor

@ewindisch @jpetazzo perhaps we all need to get together sometime soon :)

@jpetazzo
Copy link
Copy Markdown
Contributor

jpetazzo commented Jul 7, 2014

@SvenDowideit wait, that's totally not the same thing. This dynamically grants access to a device, using the corresponding cgroup. We were working on dynamic bind mounts (or even mounts). Of course, if you want to mount a filesystem sitting on a "real" device, that helps. But that's not what I was working on, sorry!

@SvenDowideit
Copy link
Copy Markdown
Contributor

@jpetazzo yes, i realise its not the same thing - but its all related :)

@ewindisch
Copy link
Copy Markdown
Contributor

@calfonso note that #6134 introduces language into the documentation around the security of ephemeral devices being added and not being able to be removed. It would be worth amending that documentation with the ability to 'docker devrm' devices. There would still be security risks dependent on how users manage these device bindings, but this partially addresses those concerns.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you'll need to indent this and put newlines around it to make it rendered as code, and atm, we prefix commandlines with $ (dollar space)

@SvenDowideit
Copy link
Copy Markdown
Contributor

Docs essentially LGTM

calfonso and others added 4 commits July 21, 2014 10:35
Co-Authored-By: Ian Main <[email protected]>
Docker-DCO-1.1-Signed-off-by: Chris Alfonso <[email protected]> (github: calfonso)
Implement the backend for device add in both native and LXC exec drivers.
These both make use of the nsenter_mknod() function added to libcontainer.

Co-Authored-By: Chris Alfonso <[email protected]>
Docker-DCO-1.1-Signed-off-by: Ian Main <[email protected]> (github: imain)
* Use docker devrm CONTAINER_ID device_path to remove a
device

Co-Authored-By: Ian Main <[email protected]>
Docker-DCO-1.1-Signed-off-by: Chris Alfonso <[email protected]> (github: calfonso)
* Added descriptions and examples for the cli.md and man pages for the
  following:
  docker devadd CONTAINER DEVICE
  docker devrm CONTAINER DEVICE

Docker-DCO-1.1-Signed-off-by: Chris Alfonso <[email protected]> (github: calfonso)
@ewindisch
Copy link
Copy Markdown
Contributor

ping @shykes @vieux @tianon

This feature seems useful and provides limited remediation for the security concerns noted in #6134 (devices granted may be replaced, major/minor numbers reused, etc...)

@crosbymichael
Copy link
Copy Markdown
Contributor

@calfonso @ewindisch @imain

I talked with the other maintainers about this and it is something that we want to get in. We are just worried about the UI for the feature. If we go the route of dev-add dev-rm` then when we want to introduce more ways to dynamically modify a container the docker commands and API will explode.

We can take what you have now with the changes to libcontainer and lxc and get these merged in but we would like it if you could propose some alternatives to the UI ( cli and API ) so that the command set does not explode when we start adding more ways to modify the container.

Does this sound ok with you?

@calfonso
Copy link
Copy Markdown
Contributor Author

@crosbymichael For the UI, what do you think about introducing something like the following?

docker update CONTAINER --action ACTION --args ACTION_ARGS and have the API have something similar? For device adding/removing it would look like: docker update 54b8808d05cf --action device-add --args /dev/loop0

Re merging libcontainer the lxc patch, that requires the C go patch for nsenter Mknod ( docker-archive/libcontainer#6 ) that you had requested be reimplemented in a more generic way as well, so we're working through that.

@vbatts
Copy link
Copy Markdown
Contributor

vbatts commented Jul 23, 2014

@crosbymichael after chatting with @calfonso this morning, perhaps a general foundation command like docker container CONTANIER [CONTAINER...] would be ideal here. By default it will show some info set on the provided CONTAINTER(s). The modifier flags would be something like

docker container --dev 'add=/dev/loop0' sharp_torvalds
docker container --dev 'rm=/dev/loop0' evil_stallman

And this way, the API and UI can stay generic for a number of other features.

Look okay?

@thaJeztah
Copy link
Copy Markdown
Member

@vbatts I like that, as it prevents the UI from 'exploding' and keeps the road open for additional modifications to existing containers (e.g. Dynamically add/remove links). Not too fond on the string notation of the actual action ('add=...'), they feel a bit "clunky" but don't see other options ATM.

@vbatts
Copy link
Copy Markdown
Contributor

vbatts commented Jul 23, 2014

@thaJeztah clunky, maybe, but same as existing flags like --filter and --storage-opts and --lxc-conf

@thaJeztah
Copy link
Copy Markdown
Member

@vbatts you're right. So, better clunky, but consistent than slick and inconsistent.

You have my vote FWIW :)

@crosbymichael
Copy link
Copy Markdown
Contributor

update or modify sounds good to me.

For an API request I was thinking about something like:

POST /containers/<name>/{update|modify}
{
    "type": "device",
    "values": {
        "add": "/dev/loop0"
    }
}

values just being a map[string]string in Go.

What do you think?

@calfonso
Copy link
Copy Markdown
Contributor Author

I like modify better than update. I like the API. Any other thoughts from anyone before we get started?

@thaJeztah
Copy link
Copy Markdown
Member

modify sounds fine to me. alter could be an option, but not sure if that is any better.

However, if renaming containers will be implemented in the future, I think the endpoint of the API should be;

POST /containers/(id)/modify

i.e. Use the container id, not its name. This is a bit less convenient, but consistent with other parts of the API as well.

Finally, shouldn't the API call use PUT instead of POST here? After all, we're updating, not creating.

@calfonso
Copy link
Copy Markdown
Contributor Author

@thaJeztah Yes, I'll use PUT

@thaJeztah
Copy link
Copy Markdown
Member

Unless @crosbymichael disagrees, because IANTM, just a friendly visitor 😄

@crosbymichael
Copy link
Copy Markdown
Contributor

@thaJeztah id and name can be used interchangeably so the endpoint will accept both.

PUT sounds +1

@calfonso maybe we need to change the map from map[string]string to map[string][]string so that things like below are supported.

{
    "type": "device",
    "values": {
        "add": ["/dev/loop0", "/dev/loop1"]
    }
}

ping @vieux

@thaJeztah
Copy link
Copy Markdown
Member

Maybe even one step further; to allow batch-updating multiple properties in future;

[{
    "type": "device",
    "values": {
        "add": ["/dev/loop0", "/dev/loop1"]
    }
},
{
    "type": "volume",
    "values": {
        "remove": ["/var/www"]
    }
}
]

@timthelion
Copy link
Copy Markdown
Contributor

I would personally like these features, but some of the security discussion here concerns me. dev-rm is not a good solution for the ephemeral devices problem. If you were to try to "watch" /proc or dmesg for devices getting removed and try to dev-rm them before the device number got reused, you would end up with an insecure race condition. I have yet to find any solution to this security problem. Should I ask here if anyone knows of a solution? If dev-rm is to be added, there should be strong warnings in the docs not to try to use it to deal with the ephemeral devices+device number re-use security flaw.

@ewindisch
Copy link
Copy Markdown
Contributor

@timthelion - there would be a timing attack possible, but that's still better than being outright unable to remove the device nodes.

@crosbymichael
Copy link
Copy Markdown
Contributor

Closing this has there is a better implementation opened by the same authors.

@drngsl
Copy link
Copy Markdown

drngsl commented Nov 27, 2015

Hi, @calfonso , May I ask you a question, How can I install docker with source code from https://github.com/calfonso/docker/tree/docker_modify which has the ability to add/remove device to running container?
I aslo seek the code about nova-docker that achieve the above operation (https://github.com/calfonso/nova-docker/tree/device_add_remove).
Can you help me?
Thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.