service: add 'docker service exec' command - #7283
Open
dlarochette wants to merge 1 commit into
Open
Conversation
Add a 'docker service exec' subcommand that executes a command in a running task of a service, on whichever node the task is scheduled, addressing a long-standing request (moby/moby#27552). The service is resolved to its first running task (or the task given with --task-id). When the task runs on the node the client is talking to, this is a plain container exec. When it runs on another node, the client connects to that node's engine through the existing SSH connection helper (the DOCKER_HOST=ssh:// mechanism) and reuses the regular exec plumbing, so interactive mode, TTY allocation, and exit-code propagation behave exactly like a local 'docker exec'. The node is reached at the address advertised in its status, falling back to the node hostname; --ssh-user and --ssh-option allow adjusting the SSH connection (e.g. jump hosts). Signed-off-by: David LAROCHETTE <david.larochette@movesol.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What I did
Added a
docker service execsubcommand that executes a command in a running task of a service, on whichever node the task is currently scheduled — without having to manually resolve the node and container and SSH into it.This addresses the long-standing request in moby/moby#27552 (open since 2016), at the CLI level: since the engine API has no cross-node exec and swarmkit has no exec RPC, the CLI reuses its own existing SSH connection helper (the
DOCKER_HOST=ssh://mechanism,docker system dial-stdioon the remote side) to reach the engine of the node running the task.How I did it
desired-state=running, and pick the first running task — or the one given with--task-id.Info().Swarm.NodeID), perform a plain local exec.ssh://host from its advertised address (Status.Addr, falling back to the hostname), open a second API client throughconnhelper.GetConnectionHelperWithSSHOpts, and run the exec through it.container.RunExecplumbing is reused as-is, so-i,-t, detach keys, console resize, and exit-code propagation behave exactly like a localdocker exec.--ssh-userand--ssh-optionallow adjusting the SSH connection (jump hosts, identity files), with the same semantics asDOCKER_HOST=ssh://connections.Requirements for the remote path (documented in the reference page): SSH access to the node and the
dockerCLI in the remote user'sPATHwith access to the local engine socket — the same requirements asDOCKER_HOST=ssh://.How to verify it
Unit tests cover task selection (default, explicit, not-running, missing) and node address resolution:
Verified manually on a 2-node swarm, local and remote paths:
A note on the approach
I'm aware a fully native cross-node exec would live in swarmkit (a bidirectional sibling of the LogBroker) and the engine API; that's a much larger, 3-repo effort. This PR takes the pragmatic route with the transport the CLI already owns and documents its requirements explicitly. Happy to adjust the UX (flag names, error wording) or discuss whether this belongs behind an experimental gate.
Description for the changelog