From 16aa64dc82b6434ec78878fa35eb96e4983b46f8 Mon Sep 17 00:00:00 2001 From: Phil Estes Date: Mon, 16 Feb 2015 00:00:51 -0500 Subject: [PATCH] Add linked container's name and hostname as aliases to `/etc/hosts` Currently when containers are linked the alias name (e.g. from `--link name:alias`) is added to the parent container's `/etc/hosts` with a reference to the IP of the linked container. Some software requires using the official hostname or node name in operations that need to match on those values, and it is therefore helpful if the parent container can refer to the child/link using those same values and still access the same IP. Docker-DCO-1.1-Signed-off-by: Phil Estes (github: estesp) --- daemon/container.go | 8 ++++++- docs/sources/userguide/dockerlinks.md | 15 +++++++----- integration-cli/docker_cli_links_test.go | 29 ++++++++++++++++-------- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/daemon/container.go b/daemon/container.go index ac565aef4c..81deb8624f 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -457,7 +457,13 @@ func (container *Container) buildHostsFiles(IP string) error { for linkAlias, child := range children { _, alias := path.Split(linkAlias) - extraContent = append(extraContent, etchosts.Record{Hosts: alias, IP: child.NetworkSettings.IPAddress}) + // allow access to the linked container via the alias, real name, and container hostname + aliasList := alias + " " + child.Config.Hostname + // only add the name if alias isn't equal to the name + if alias != child.Name[1:] { + aliasList = aliasList + " " + child.Name[1:] + } + extraContent = append(extraContent, etchosts.Record{Hosts: aliasList, IP: child.NetworkSettings.IPAddress}) } for _, extraHost := range container.hostConfig.ExtraHosts { diff --git a/docs/sources/userguide/dockerlinks.md b/docs/sources/userguide/dockerlinks.md index f35f61ecfc..045a37fa59 100644 --- a/docs/sources/userguide/dockerlinks.md +++ b/docs/sources/userguide/dockerlinks.md @@ -252,20 +252,23 @@ In addition to the environment variables, Docker adds a host entry for the source container to the `/etc/hosts` file. Here's an entry for the `web` container: - $ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash + $ sudo docker run -t -i --rm --link db:webdb training/webapp /bin/bash root@aed84ee21bde:/opt/webapp# cat /etc/hosts 172.17.0.7 aed84ee21bde . . . - 172.17.0.5 db + 172.17.0.5 webdb 6e5cdeb2d300 db You can see two relevant host entries. The first is an entry for the `web` container that uses the Container ID as a host name. The second entry uses the -link alias to reference the IP address of the `db` container. You can ping -that host now via this host name. +link alias to reference the IP address of the `db` container. In addition to +the alias you provide, the linked container's name--if unique from the alias +provided to the `--link` parameter--and the linked container's hostname will +also be added in `/etc/hosts` for the linked container's IP address. You can ping +that host now via any of these entries: root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping - root@aed84ee21bde:/opt/webapp# ping db - PING db (172.17.0.5): 48 data bytes + root@aed84ee21bde:/opt/webapp# ping webdb + PING webdb (172.17.0.5): 48 data bytes 56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms 56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms 56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms diff --git a/integration-cli/docker_cli_links_test.go b/integration-cli/docker_cli_links_test.go index 542adc379b..3f965342b3 100644 --- a/integration-cli/docker_cli_links_test.go +++ b/integration-cli/docker_cli_links_test.go @@ -65,16 +65,27 @@ func TestLinksPingUnlinkedContainers(t *testing.T) { } func TestLinksPingLinkedContainers(t *testing.T) { - var out string - out, _, _ = dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10") - idA := stripTrailingCharacters(out) - out, _, _ = dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10") - idB := stripTrailingCharacters(out) - dockerCmd(t, "run", "--rm", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1") - dockerCmd(t, "kill", idA) - dockerCmd(t, "kill", idB) - deleteAllContainers() + runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "container1", "--hostname", "fred", "busybox", "top") + if _, err := runCommand(runCmd); err != nil { + t.Fatal(err) + } + runCmd = exec.Command(dockerBinary, "run", "-d", "--name", "container2", "--hostname", "wilma", "busybox", "top") + if _, err := runCommand(runCmd); err != nil { + t.Fatal(err) + } + runArgs := []string{"run", "--rm", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sh", "-c"} + pingCmd := "ping -c 1 %s -W 1 && ping -c 1 %s -W 1" + + // test ping by alias, ping by name, and ping by hostname + // 1. Ping by alias + dockerCmd(t, append(runArgs, fmt.Sprintf(pingCmd, "alias1", "alias2"))...) + // 2. Ping by container name + dockerCmd(t, append(runArgs, fmt.Sprintf(pingCmd, "container1", "container2"))...) + // 3. Ping by hostname + dockerCmd(t, append(runArgs, fmt.Sprintf(pingCmd, "fred", "wilma"))...) + + deleteAllContainers() logDone("links - ping linked container") }