github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/client/allocrunner/network_manager_linux.go (about) 1 package allocrunner 2 3 import ( 4 "fmt" 5 "strings" 6 7 hclog "github.com/hashicorp/go-hclog" 8 clientconfig "github.com/hashicorp/nomad/client/config" 9 "github.com/hashicorp/nomad/client/lib/nsutil" 10 "github.com/hashicorp/nomad/client/pluginmanager/drivermanager" 11 "github.com/hashicorp/nomad/nomad/structs" 12 "github.com/hashicorp/nomad/plugins/drivers" 13 ) 14 15 func newNetworkManager(alloc *structs.Allocation, driverManager drivermanager.Manager) (nm drivers.DriverNetworkManager, err error) { 16 // The defaultNetworkManager is used if a driver doesn't need to create the network 17 nm = &defaultNetworkManager{} 18 tg := alloc.Job.LookupTaskGroup(alloc.TaskGroup) 19 20 // default netmode to host, this can be overridden by the task or task group 21 tgNetMode := "host" 22 if len(tg.Networks) > 0 && tg.Networks[0].Mode != "" { 23 tgNetMode = tg.Networks[0].Mode 24 } 25 26 // networkInitiator tracks the task driver which needs to create the network 27 // to check for multiple drivers needing the create the network 28 var networkInitiator string 29 30 // driverCaps tracks which drivers we've checked capabilities for so as not 31 // to do extra work 32 driverCaps := make(map[string]struct{}) 33 for _, task := range tg.Tasks { 34 // the task's netmode defaults to the the task group but can be overridden 35 taskNetMode := tgNetMode 36 if len(task.Resources.Networks) > 0 && task.Resources.Networks[0].Mode != "" { 37 taskNetMode = task.Resources.Networks[0].Mode 38 } 39 40 // netmode host should always work to support backwards compat 41 if taskNetMode == "host" { 42 continue 43 } 44 45 // check to see if capabilities of this task's driver have already been checked 46 if _, ok := driverCaps[task.Driver]; ok { 47 continue 48 } 49 50 driver, err := driverManager.Dispense(task.Driver) 51 if err != nil { 52 return nil, fmt.Errorf("failed to dispense driver %s: %v", task.Driver, err) 53 } 54 55 caps, err := driver.Capabilities() 56 if err != nil { 57 return nil, fmt.Errorf("failed to retrieve capabilities for driver %s: %v", 58 task.Driver, err) 59 } 60 61 // check that the driver supports the requested network isolation mode 62 netIsolationMode := netModeToIsolationMode(taskNetMode) 63 if !caps.HasNetIsolationMode(netIsolationMode) { 64 return nil, fmt.Errorf("task %s does not support %q networking mode", task.Name, taskNetMode) 65 } 66 67 // check if the driver needs to create the network and if a different 68 // driver has already claimed it needs to initiate the network 69 if caps.MustInitiateNetwork { 70 if networkInitiator != "" { 71 return nil, fmt.Errorf("tasks %s and %s want to initiate networking but only one driver can do so", networkInitiator, task.Name) 72 } 73 netManager, ok := driver.(drivers.DriverNetworkManager) 74 if !ok { 75 return nil, fmt.Errorf("driver %s does not implement network management RPCs", task.Driver) 76 } 77 78 nm = netManager 79 networkInitiator = task.Name 80 } 81 82 // mark this driver's capabilities as checked 83 driverCaps[task.Driver] = struct{}{} 84 } 85 86 return nm, nil 87 } 88 89 // defaultNetworkManager creates a network namespace for the alloc 90 type defaultNetworkManager struct{} 91 92 func (*defaultNetworkManager) CreateNetwork(allocID string) (*drivers.NetworkIsolationSpec, bool, error) { 93 netns, err := nsutil.NewNS(allocID) 94 if err != nil { 95 return nil, false, err 96 } 97 98 spec := &drivers.NetworkIsolationSpec{ 99 Mode: drivers.NetIsolationModeGroup, 100 Path: netns.Path(), 101 Labels: make(map[string]string), 102 } 103 104 return spec, true, nil 105 } 106 107 func (*defaultNetworkManager) DestroyNetwork(allocID string, spec *drivers.NetworkIsolationSpec) error { 108 return nsutil.UnmountNS(spec.Path) 109 } 110 111 func netModeToIsolationMode(netMode string) drivers.NetIsolationMode { 112 switch strings.ToLower(netMode) { 113 case "host": 114 return drivers.NetIsolationModeHost 115 case "bridge", "none": 116 return drivers.NetIsolationModeGroup 117 case "driver": 118 return drivers.NetIsolationModeTask 119 default: 120 return drivers.NetIsolationModeHost 121 } 122 } 123 124 func newNetworkConfigurator(log hclog.Logger, alloc *structs.Allocation, config *clientconfig.Config) (NetworkConfigurator, error) { 125 tg := alloc.Job.LookupTaskGroup(alloc.TaskGroup) 126 127 // Check if network stanza is given 128 if len(tg.Networks) == 0 { 129 return &hostNetworkConfigurator{}, nil 130 } 131 132 switch strings.ToLower(tg.Networks[0].Mode) { 133 case "bridge": 134 return newBridgeNetworkConfigurator(log, config.BridgeNetworkName, config.BridgeNetworkAllocSubnet, config.CNIPath) 135 default: 136 return &hostNetworkConfigurator{}, nil 137 } 138 }