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 }