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

Support for container aliases when joining a network #737

Closed
dnephin opened this issue Nov 5, 2015 · 48 comments
Closed

Support for container aliases when joining a network #737

dnephin opened this issue Nov 5, 2015 · 48 comments
Milestone

Comments

@dnephin
Copy link
Member

dnephin commented Nov 5, 2015

We'd like a container to be able to join a network under different names, not just the container name.

Related: docker/compose#2312

@cpuguy83
Copy link
Member

cpuguy83 commented Nov 5, 2015

And multiple names
Nice thing about links is this was localized per container... I suppose with "properly" segmented networks this localization shouldn't be a huge problem to be at the network level.

@kdemarest
Copy link

+1 - the container should be able to identify itself with more than just its name for purposes of network topology.

@alethenorio
Copy link

With links it was really useful to be able to set the alias to something like mynet.example.com when trying to replicate non-docker environments for local test purposes. Supplying an alias on network connect (or some other way) would be really useful.

@secat
Copy link

secat commented Nov 14, 2015

+1 This will be very useful when using docker containers on a mesos cluster since the container name is assigned by the mesos agent (slave).

@delfuego
Copy link

This is pretty much a mandatory need when using Docker Compose, given that the preferred use of Compose is to allow it to set container names when they are spun up. So consider this a hearty +1.

@mavenugo
Copy link
Contributor

thanks everyone for the comments.

@dnephin @cpuguy83 @delfuego when we use links, the aliasing of the container name is specified at the time of linking and not during the time of container (that is being linked and aliased here) create. This provides a nice functionality of the child container calling the parent anything it wants as defined in the application that is running inside container. But by providing an alias for a container when it is connected to network, we are essentially providing the alias at the container connect time. That means the child container that is linked (via the network & SD) to the parent cannot be made 1-1. User would have to start changing the expectations on the 1-1 name alias between a pair of containers. Instead it will be a 1-N relationship within the network. i.e., a container can be aliased, but that alias will be available for all other containers in that network. Is that acceptable ?

Also, how dynamic and generic we see this alias feature to be ? Should this be a generic engine feature on a container to have multiple names (or) specific to networking for the purpose of linking containers using multiple names ? How dynamic should we make this and how would the UX look like ? Any ideas ?

@cpuguy83
Copy link
Member

@mavenugo Yes, I agree it would be difficult to have an alias apply like it does with links today.
What I'm thinking (litteraly spent like 3 minutes thinking about it, so not well thought out), is something like docker network connect --as db backend mysqldb and potentially allowing multiple connects to a network that way but only ever creating the actual interface on the first connect... This may be overloading connect.

@dnephin
Copy link
Member Author

dnephin commented Nov 18, 2015

The most important thing for compose is that a container is accessible by names docker-compose defines. That way the default discovery naming is backwards compatible with the default link names (servicename, and servicename_num).

An alias being available to every container doesn't seem like a problem for most uses. There may be some configurations that need to change, but as long as we can provide arbitrary aliases for a container, it should be workable. We create a network for each compose project, so the N is just the services defined within a single Compose file.

how dynamic and generic we see this alias feature to be ?

I don't think we want a container to have multiple names. I think it's specific to networking (links support multiple aliases with a single container name).

How dynamic should we make this and how would the UX look like ?

I think setting the aliases at connect time sounds appropriate (I agree with the example @cpuguy83 provided).

From the cli: docker network connect --as db --as alias2 --as alias3 backend mysqldb

From compose we'd add a second for aliases to the compose file, so that users could set a custom name. @aanand had a PR with the docs for this a while back, but I can't find it now. It might have been rebased, but maybe he has a copy of the old docs.

@cpuguy83
Copy link
Member

@dnephin You could parse "link" into a "network connect --as"

@dnephin
Copy link
Member Author

dnephin commented Nov 18, 2015

I think we'd rather keep them separate, since they function very differently, but technically we could do that, true.

