github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/drivers/docker/network.go (about)

     1  package docker
     2  
     3  import (
     4  	"fmt"
     5  
     6  	docker "github.com/fsouza/go-dockerclient"
     7  	"github.com/hashicorp/nomad/plugins/drivers"
     8  )
     9  
    10  // dockerNetSpecLabelKey is used when creating a parent container for
    11  // shared networking. It is a label whos value identifies the container ID of
    12  // the parent container so tasks can configure their network mode accordingly
    13  const dockerNetSpecLabelKey = "docker_sandbox_container_id"
    14  
    15  func (d *Driver) CreateNetwork(allocID string) (*drivers.NetworkIsolationSpec, bool, error) {
    16  	// Initialize docker API clients
    17  	client, _, err := d.dockerClients()
    18  	if err != nil {
    19  		return nil, false, fmt.Errorf("failed to connect to docker daemon: %s", err)
    20  	}
    21  
    22  	repo, _ := parseDockerImage(d.config.InfraImage)
    23  	authOptions, err := firstValidAuth(repo, []authBackend{
    24  		authFromDockerConfig(d.config.Auth.Config),
    25  		authFromHelper(d.config.Auth.Helper),
    26  	})
    27  	if err != nil {
    28  		d.logger.Debug("auth failed for infra container image pull", "image", d.config.InfraImage, "error", err)
    29  	}
    30  	_, err = d.coordinator.PullImage(d.config.InfraImage, authOptions, allocID, noopLogEventFn, d.config.infraImagePullTimeoutDuration, d.config.pullActivityTimeoutDuration)
    31  	if err != nil {
    32  		return nil, false, err
    33  	}
    34  
    35  	config, err := d.createSandboxContainerConfig(allocID)
    36  	if err != nil {
    37  		return nil, false, err
    38  	}
    39  
    40  	specFromContainer := func(c *docker.Container) *drivers.NetworkIsolationSpec {
    41  		return &drivers.NetworkIsolationSpec{
    42  			Mode: drivers.NetIsolationModeGroup,
    43  			Path: c.NetworkSettings.SandboxKey,
    44  			Labels: map[string]string{
    45  				dockerNetSpecLabelKey: c.ID,
    46  			},
    47  		}
    48  	}
    49  
    50  	// We want to return a flag that tells us if the container already
    51  	// existed so that callers can decide whether or not to recreate
    52  	// the task's network namespace associations.
    53  	container, err := d.containerByName(config.Name)
    54  	if err != nil {
    55  		return nil, false, err
    56  	}
    57  	if container != nil && container.State.Running {
    58  		return specFromContainer(container), false, nil
    59  	}
    60  
    61  	container, err = d.createContainer(client, *config, d.config.InfraImage)
    62  	if err != nil {
    63  		return nil, false, err
    64  	}
    65  
    66  	if err = d.startContainer(container); err != nil {
    67  		return nil, false, err
    68  	}
    69  
    70  	// until the container is started, InspectContainerWithOptions
    71  	// returns a mostly-empty struct
    72  	container, err = client.InspectContainerWithOptions(docker.InspectContainerOptions{
    73  		ID: container.ID,
    74  	})
    75  	if err != nil {
    76  		return nil, false, err
    77  	}
    78  
    79  	return specFromContainer(container), true, nil
    80  }
    81  
    82  func (d *Driver) DestroyNetwork(allocID string, spec *drivers.NetworkIsolationSpec) error {
    83  	client, _, err := d.dockerClients()
    84  	if err != nil {
    85  		return fmt.Errorf("failed to connect to docker daemon: %s", err)
    86  	}
    87  
    88  	return client.RemoveContainer(docker.RemoveContainerOptions{
    89  		Force: true,
    90  		ID:    spec.Labels[dockerNetSpecLabelKey],
    91  	})
    92  }
    93  
    94  // createSandboxContainerConfig creates a docker container configuration which
    95  // starts a container with an empty network namespace
    96  func (d *Driver) createSandboxContainerConfig(allocID string) (*docker.CreateContainerOptions, error) {
    97  
    98  	return &docker.CreateContainerOptions{
    99  		Name: fmt.Sprintf("nomad_init_%s", allocID),
   100  		Config: &docker.Config{
   101  			Image: d.config.InfraImage,
   102  		},
   103  		HostConfig: &docker.HostConfig{
   104  			// set the network mode to none which creates a network namespace with
   105  			// only a loopback interface
   106  			NetworkMode: "none",
   107  		},
   108  	}, nil
   109  }