From 730e2aa4c8265fe2382996bc0cf431d8837d8325 Mon Sep 17 00:00:00 2001 From: Michael Schurter Date: Fri, 1 Dec 2017 17:20:43 -0800 Subject: [PATCH] rkt: Don't require port_map with host networking Also don't try to return a DriverNetwork with host networking. None will ever exist as that's the point of host networking: rkt won't create a network namespace. --- CHANGELOG.md | 1 + client/driver/rkt.go | 25 +++++++++------ client/driver/rkt_test.go | 66 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c06034d4d1..66e915cfc21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ BUG FIXES: * client: Fix allocation accounting in GC and trigger GCs on allocation updates [GH-3445] * driver/rkt: Remove pods on shutdown [GH-3562] + * driver/rkt: Don't require port maps when using host networking [GH-3615] * template: Fix issue where multiple environment variable templates would be parsed incorrectly when contents of one have changed after the initial rendering [GH-3529] diff --git a/client/driver/rkt.go b/client/driver/rkt.go index 206d5f94fc0..75b6c074c09 100644 --- a/client/driver/rkt.go +++ b/client/driver/rkt.go @@ -529,6 +529,9 @@ func (d *RktDriver) Start(ctx *ExecContext, task *structs.Task) (*StartResponse, if len(driverConfig.PortMap) > 0 { return nil, fmt.Errorf("Trying to map ports but no network interface is available") } + } else if network == "host" { + // Port mapping is skipped when host networking is used. + d.logger.Println("[DEBUG] driver.rkt: Ignoring port_map when using --net=host") } else { // TODO add support for more than one network network := task.Resources.Networks[0] @@ -657,15 +660,19 @@ func (d *RktDriver) Start(ctx *ExecContext, task *structs.Task) (*StartResponse, } go h.run() - d.logger.Printf("[DEBUG] driver.rkt: retrieving network information for pod %q (UUID %s) for task %q", img, uuid, d.taskName) - driverNetwork, err := rktGetDriverNetwork(uuid, driverConfig.PortMap) - if err != nil && !pluginClient.Exited() { - d.logger.Printf("[WARN] driver.rkt: network status retrieval for pod %q (UUID %s) for task %q failed. Last error: %v", img, uuid, d.taskName, err) - - // If a portmap was given, this turns into a fatal error - if len(driverConfig.PortMap) != 0 { - pluginClient.Kill() - return nil, fmt.Errorf("Trying to map ports but driver could not determine network information") + // Only return a driver network if *not* using host networking + var driverNetwork *cstructs.DriverNetwork + if network != "host" { + d.logger.Printf("[DEBUG] driver.rkt: retrieving network information for pod %q (UUID %s) for task %q", img, uuid, d.taskName) + driverNetwork, err = rktGetDriverNetwork(uuid, driverConfig.PortMap) + if err != nil && !pluginClient.Exited() { + d.logger.Printf("[WARN] driver.rkt: network status retrieval for pod %q (UUID %s) for task %q failed. Last error: %v", img, uuid, d.taskName, err) + + // If a portmap was given, this turns into a fatal error + if len(driverConfig.PortMap) != 0 { + pluginClient.Kill() + return nil, fmt.Errorf("Trying to map ports but driver could not determine network information") + } } } diff --git a/client/driver/rkt_test.go b/client/driver/rkt_test.go index c41f749edc5..5f167c2f692 100644 --- a/client/driver/rkt_test.go +++ b/client/driver/rkt_test.go @@ -519,6 +519,72 @@ func TestRktDriver_PortsMapping(t *testing.T) { } } +// TestRktDriver_PortsMapping_Host asserts that port_map isn't required when +// host networking is used. +func TestRktDriver_PortsMapping_Host(t *testing.T) { + if !testutil.IsTravis() { + t.Parallel() + } + if os.Getenv("NOMAD_TEST_RKT") == "" { + t.Skip("skipping rkt tests") + } + + ctestutils.RktCompatible(t) + task := &structs.Task{ + Name: "etcd", + Driver: "rkt", + Config: map[string]interface{}{ + "image": "docker://redis:latest", + "net": []string{"host"}, + }, + LogConfig: &structs.LogConfig{ + MaxFiles: 10, + MaxFileSizeMB: 10, + }, + Resources: &structs.Resources{ + MemoryMB: 256, + CPU: 512, + Networks: []*structs.NetworkResource{ + { + IP: "127.0.0.1", + ReservedPorts: []structs.Port{{Label: "main", Value: 8080}}, + }, + }, + }, + } + + ctx := testDriverContexts(t, task) + defer ctx.AllocDir.Destroy() + d := NewRktDriver(ctx.DriverCtx) + + if _, err := d.Prestart(ctx.ExecCtx, task); err != nil { + t.Fatalf("error in prestart: %v", err) + } + resp, err := d.Start(ctx.ExecCtx, task) + if err != nil { + t.Fatalf("err: %v", err) + } + if resp.Network != nil { + t.Fatalf("No network should be returned with --net=host but found: %#v", resp.Network) + } + + failCh := make(chan error, 1) + go func() { + time.Sleep(1 * time.Second) + if err := resp.Handle.Kill(); err != nil { + failCh <- err + } + }() + + select { + case err := <-failCh: + t.Fatalf("failed to kill handle: %v", err) + case <-resp.Handle.WaitCh(): + case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second): + t.Fatalf("timeout") + } +} + func TestRktDriver_HandlerExec(t *testing.T) { if !testutil.IsTravis() { t.Parallel()