@mavenugo
Copy link
Contributor

Thanks. If the alias as we defined here can be used with compatibility with links am all for it.

@delfuego
Copy link

@dnephin If this gets built out as an option for the docker network command (and an entry in the docker-compose.yml file), then there'd also need to be a way to specify the alias from docker run — if a container only needs a connection to one network but needs an alias, then it wouldn't make sense to force using docker run to build and start the container, and then a separate docker network connect command to be able to connect it to the right network with an alias. So, perhaps:

docker run --net user-net:alias ...

@mavenugo
Copy link
Contributor

@delfuego we dont need to modify the docker run. With the above proposed change to the docker network connect, this command can be called after the container is started using the docker run to setup the alias. Yes, compose might have to invoke 2 commands. But it is kinda equivalent to links in the sense that the alias of a container is specified when it was linked and not during the container create/start time.

@secat
Copy link

secat commented Nov 19, 2015

I do not know exactly how the automatic service discovery is done in details with the multi-host overlay network driver, but IMHO: in a microservices architecture running under a mesos cluster by example, the container name alias should be available on the network at the container start time and therefore be available to all other containers on the same network without doing other manual commands.

Perhaps we could have an api like this one:

docker run --net user-net --alias app-alias [...]

@secat
Copy link

secat commented Nov 20, 2015

Also, I do not know if this issue is the right place to talk about this, but IMHO the alias feature won't be very useful if multiple SRV records for the same container name/alias is not supported.

See skydns features for further details.

I ran a test on 3 boot2docker machine following the docker network demo and I tried to have two separate machine running a container with the same name on the same network. It failed and I received the following error output:

Error response from daemon: Cannot start container e4ac2e984cd2ab5f43ef8dadba8fa6599dac3ec651d8e45c17d3f609d7373833: container already connected to network myapp

@cpuguy83
Copy link
Member

@secat I think this comes down to a proper discussion around discovery (beyond the current /etc/hosts functionality), and we should keep that in mind when implementing aliases.

Note that when I say aliases, I'm really referring to the concept of giving a container a 2nd name (which is also what --link does) rather than alias in terms of /etc/hosts.

@adewes
Copy link

adewes commented Nov 20, 2015

