Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Always try to enable IPv6 on a container's loopback interface, removing the dependency on whether it currently has any IPv6-enabled endpoints. If IPv6 can be enabled, the kernel will assign address '::1' to the loopback interface. If IPv6 cannot be enabled, perhaps because it's not enabled in the kernel, or because the container was created it disabled using option '--sysctl net.ipv6.conf.all.disable_ipv6=1' - the loopback interface will not get address '::1'. After the container task has been created, before it is started, use the presence of the '::1' address to determine whether the container can support IPv6. Then, generate the its '/etc/hosts' file with or without IPv6 entries accordingly. Signed-off-by: Rob Murray <rob.murray@docker.com>
- Loading branch information
Showing
11 changed files
with
287 additions
and
50 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package networking | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/docker/docker/testutil" | ||
|
||
containertypes "github.com/docker/docker/api/types/container" | ||
"github.com/docker/docker/integration/internal/container" | ||
"github.com/docker/docker/testutil/daemon" | ||
"gotest.tools/v3/assert" | ||
is "gotest.tools/v3/assert/cmp" | ||
"gotest.tools/v3/skip" | ||
) | ||
|
||
// Check that the '/etc/hosts' file in a container is created according to | ||
// whether the container supports IPv6. | ||
// Regression test for https://github.com/moby/moby/issues/35954 | ||
func TestEtcHostsIpv6(t *testing.T) { | ||
skip.If(t, testEnv.DaemonInfo.OSType == "windows") | ||
|
||
ctx := setupTest(t) | ||
d := daemon.New(t) | ||
d.StartWithBusybox(ctx, t, | ||
"--ipv6", | ||
"--ip6tables", | ||
"--experimental", | ||
"--fixed-cidr-v6=fdc8:ffe2:d8d7:1234::/64") | ||
defer d.Stop(t) | ||
|
||
c := d.NewClientT(t) | ||
defer c.Close() | ||
|
||
testcases := []struct { | ||
name string | ||
sysctls map[string]string | ||
expIPv6Enabled bool | ||
expEtcHosts string | ||
}{ | ||
{ | ||
// Create a container with no overrides, on the IPv6-enabled default bridge. | ||
// Expect the container to have a working '::1' address, on the assumption | ||
// the test host's kernel supports IPv6 - and for its '/etc/hosts' file to | ||
// include IPv6 addresses. | ||
name: "IPv6 enabled", | ||
expIPv6Enabled: true, | ||
expEtcHosts: `127.0.0.1 localhost | ||
::1 localhost ip6-localhost ip6-loopback | ||
fe00::0 ip6-localnet | ||
ff00::0 ip6-mcastprefix | ||
ff02::1 ip6-allnodes | ||
ff02::2 ip6-allrouters | ||
`, | ||
}, | ||
{ | ||
// Create a container in the same network, with IPv6 disabled. Expect '::1' | ||
// not to be pingable, and no IPv6 addresses in its '/etc/hosts'. | ||
name: "IPv6 disabled", | ||
sysctls: map[string]string{"net.ipv6.conf.all.disable_ipv6": "1"}, | ||
expIPv6Enabled: false, | ||
expEtcHosts: "127.0.0.1\tlocalhost\n", | ||
}, | ||
} | ||
|
||
for _, tc := range testcases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
ctx := testutil.StartSpan(ctx, t) | ||
ctrId := container.Run(ctx, t, c, | ||
container.WithName("etchosts_"+sanitizeCtrName(t.Name())), | ||
container.WithImage("busybox:latest"), | ||
container.WithCmd("top"), | ||
container.WithSysctls(tc.sysctls), | ||
) | ||
defer func() { | ||
c.ContainerRemove(ctx, ctrId, containertypes.RemoveOptions{Force: true}) | ||
}() | ||
|
||
runCmd := func(ctrId string, cmd []string, expExitCode int) string { | ||
t.Helper() | ||
execCtx, cancel := context.WithTimeout(ctx, 5*time.Second) | ||
defer cancel() | ||
res, err := container.Exec(execCtx, c, ctrId, cmd) | ||
assert.Check(t, is.Nil(err)) | ||
assert.Check(t, is.Equal(res.ExitCode, expExitCode)) | ||
return res.Stdout() | ||
} | ||
|
||
// Check that IPv6 is/isn't enabled, as expected. | ||
var expPingExitStatus int | ||
if !tc.expIPv6Enabled { | ||
expPingExitStatus = 1 | ||
} | ||
runCmd(ctrId, []string{"ping", "-6", "-c1", "-W3", "::1"}, expPingExitStatus) | ||
|
||
// Check the contents of /etc/hosts. | ||
stdout := runCmd(ctrId, []string{"cat", "/etc/hosts"}, 0) | ||
// Append the container's own addresses/name to the expected hosts file content. | ||
inspect := container.Inspect(ctx, t, c, ctrId) | ||
exp := tc.expEtcHosts + inspect.NetworkSettings.IPAddress + "\t" + inspect.Config.Hostname + "\n" | ||
if tc.expIPv6Enabled { | ||
exp += inspect.NetworkSettings.GlobalIPv6Address + "\t" + inspect.Config.Hostname + "\n" | ||
} | ||
assert.Check(t, is.Equal(stdout, exp)) | ||
}) | ||
} | ||
} |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Oops, something went wrong.