Merge pull request #8390 from MalteJ/set-macaddress

Adding docker-cli run param to set MAC address
This commit is contained in:
Alexandr Morozov 2014-11-04 07:54:59 -08:00
commit 9eb8fcd58a
11 changed files with 87 additions and 9 deletions

View file

@ -457,6 +457,7 @@ func (container *Container) AllocateNetwork() error {
)
job := eng.Job("allocate_interface", container.ID)
job.Setenv("RequestedMac", container.Config.MacAddress)
if env, err = job.Stdout.AddEnv(); err != nil {
return err
}

View file

@ -29,6 +29,7 @@ docker-run - Run a command in a new container
[**-m**|**--memory**[=*MEMORY*]]
[**--name**[=*NAME*]]
[**--net**[=*"bridge"*]]
[**--mac-address**[=*MACADDRESS*]]
[**-P**|**--publish-all**[=*false*]]
[**-p**|**--publish**[=*[]*]]
[**--privileged**[=*false*]]
@ -187,6 +188,14 @@ and foreground Docker containers.
'container:<name|id>': reuses another container network stack
'host': use the host network stack inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
**--mac-address**=*macaddress*
Set the MAC address for the container's Ethernet device:
--mac-address=12:34:56:78:9a:bc
Remember that the MAC address in an Ethernet network must be unique.
The IPv6 link-local address will be based on the device's MAC address
according to RFC4862.
**-P**, **--publish-all**=*true*|*false*
When set to true publish all exposed ports to the host interfaces. The
default is false. If the operator uses -P (or -p) then Docker will make the

View file

