mirror of
https://github.com/kemko/nomad.git
synced 2026-01-04 17:35:43 +03:00
Merge pull request #1980 from dmexe/network-aliases
Add network_aliases for docker driver
This commit is contained in:
@@ -113,6 +113,7 @@ type DockerDriverConfig struct {
|
||||
Args []string `mapstructure:"args"` // The arguments to the Command/Entrypoint
|
||||
IpcMode string `mapstructure:"ipc_mode"` // The IPC mode of the container - host and none
|
||||
NetworkMode string `mapstructure:"network_mode"` // The network mode of the container - host, nat and none
|
||||
NetworkAliases []string `mapstructure:"network_aliases"` // The network-scoped alias for the container
|
||||
PidMode string `mapstructure:"pid_mode"` // The PID mode of the container - host and none
|
||||
UTSMode string `mapstructure:"uts_mode"` // The UTS mode of the container - host and none
|
||||
UsernsMode string `mapstructure:"userns_mode"` // The User namespace mode of the container - host and none
|
||||
@@ -165,6 +166,7 @@ func NewDockerDriverConfig(task *structs.Task, env *env.TaskEnvironment) (*Docke
|
||||
dconf.Command = env.ReplaceEnv(dconf.Command)
|
||||
dconf.IpcMode = env.ReplaceEnv(dconf.IpcMode)
|
||||
dconf.NetworkMode = env.ReplaceEnv(dconf.NetworkMode)
|
||||
dconf.NetworkAliases = env.ParseAndReplace(dconf.NetworkAliases)
|
||||
dconf.PidMode = env.ReplaceEnv(dconf.PidMode)
|
||||
dconf.UTSMode = env.ReplaceEnv(dconf.UTSMode)
|
||||
dconf.Hostname = env.ReplaceEnv(dconf.Hostname)
|
||||
@@ -272,6 +274,9 @@ func (d *DockerDriver) Validate(config map[string]interface{}) error {
|
||||
"network_mode": &fields.FieldSchema{
|
||||
Type: fields.TypeString,
|
||||
},
|
||||
"network_aliases": &fields.FieldSchema{
|
||||
Type: fields.TypeArray,
|
||||
},
|
||||
"pid_mode": &fields.FieldSchema{
|
||||
Type: fields.TypeString,
|
||||
},
|
||||
@@ -838,10 +843,22 @@ func (d *DockerDriver) createContainerConfig(ctx *ExecContext, task *structs.Tas
|
||||
containerName := fmt.Sprintf("%s-%s", task.Name, ctx.AllocID)
|
||||
d.logger.Printf("[DEBUG] driver.docker: setting container name to: %s", containerName)
|
||||
|
||||
networkingConfig := &docker.NetworkingConfig{
|
||||
EndpointsConfig: make(map[string]*docker.EndpointConfig),
|
||||
}
|
||||
|
||||
if len(driverConfig.NetworkAliases) > 0 {
|
||||
networkingConfig.EndpointsConfig[hostConfig.NetworkMode] = &docker.EndpointConfig{
|
||||
Aliases: driverConfig.NetworkAliases,
|
||||
}
|
||||
d.logger.Printf("[DEBUG] driver.docker: applied network aliases on the container: [%s]%+v", hostConfig.NetworkMode, driverConfig.NetworkAliases)
|
||||
}
|
||||
|
||||
return docker.CreateContainerOptions{
|
||||
Name: containerName,
|
||||
Config: config,
|
||||
HostConfig: hostConfig,
|
||||
Name: containerName,
|
||||
Config: config,
|
||||
HostConfig: hostConfig,
|
||||
NetworkingConfig: networkingConfig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -87,15 +87,11 @@ func dockerTask() (*structs.Task, int, int) {
|
||||
// If there is a problem during setup this function will abort or skip the test
|
||||
// and indicate the reason.
|
||||
func dockerSetup(t *testing.T, task *structs.Task) (*docker.Client, DriverHandle, func()) {
|
||||
if !testutil.DockerIsConnected(t) {
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
client, err := docker.NewClientFromEnv()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to initialize client: %s\nStack\n%s", err, debug.Stack())
|
||||
}
|
||||
client := newTestDockerClient(t)
|
||||
return dockerSetupWithClient(t, task, client)
|
||||
}
|
||||
|
||||
func dockerSetupWithClient(t *testing.T, task *structs.Task, client *docker.Client) (*docker.Client, DriverHandle, func()) {
|
||||
driverCtx, execCtx := testDriverContexts(task)
|
||||
driverCtx.config.Options = map[string]string{"docker.cleanup.image": "false"}
|
||||
driver := NewDockerDriver(driverCtx)
|
||||
@@ -119,6 +115,18 @@ func dockerSetup(t *testing.T, task *structs.Task) (*docker.Client, DriverHandle
|
||||
return client, handle, cleanup
|
||||
}
|
||||
|
||||
func newTestDockerClient(t *testing.T) *docker.Client {
|
||||
if !testutil.DockerIsConnected(t) {
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
client, err := docker.NewClientFromEnv()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to initialize client: %s\nStack\n%s", err, debug.Stack())
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// This test should always pass, even if docker daemon is not available
|
||||
func TestDockerDriver_Fingerprint(t *testing.T) {
|
||||
driverCtx, execCtx := testDriverContexts(&structs.Task{Name: "foo", Resources: basicResources})
|
||||
@@ -589,6 +597,51 @@ func TestDockerDriver_NetworkMode_Host(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDockerDriver_NetworkAliases_Bridge(t *testing.T) {
|
||||
// Because go-dockerclient doesn't provide api for query network aliases, just check that
|
||||
// a container can be created with a 'network_aliases' property
|
||||
|
||||
// Create network, network-scoped alias is supported only for containers in user defined networks
|
||||
client := newTestDockerClient(t)
|
||||
networkOpts := docker.CreateNetworkOptions{Name: "foobar", Driver: "bridge"}
|
||||
network, err := client.CreateNetwork(networkOpts)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
defer client.RemoveNetwork(network.ID)
|
||||
|
||||
expected := []string{"foobar"}
|
||||
task := &structs.Task{
|
||||
Name: "nc-demo",
|
||||
Config: map[string]interface{}{
|
||||
"image": "busybox",
|
||||
"load": []string{"busybox.tar"},
|
||||
"command": "/bin/nc",
|
||||
"args": []string{"-l", "127.0.0.1", "-p", "0"},
|
||||
"network_mode": network.Name,
|
||||
"network_aliases": expected,
|
||||
},
|
||||
Resources: &structs.Resources{
|
||||
MemoryMB: 256,
|
||||
CPU: 512,
|
||||
},
|
||||
LogConfig: &structs.LogConfig{
|
||||
MaxFiles: 10,
|
||||
MaxFileSizeMB: 10,
|
||||
},
|
||||
}
|
||||
|
||||
client, handle, cleanup := dockerSetupWithClient(t, task, client)
|
||||
defer cleanup()
|
||||
|
||||
waitForExist(t, client, handle.(*DockerHandle))
|
||||
|
||||
_, err = client.InspectContainer(handle.(*DockerHandle).ContainerID())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDockerDriver_Labels(t *testing.T) {
|
||||
task, _, _ := dockerTask()
|
||||
task.Config["labels"] = []map[string]string{
|
||||
|
||||
@@ -126,6 +126,21 @@ The `docker` driver supports the following configuration in the job spec:
|
||||
pre-docker 1.9 are `default`, `bridge`, `host`, `none`, or `container:name`.
|
||||
See below for more details.
|
||||
|
||||
* `network_aliases` - (Optional) A list of network-scoped aliases, provide a way for a
|
||||
container to be discovered by an alternate name by any other container within
|
||||
the scope of a particular network. Network-scoped alias is supported only for
|
||||
containers in user defined networks
|
||||
|
||||
```hcl
|
||||
config {
|
||||
network_mode = "overlay"
|
||||
network_aliases = [
|
||||
"${NOMAD_TASK_NAME}",
|
||||
"${NOMAD_TASK_NAME}-${NOMAD_ALLOC_INDEX}"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
* `hostname` - (Optional) The hostname to assign to the container. When
|
||||
launching more than one of a task (using `count`) with this option set, every
|
||||
container the task starts will have the same hostname.
|
||||
|
||||
Reference in New Issue
Block a user