+1 I think this is an absolutely necessary feature for many use cases (I posted a question about my use case on SO: http://stackoverflow.com/questions/33835469/docker-networking-auto-discovering-host-names-in-a-bridge-network).

I think for most cases it would suffice to be able to customize the host name that is put in the /etc/hosts file. Having multiple aliases for a given host could be relevant as well, e.g. if you have pre-built images that expect a given host name for another container that they connect to.

Is there a good reason that the --hostname parameter does only change the host name of the container locally (i.e. just for the container itself) insteady of globally (i.e. for all other containers)? Personally I was very surprised and confused by this behavior when using --hostname.

@hjanuschka
Copy link

an alias feature is absolutly necessary!

would be nice to be able to set aliases like we could with links - any progress on this?

@woshihaoren
Copy link

+1 . an alias feature is absolutly necessary!

@fermayo
Copy link
Member

fermayo commented Nov 27, 2015

So, as @mavenugo pointed out, just giving aliases to containers won't be able to replace "link" functionality completely. I think links have already a very good UX that developers are already familiar to that we can just try to support in other than bridge networks. "Links" give aliases to "parent" containers to their "children" containers only, not globally. So for two different containers connected to the same network, the alias could resolve to different containers:

docker run --name db1 mysql
docker run --name db2 mysql
docker run --link db1:db app1
docker run --link db2:db app2

In this case you can't just give to both db1 and db2 the alias db.

I would suggest using DNS search domains for the embedded docker DNS server to detect from which container the lookup is coming and resolve appropriately.

In terms of UX, can't we just use --link [network:]container[:alias] where network defaults to bridge (to keep backwards compatibility)?

I understand some type of alias functionality as being discussed here could act as a workaround in the short term, and compose could use it to "implement links", but can't we just try to implement that functionality natively on the server side?

@cpuguy83
Copy link
Member

@fermayo I would argue that we should not support the example you gave. These should be separate networks.

@dnephin
Copy link
Member Author

dnephin commented Nov 27, 2015

I think the 1-1 aliasing is a separately discussion. This issue is just to support "global aliases", which is the minimum required to support non-experimental networking in compose.

I think the discussion about 1-1 aliasing is a much larger, and more controversial topic, so I'd like to keep it separate from "global aliases".

@dave-tucker
Copy link
Contributor

While we're here, one important point of clarification to make:

  • --name was supposed to be a friendly name that can be used instead of the container ID on the docker CLI. It has to be unique
  • --hostname the containers network name e.g /etc/hostname. It should be unique within a domain but this is not enforced.

When using --link container, we actually wrote the --name of a container inside the others /etc/hosts which really blurred the line of what --name is supposed to do. We've continued to do this in Docker 1.9 with service discovery. If you have containers in two different applications that need to be called web, you are out of luck 🐼

My request is, if --name and --hostname are present, use only the hostname inside the container.
As --name needs to be unique, best practice would be to avoid generic names and instead to prefix them with a project or application name... by coincidence we have a tool called Docker Compose that does that for you :trollface:

For aliases, we could use multiple --hostname entries instead of adding an --alias flag. The caveat here would be that the "first" entry would be present in /etc/hostname where the others will effectively be A records or the equivalent in /etc/hosts

Example

Consider the following docker-compose.yml with a project name of test:

web:
    image: nginx

On docker-compose --x-networking up:

A new network called test is created

Then, a new container is created using the API equivalent of:

docker run --name test_web_1 --hostname web_1 --hostname web nginx

We can see that the containers hostname is web_1

root@web_1$ cat /etc/hostname
web_1

And the containers /etc/hosts would look something like this:

root@web_1$ cat /etc/hosts
127.0.0.1   localhost
172.17.0.3 web_1
172.17.0.3 web

@woshihaoren
Copy link

@dave-tucker When other containers join test network, Can they get last hostname in /etc/hosts ?

Example:
web:
    image: nginx
mysql:
    image: mysql

docker-compose -p test --x-networking up

root@web_1$ cat /etc/hosts
127.0.0.1   localhost
172.17.0.3 web_1
172.17.0.3 web
172.17.0.4 mysql

@dave-tucker
Copy link
Contributor

@woshihaoren yep, we should probably move that discussion over to compose (e.g behaviour of scale with stateful/stateless services). From a "plumbing' standpoint, I think my proposal should work.

@woshihaoren
Copy link

@dave-tucker Yeah, I think your proposal should work. See what they think

@mavenugo mavenugo added this to the 0.6 milestone Nov 29, 2015
@fermayo
Copy link
Member

fermayo commented Nov 29, 2015

@cpuguy83 @dnephin In Tutum we do implement the example I gave above (cross host links) and I was hoping something similar could be implemented natively. We can discuss it on a separate thread.

@dave-tucker For multiple A records for the same hostname you would need a proper DNS server (#767). /etc/hosts does not support round robin A records (it will always resolve to the first match found on the file).

@mavenugo
Copy link
Contributor

Thanks everyone for the inputs. I added the milestone (as 0.6) which is the next major release for libnetwork (via Docker 1.10). This is absolutely required in order to have a clean integration with Compose.

As @fermayo pointed out, though this proposal is independent of the implementation (/etc/hosts vs DNS), #767 does impact the finer details of the discussion. For example, supporting multiple A records is important in order to provide the round robin functionality for multiple aliases mapping to the same name, This is quite useful for number of scenarios including compose. We will add this as a requirement in #767.

I think @dave-tucker has a valid point regarding name vs alias vs hostname discussion. But, --name is quite popular for not just container identity but also as a SD mechanism (as used in links) and it will not be easy to move away from that. Using container --hostname as an alias (in docker run) is an interesting idea. But having multiple --hostname, we cannot guarantee which hostname is the first among many to be used in /etc/hostname. Also, we would need a way to dynamically alias a container via network connect to provide the dynamic alias functionality as in link (though it is not 1:1 alias). Hence overloading existing mechanisms such as name or hostname as an alias feature will result in various backward compatibility issues. Hence, Instead of treating it is as a vs relationship between these options, maybe we should consider it as an and relationship where we can pick up name and hostname and alias and use all of them as a valid identifier for SD.

@fermayo supporting 1:1 alias (similar to links) is going to complicate the design and hence am trying to see if this is a mandatory requirement ? With the concept of network, we are providing that isolated domain which the application running inside the network (example : the compose file) make use of freely. providing further level of restriction comes under policy boundary where it should be applied not just for the concept of SD, but also for container <-> container reachability. FYI, links provide just name resolution isolation, but doesn't prevent containers to talk to each other via ip-addresses. Do you think you could use live WITHOUT the 1:1 alias feature and WITH multiple A-records (via #767) for round-robin load-balancing in order to make use of SD effectively ?

@dave-tucker @dnephin for the UX, I think @cpuguy83 suggestion of docker network connect --as db --as alias2 --as alias3 backend mysqldb seems the simplest which also provides the dynamic alias capability without impacting any backward compatibility. We could also include the existing --hostname to the mix if that is seen as no-brainer. WDYT ?

@fermayo
Copy link
Member

fermayo commented Nov 30, 2015

  1. I understand links don't implement network level isolation, but they are still useful from a service dependency POV.
  2. I don't think multiple networks should be used to just namespace service discovery - you can just use DNS domains for that. Having said that, we could still use this way of namespacing SD if we can give aliases like "service.stack" and set the appropriate DNS search domain from our end.
  3. The only thing that will really break is giving the same alias to different services within the same "stack" (compose file). Can be managed.
  4. In terms of UX, is there a reason why the aliases cannot be defined at create/start time? I read your comment above @mavenugo but I'm still not sure why would the user need to execute a separate command.

@mavenugo
Copy link
Contributor

I don't think multiple networks should be used to just namespace service discovery - you can just use DNS domains for that. Having said that, we could still use this way of namespacing SD if we can give aliases like "service.stack" and set the appropriate DNS search domain from our end.

@mrjana @sanimej can you please share your views on this ? This is closely related to #767

The only thing that will really break is giving the same alias to different services within the same "stack" (compose file). Can be managed.

@dnephin @dave-tucker Based on your previous comments, I guess 1:1 alias is not mandatory for compose. Is that correct ?

In terms of UX, is there a reason why the aliases cannot be defined at create/start time? I read your comment above @mavenugo but I'm still not sure why would the user need to execute a separate command.

No reason. I was just thinking in terms of links where-in, the alias were specified dynamically when the child containers were brought up. Having said that, we can introduce --alias on the container create/start UX.

@cpuguy83
Copy link
Member

@mavenugo Couldn't we have --link foo:bar set this up?
So, this would create a network for the new container and foo, where foo is joined to the network as bar?

@cpuguy83
Copy link
Member

I guess there are some potential gotchas here tracking removed/re-created containers.

@aanand
Copy link

aanand commented Nov 30, 2015

I think @dave-tucker has a valid point regarding name vs alias vs hostname discussion. But, --name is quite popular for not just container identity but also as a SD mechanism (as used in links) and it will not be easy to move away from that.

I had no idea we populated /etc/hosts with container names (and that you can pass a --link CONTAINER_NAME to docker run without an alias). That's pretty bad and leaky. Still, since networking already involves a backwards-incompatible change to either people's application code or Compose files (or docker run commands), is this not an opportune moment to drop that behaviour?

Regarding @dave-tucker's proposal to use hostname: I like its simplicity and consistency (the hostname of the container inside the container is also the hostname of the container outside the container!) but there's software out there that doesn't even play well with multiple containers having the same internal hostname, as @vieux discovered in docker/compose#2327 - so there'd need to be a way around that.

Hence, Instead of treating it is as a vs relationship between these options, maybe we should consider it as an and relationship where we can pick up name and hostname and alias and use all of them as a valid identifier for SD.

Using multiple properties with a defined order of priority could work, but for the reasons of leakiness described by @dave-tucker, I really feel name shouldn't be on that list at all, unless we feel that ignoring it would break a lot of people's setups.

@mavenugo
Copy link
Contributor

@aanand

I had no idea we populated /etc/hosts with container names (and that you can pass a --link CONTAINER_NAME to docker run without an alias). That's pretty bad and leaky.

This was always the case with --link and am not quite sure why this is bad necessarily. Could you please explain what you mean by leaky ?

Still, since networking already involves a backwards-incompatible change to either people's application code or Compose files (or docker run commands), is this not an opportune moment to drop that behaviour?

--link is a very useful functionality, but had a few issues due to the nature of the unidirectional SD. And there is no backwards-incompatible change that i know of. Can you please explain which case are you referring to here ?
FYI, --link works exactly the same way in the default bridge network in order to maintain backward compatibility. The SD concept that we are discussing here is implemented only on user-defined networks that was introduced in 1.9.0. So, AFAIK there isnt any backward incompatible changes that impacts the users.

Though @dave-tucker's point is valid regarding using name just as an identifier, I think the users expect it for SD as well given the history with link.

The alias functionality being discussed here is very important for many cases (including Compose). Lets make sure we design it to address the Compose requirement and also other cases as raised by @fermayo.

@dave-tucker
Copy link
Contributor

@mavenugo

But, --name is quite popular for not just container identity but also as a SD mechanism (as used in links) and it will not be easy to move away from that.

I think we are missing some data to back that up - will try and find some.
FWIW, the subsection of the community you have described would be those using --link name directly instead of --link name:alias or using Docker Compose.
FWIW, when I was getting started with Docker, a lot of the tutorials re:links always used the --link name:alias syntax, even if the alias was the same as the container name e.g --link mysql:mysql

@thaJeztah
Copy link
Member

From my personal experience, the alias is an important feature. In my previous job we spun up many fig / docker-compose projects on the same host. Using the service name within the project (or instance of a project), allowed for easily reuse basic configuration, and simple service "discovery" within a project (I.e., the database could be connected to using the db hostname, mailserver via mail). Making the discovery based on container name makes that impossible (without using links), and makes it a lot more difficult to build reusable components (services/configuration).

@hjanuschka
Copy link

@thaJeztah totally aggree with you!
we absolutly need the alias feature to work similiar to links! - its pretty hard to argue for using docker in production when the -x-networking degrades composer to basically a bash script!

looking forward to the milestone, or any alternative solution with a good "how to port your linked container s to the new-feature" guides

@jippi
Copy link

jippi commented Dec 16, 2015

👍

@thaJeztah
Copy link
Member

see moby/moby#18699 for the proposal in docker/docker

@mwootendev
Copy link

+1 I have an exact need for this right now.

@nordluf
Copy link

nordluf commented Feb 22, 2016

I made Docker image to have power of multi A records for one net-alias. https://hub.docker.com/r/nordluf/swarm-discovery/ It works, at least in my environment, with many identical microservices which I want to connect using one dns name . May be it can be useful for others.

@sheerun
Copy link

sheerun commented Mar 8, 2016

Is it closed because of moby/moby#18699? What's left?

@mavenugo
Copy link
Contributor

mavenugo commented Mar 8, 2016

Yes. this issue must be closed. Thanks @sheerun for bringing it up.

@eblanshey
Copy link

For anyone coming in late, see the compose file reference for "aliases":

services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
         - alias3
      other-network:
        aliases:
         - alias2

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

No branches or pull requests