@ -104,6 +104,9 @@ Finally, several networking options can only be provided when calling
* `--net=bridge|none|container:NAME_or_ID|host` — see
[How Docker networks a container](#container-networking)
* `--mac-address=MACADDRESS...` — see
[How Docker networks a container](#container-networking)
* `-p SPEC` or `--publish=SPEC` — see
[Binding container ports](#binding-ports)
@ -537,9 +540,15 @@ The steps with which Docker configures a container are:
separate and unique network interface namespace, there are no
physical interfaces with which this name could collide.
4. Give the container's `eth0` a new IP address from within the
4. Set the interface's MAC address according to the `--mac-address`
parameter or generate a random one.
5. Give the container's `eth0` a new IP address from within the
bridge's range of network addresses, and set its default route to
the IP address that the Docker host owns on the bridge.
the IP address that the Docker host owns on the bridge. If available
the IP address is generated from the MAC address. This prevents ARP
cache invalidation problems, when a new container comes up with an
IP used in the past by another container with another MAC.
With these steps complete, the container now possesses an `eth0`
(virtual) network card and will find itself able to communicate with
@ -621,6 +630,7 @@ Docker do all of the configuration:
$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 address 12:34:56:78:9a:bc
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1

View file

@ -52,6 +52,10 @@ You can still call an old version of the API using
`info` now returns the number of CPUs available on the machine (`NCPU`) and
total memory available (`MemTotal`).
`POST /containers/create`
**New!**
You can set the new container's MAC address explicitly.
## v1.15
### Full Documentation

View file

@ -131,6 +131,7 @@ Create a container
},
"WorkingDir":"",
"NetworkDisabled": false,
"MacAddress":"12:34:56:78:9a:bc",
"ExposedPorts":{
"22/tcp": {}
},

View file

@ -131,6 +131,7 @@ Create a container
},
"WorkingDir":"",
"NetworkDisabled": false,
"MacAddress":"12:34:56:78:9a:bc",
"ExposedPorts":{
"22/tcp": {}
},

View file

@ -516,6 +516,7 @@ Creates a new container.
--lxc-conf=[] (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
-m, --memory="" Memory limit (format: <number><optional unit>, where unit = b, k, m or g)
--name="" Assign a name to the container
--mac-address="" Set the container's MAC address
--net="bridge" Set the Network mode for the container
'bridge': creates a new network stack for the container on the docker bridge
'none': no networking for this container
@ -867,6 +868,13 @@ straightforward manner.
$ sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' $INSTANCE_ID
**Get an instance's MAC Address:**
For the most part, you can pick out any field from the JSON in a fairly
straightforward manner.
$ sudo docker inspect --format='{{.NetworkSettings.MacAddress}}' $INSTANCE_ID
**List All Port Bindings:**
One can loop over arrays and maps in the results to produce simple text

View file

@ -133,13 +133,14 @@ example, `docker run ubuntu:14.04`.
## Network settings
--dns=[] : Set custom dns servers for the container
--net="bridge" : Set the Network mode for the container
'bridge': creates a new network stack for the container on the docker bridge
'none': no networking for this container
'container:<name|id>': reuses another container network stack
'host': use the host network stack inside the container
--add-host="" : Add a line to /etc/hosts (host:IP)
--dns=[] : Set custom dns servers for the container
--net="bridge" : Set the Network mode for the container
'bridge': creates a new network stack for the container on the docker bridge
'none': no networking for this container
'container:<name|id>': reuses another container network stack
'host': use the host network stack inside the container
--add-host="" : Add a line to /etc/hosts (host:IP)
--mac-address="" : Sets the container's Ethernet device's MAC address
By default, all containers have networking enabled and they can make any
outgoing connections. The operator can completely disable networking
@ -150,6 +151,10 @@ networking. In cases like this, you would perform I/O through files or
Your container will use the same DNS servers as the host by default, but
you can override this with `--dns`.
By default a random MAC is generated. You can set the container's MAC address
explicitly by providing a MAC via the `--mac-address` parameter (format:
`12:34:56:78:9a:bc`).
Supported networking modes are:
* none - no networking in the container

View file

@ -2018,6 +2018,41 @@ func TestRunNetworkNotInitializedNoneMode(t *testing.T) {
logDone("run - network must not be initialized in 'none' mode")
}
func TestRunSetMacAddress(t *testing.T) {
mac := "12:34:56:78:9a:bc"
cmd := exec.Command("/bin/bash", "-c", dockerBinary+` run -i --rm --mac-address=`+mac+` busybox /bin/sh -c "ip link show eth0 | tail -1 | awk '{ print \$2 }'"`)
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err)
}
actualMac := strings.TrimSpace(out)
if actualMac != mac {
t.Fatalf("Set MAC address with --mac-address failed. The container has an incorrect MAC address: %q, expected: %q", actualMac, mac)
}
deleteAllContainers()
logDone("run - setting MAC address with --mac-address")
}
func TestRunInspectMacAddress(t *testing.T) {
mac := "12:34:56:78:9a:bc"
cmd := exec.Command(dockerBinary, "run", "-d", "--mac-address="+mac, "busybox", "top")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err)
}
id := strings.TrimSpace(out)
inspectedMac, err := inspectField(id, "NetworkSettings.MacAddress")
if err != nil {
t.Fatal(err)
}
if inspectedMac != mac {
t.Fatalf("docker inspect outputs wrong MAC address: %q, should be: %q", inspectedMac, mac)
}
deleteAllContainers()
logDone("run - inspecting MAC address")
}
func TestRunDeallocatePortOnMissingIptablesRule(t *testing.T) {
cmd := exec.Command(dockerBinary, "run", "-d", "-p", "23:23", "busybox", "top")
out, _, err := runCommandWithOutput(cmd)

View file

@ -31,6 +31,7 @@ type Config struct {
WorkingDir string
Entrypoint []string
NetworkDisabled bool
MacAddress string
OnBuild []string
SecurityOpt []string
}
@ -53,6 +54,7 @@ func ContainerConfigFromJob(job *engine.Job) *Config {
Image: job.Getenv("Image"),
WorkingDir: job.Getenv("WorkingDir"),
NetworkDisabled: job.GetenvBool("NetworkDisabled"),
MacAddress: job.Getenv("MacAddress"),
}
job.GetenvJson("ExposedPorts", &config.ExposedPorts)
job.GetenvJson("Volumes", &config.Volumes)

View file

@ -59,6 +59,7 @@ func Parse(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Config,
flCpuShares = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
flCpuset = cmd.String([]string{"-cpuset"}, "", "CPUs in which to allow execution (0-3, 0,1)")
flNetMode = cmd.String([]string{"-net"}, "bridge", "Set the Network mode for the container\n'bridge': creates a new network stack for the container on the docker bridge\n'none': no networking for this container\n'container:<name|id>': reuses another container network stack\n'host': use the host network stack inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.")
flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
flRestartPolicy = cmd.String([]string{"-restart"}, "", "Restart policy to apply when a container exits (no, on-failure[:max-retry], always)")
)
@ -269,6 +270,7 @@ func Parse(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Config,
Cmd: runCmd,
Image: image,
Volumes: flVolumes.GetMap(),
MacAddress: *flMacAddress,
Entrypoint: entrypoint,
WorkingDir: *flWorkingDir,
SecurityOpt: flSecurityOpt.GetAll(),