-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Advertise driver-specific addresses #2709
Changes from 17 commits
3fddb05
8a7df57
4117c8b
57b6f6e
ee5e02f
cda2db2
8ed23d4
a464ca3
e6552e1
2023946
81b942e
deffe5b
3f37be3
b5fdf1d
5d7fba4
fe3bb07
9ef4a42
a70ad9b
cc29d74
8c32582
85860dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -471,7 +471,7 @@ func (d *DockerDriver) Prestart(ctx *ExecContext, task *structs.Task) (*Prestart | |
return nil, err | ||
} | ||
|
||
// Set state needed by Start() | ||
// Set state needed by Start | ||
d.driverConfig = driverConfig | ||
|
||
// Initialize docker API clients | ||
|
@@ -485,15 +485,21 @@ func (d *DockerDriver) Prestart(ctx *ExecContext, task *structs.Task) (*Prestart | |
if err != nil { | ||
return nil, err | ||
} | ||
d.imageID = id | ||
|
||
resp := NewPrestartResponse() | ||
resp.CreatedResources.Add(dockerImageResKey, id) | ||
resp.PortMap = d.driverConfig.PortMap | ||
d.imageID = id | ||
|
||
// Return the PortMap if it's set | ||
if len(driverConfig.PortMap) > 0 { | ||
resp.Network = &cstructs.DriverNetwork{ | ||
PortMap: driverConfig.PortMap, | ||
} | ||
} | ||
return resp, nil | ||
} | ||
|
||
func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) { | ||
func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (*StartResponse, error) { | ||
|
||
pluginLogFile := filepath.Join(ctx.TaskDir.Dir, "executor.out") | ||
executorConfig := &dstructs.ExecutorConfig{ | ||
|
@@ -560,6 +566,15 @@ func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle | |
pluginClient.Kill() | ||
return nil, fmt.Errorf("Failed to start container %s: %s", container.ID, err) | ||
} | ||
// InspectContainer to get all of the container metadata as | ||
// much of the metadata (eg networking) isn't populated until | ||
// the container is started | ||
if container, err = client.InspectContainer(container.ID); err != nil { | ||
err = fmt.Errorf("failed to inspect started container %s: %s", container.ID, err) | ||
d.logger.Printf("[ERR] driver.docker: %v", err) | ||
pluginClient.Kill() | ||
return nil, structs.NewRecoverableError(err, true) | ||
} | ||
d.logger.Printf("[INFO] driver.docker: started container %s", container.ID) | ||
} else { | ||
d.logger.Printf("[DEBUG] driver.docker: re-attaching to container %s with status %q", | ||
|
@@ -585,7 +600,50 @@ func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle | |
} | ||
go h.collectStats() | ||
go h.run() | ||
return h, nil | ||
|
||
// Detect container address | ||
ip, autoUse := d.detectIP(container) | ||
|
||
// Create a response with the driver handle and container network metadata | ||
resp := &StartResponse{ | ||
Handle: h, | ||
Network: &cstructs.DriverNetwork{ | ||
PortMap: d.driverConfig.PortMap, | ||
IP: ip, | ||
AutoAdvertise: autoUse, | ||
}, | ||
} | ||
return resp, nil | ||
} | ||
|
||
func (d *DockerDriver) detectIP(c *docker.Container) (string, bool) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put a comment on what this does and the fields it returns |
||
if c.NetworkSettings == nil { | ||
// This should only happen if there's been a coding error (such | ||
// as not calling InspetContainer after CreateContainer). Code | ||
// defensively in case the Docker API changes subtly. | ||
d.logger.Printf("[ERROR] driver.docker: no network settings for container %s", c.ID) | ||
return "", false | ||
} | ||
ip, ipName := "", "" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add blank spaces between blocks. Here and line 643 |
||
auto := false | ||
for name, net := range c.NetworkSettings.Networks { | ||
if net.IPAddress == "" { | ||
// Ignore networks without an IP address | ||
continue | ||
} | ||
ip = net.IPAddress | ||
ipName = name | ||
|
||
// Don't auto-advertise bridge IPs | ||
if name != "bridge" { | ||
auto = true | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just break? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
break | ||
} | ||
if n := len(c.NetworkSettings.Networks); n > 1 { | ||
d.logger.Printf("[WARN] driver.docker: multiple (%d) Docker networks for container %q but Nomad only supports 1: choosing %q", n, c.ID, ipName) | ||
} | ||
return ip, auto | ||
} | ||
|
||
func (d *DockerDriver) Cleanup(_ *ExecContext, res *CreatedResources) error { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Canonicalize below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added