Skip to content

Proposal: Container groups #8637

@aanand

Description

@aanand

NOTE: this is out of date - please see #9694

This is a proposal to add the concept of a group to the Docker engine, which is a logical group of potentially interdependent containers, performing related work, potentially on multiple hosts. It replaces issue #7576.

The primary motivations are:

  1. Provide a platform on which to build a Fig-like stack composition feature without resorting to hacks such as Fig's container naming scheme (<project name>_<service name>_<numeric suffix>), which is brittle and slow.
  2. Scope container names so that multiple people can work on multiple apps without treading on one another’s toes
  3. Provide a way to create/update multiple, associated containers in a single call - in a clustered future, this enables the cluster to make scheduling decisions about where to place those containers based on the fact that they’re a logical group.

Update: the following description and screencast are a little out-of-date - see the ensuing discussion. Furthermore, here's a preview build of the current state of groups and composition: https://gist.github.com/aanand/9e7ac7185ffd64c1a91a

Some progress has been made on implementing this proposal in the figgy branch of @crosbymichael’s fork. I’ve recorded a short screencast to demonstrate how the current implementation fulfils feature 1 above, and could be trivially extended to fulfil feature 2:

Screenshot

Basic functionality

A group has a unique name which occupies the same namespace as container names.

A container can optionally belong to a single group, in which case its name begins with <group name>/. For example, a group named myapp may have the containers myapp/web and myapp/db.

API/CLI additions

Existing API endpoints and CLI commands for starting, stopping, killing and removing containers work exactly the same on containers inside groups as on those outside.

There are new API endpoints for creating, listing and removing groups, and a new CLI command, docker groups, with subcommands for the same:

$ docker groups list
NAME     CONTAINERS

$ docker groups create foo

$ docker groups list
NAME     CONTAINERS
foo      0

$ docker groups rm foo
foo

The API endpoint for creating a container has a new parameter, groupName, which causes the container to be created within the named group (which must already exist). The docker run command has a new argument, --group NAME:

$ docker run --group=foo --name=sleep ubuntu sleep infinity

$ docker groups list
NAME     CONTAINERS
foo      1

$ docker ps
NAME        COMMAND          ...
foo/sleep   sleep infinity   ...

If a name isn’t supplied when creating a group, one is generated in a similar manner to container names (<adjective>_<surname>).

There are new API endpoints and CLI commands for starting, stopping and killing all containers in a group.

$ docker groups stop foo
foo/sleep

$ docker groups start foo
foo/sleep

$ docker groups kill foo
foo/sleep

Communication within groups and between hosts [OUT OF DATE - see discussion]

Containers within a group share a network namespace and /etc/hosts file. The hosts file has an entry for each container with its name (sans group prefix) as the hostname:

10.0.0.1    web
10.0.0.2    redis

Inter-container communication using these hostnames is preferred over explicit links.

There is an API endpoint for creating/updating a group from a blob of JSON which contains both a name for the group and the names and configuration for zero or more containers within the group. If a group with the specified name already exists, containers with matching names within it are killed and removed.

When creating/updating a group with this endpoint, instead of supplying configuration for a particular name, an IP address can be supplied. For example:

{
  "Name": "foo",
  "Containers": [
    {
      "Name": "web",
      "Image": "my-web-image",
      <...more configuration...>
    },
    {
      "Name": "redis",
      "IP": "123.456.78.9"
    }
  ]
}

This results in no redis container being created, and the given IP address being written into the shared hosts file:

10.0.0.1        web
123.456.78.9    redis

Orchestration primitive [OUT OF DATE - see discussion]

A hypothetical clustering/orchestration layer could both use and expose the Docker groups API, but make use of replacement IPs to make the cluster appear like a single Docker host from the outside. Here's a supremely trivial example:

When a user posts JSON containing web and db entries to the cluster:

  1. Create a group on two separate hosts.
  2. On one host, create a group with the supplied container config for web, but the IP address of the second host for redis.
  3. On the second host, create a group with the supplied container config for redis, but the IP address of the first host for web.

Both containers are now running on separate hosts, but are still communicating as if they were in a single group on a single host. When the cluster is queried, it unifies the contents of each host behind the scenes to present a single collection of containers/groups, just as if it were a single host.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/featureFunctionality or other elements that the project doesn't currently have. Features are new and shiny

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions