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 <estesp@linux.vnet.ibm.com> (github: estesp)
This commit is contained in:
Phil Estes 2015-02-16 00:00:51 -05:00
parent ee95aa1b81
commit 16aa64dc82
3 changed files with 36 additions and 16 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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")
}