1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Allow user to specify container's link-local addresses

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch 2016-06-09 15:10:59 -07:00
parent c913dd5f57
commit 1c4efb6aa0
11 changed files with 107 additions and 30 deletions

View file

@ -12,12 +12,13 @@ import (
) )
type connectOptions struct { type connectOptions struct {
network string network string
container string container string
ipaddress string ipaddress string
ipv6address string ipv6address string
links opts.ListOpts links opts.ListOpts
aliases []string aliases []string
linklocalips []string
} }
func newConnectCommand(dockerCli *client.DockerCli) *cobra.Command { func newConnectCommand(dockerCli *client.DockerCli) *cobra.Command {
@ -41,6 +42,7 @@ func newConnectCommand(dockerCli *client.DockerCli) *cobra.Command {
flags.StringVar(&opts.ipv6address, "ip6", "", "IPv6 Address") flags.StringVar(&opts.ipv6address, "ip6", "", "IPv6 Address")
flags.Var(&opts.links, "link", "Add link to another container") flags.Var(&opts.links, "link", "Add link to another container")
flags.StringSliceVar(&opts.aliases, "alias", []string{}, "Add network-scoped alias for the container") flags.StringSliceVar(&opts.aliases, "alias", []string{}, "Add network-scoped alias for the container")
flags.StringSliceVar(&opts.linklocalips, "link-local-ip", []string{}, "Add a link-local address for the container")
return cmd return cmd
} }
@ -50,8 +52,9 @@ func runConnect(dockerCli *client.DockerCli, opts connectOptions) error {
epConfig := &network.EndpointSettings{ epConfig := &network.EndpointSettings{
IPAMConfig: &network.EndpointIPAMConfig{ IPAMConfig: &network.EndpointIPAMConfig{
IPv4Address: opts.ipaddress, IPv4Address: opts.ipaddress,
IPv6Address: opts.ipv6address, IPv6Address: opts.ipv6address,
LinkLocalIPs: opts.linklocalips,
}, },
Links: opts.links.GetAll(), Links: opts.links.GetAll(),
Aliases: opts.aliases, Aliases: opts.aliases,

View file

@ -789,9 +789,15 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC
if epConfig != nil { if epConfig != nil {
ipam := epConfig.IPAMConfig ipam := epConfig.IPAMConfig
if ipam != nil && (ipam.IPv4Address != "" || ipam.IPv6Address != "") { if ipam != nil && (ipam.IPv4Address != "" || ipam.IPv6Address != "" || len(ipam.LinkLocalIPs) > 0) {
var ipList []net.IP
for _, ips := range ipam.LinkLocalIPs {
if ip := net.ParseIP(ips); ip != nil {
ipList = append(ipList, ip)
}
}
createOptions = append(createOptions, createOptions = append(createOptions,
libnetwork.CreateOptionIpam(net.ParseIP(ipam.IPv4Address), net.ParseIP(ipam.IPv6Address), nil, nil)) libnetwork.CreateOptionIpam(net.ParseIP(ipam.IPv4Address), net.ParseIP(ipam.IPv6Address), ipList, nil))
} }
for _, alias := range epConfig.Aliases { for _, alias := range epConfig.Aliases {

View file

@ -339,7 +339,8 @@ Create a container
"isolated_nw" : { "isolated_nw" : {
"IPAMConfig": { "IPAMConfig": {
"IPv4Address":"172.20.30.33", "IPv4Address":"172.20.30.33",
"IPv6Address":"2001:db8:abcd::3033" "IPv6Address":"2001:db8:abcd::3033",
"LinkLocalIPs:["169.254.34.68", "fe80::3468"]
}, },
"Links":["container_1", "container_2"], "Links":["container_1", "container_2"],
"Aliases":["server_x", "server_y"] "Aliases":["server_x", "server_y"]

View file

@ -54,6 +54,7 @@ Creates a new container.
-l, --label=[] Set metadata on the container (e.g., --label=com.example.key=value) -l, --label=[] Set metadata on the container (e.g., --label=com.example.key=value)
--label-file=[] Read in a line delimited file of labels --label-file=[] Read in a line delimited file of labels
--link=[] Add link to another container --link=[] Add link to another container
--link-local-ip=[] Container IPv4/IPv6 link-local addresses (e.g. 169.254.0.77, fe80::77)
--log-driver="" Logging driver for container --log-driver="" Logging driver for container
--log-opt=[] Log driver specific options --log-opt=[] Log driver specific options
-m, --memory="" Memory limit -m, --memory="" Memory limit

View file

@ -19,6 +19,7 @@ parent = "smn_cli"
--ip IPv4 Address --ip IPv4 Address
--ip6 IPv6 Address --ip6 IPv6 Address
--link=[] Add a link to another container --link=[] Add a link to another container
--link-local-ip=[] IPv4/IPv6 link-local addresses
Connects a container to a network. You can connect a container by name Connects a container to a network. You can connect a container by name
or by ID. Once connected, the container can communicate with other containers in or by ID. Once connected, the container can communicate with other containers in

View file

@ -55,6 +55,7 @@ parent = "smn_cli"
-l, --label=[] Set metadata on the container (e.g., --label=com.example.key=value) -l, --label=[] Set metadata on the container (e.g., --label=com.example.key=value)
--label-file=[] Read in a file of labels (EOL delimited) --label-file=[] Read in a file of labels (EOL delimited)
--link=[] Add link to another container --link=[] Add link to another container
--link-local-ip=[] Container IPv4/IPv6 link-local addresses (e.g. 169.254.0.77, fe80::77)
--log-driver="" Logging driver for container --log-driver="" Logging driver for container
--log-opt=[] Log driver specific options --log-opt=[] Log driver specific options
-m, --memory="" Memory limit -m, --memory="" Memory limit

View file

@ -288,18 +288,19 @@ of the containers.
## Network settings ## Network settings
--dns=[] : Set custom dns servers for the container --dns=[] : Set custom dns servers for the container
--net="bridge" : Connect a container to a network --net="bridge" : Connect a container to a network
'bridge': create a network stack on the default Docker bridge 'bridge': create a network stack on the default Docker bridge
'none': no networking 'none': no networking
'container:<name|id>': reuse another container's network stack 'container:<name|id>': reuse another container's network stack
'host': use the Docker host network stack 'host': use the Docker host network stack
'<network-name>|<network-id>': connect to a user-defined network '<network-name>|<network-id>': connect to a user-defined network
--net-alias=[] : Add network-scoped alias for the container --net-alias=[] : Add network-scoped alias for the container
--add-host="" : Add a line to /etc/hosts (host:IP) --add-host="" : Add a line to /etc/hosts (host:IP)
--mac-address="" : Sets the container's Ethernet device's MAC address --mac-address="" : Sets the container's Ethernet device's MAC address
--ip="" : Sets the container's Ethernet device's IPv4 address --ip="" : Sets the container's Ethernet device's IPv4 address
--ip6="" : Sets the container's Ethernet device's IPv6 address --ip6="" : Sets the container's Ethernet device's IPv6 address
--link-local-ip=[] : Sets one or more container's Ethernet device's link local IPv4/IPv6 addresses
By default, all containers have networking enabled and they can make any By default, all containers have networking enabled and they can make any
outgoing connections. The operator can completely disable networking outgoing connections. The operator can completely disable networking

View file

@ -1336,6 +1336,53 @@ func verifyIPAddresses(c *check.C, cName, nwname, ipv4, ipv6 string) {
c.Assert(strings.TrimSpace(out), check.Equals, ipv6) c.Assert(strings.TrimSpace(out), check.Equals, ipv6)
} }
func (s *DockerNetworkSuite) TestDockerNetworkConnectLinkLocalIP(c *check.C) {
// create one test network
dockerCmd(c, "network", "create", "n0")
assertNwIsAvailable(c, "n0")
// run a container with incorrect link-local address
_, _, err := dockerCmdWithError("run", "--link-local-ip", "169.253.5.5", "busybox", "top")
c.Assert(err, check.NotNil)
_, _, err = dockerCmdWithError("run", "--link-local-ip", "2001:db8::89", "busybox", "top")
c.Assert(err, check.NotNil)
// run two containers with link-local ip on the test network
dockerCmd(c, "run", "-d", "--name", "c0", "--net=n0", "--link-local-ip", "169.254.7.7", "--link-local-ip", "fe80::254:77", "busybox", "top")
c.Assert(waitRun("c0"), check.IsNil)
dockerCmd(c, "run", "-d", "--name", "c1", "--net=n0", "--link-local-ip", "169.254.8.8", "--link-local-ip", "fe80::254:88", "busybox", "top")
c.Assert(waitRun("c1"), check.IsNil)
// run a container on the default network and connect it to the test network specifying a link-local address
dockerCmd(c, "run", "-d", "--name", "c2", "busybox", "top")
c.Assert(waitRun("c2"), check.IsNil)
dockerCmd(c, "network", "connect", "--link-local-ip", "169.254.9.9", "n0", "c2")
// verify the three containers can ping each other via the link-local addresses
_, _, err = dockerCmdWithError("exec", "c0", "ping", "-c", "1", "169.254.8.8")
c.Assert(err, check.IsNil)
_, _, err = dockerCmdWithError("exec", "c1", "ping", "-c", "1", "169.254.9.9")
c.Assert(err, check.IsNil)
_, _, err = dockerCmdWithError("exec", "c2", "ping", "-c", "1", "169.254.7.7")
c.Assert(err, check.IsNil)
// Stop and restart the three containers
dockerCmd(c, "stop", "c0")
dockerCmd(c, "stop", "c1")
dockerCmd(c, "stop", "c2")
dockerCmd(c, "start", "c0")
dockerCmd(c, "start", "c1")
dockerCmd(c, "start", "c2")
// verify the ping again
_, _, err = dockerCmdWithError("exec", "c0", "ping", "-c", "1", "169.254.8.8")
c.Assert(err, check.IsNil)
_, _, err = dockerCmdWithError("exec", "c1", "ping", "-c", "1", "169.254.9.9")
c.Assert(err, check.IsNil)
_, _, err = dockerCmdWithError("exec", "c2", "ping", "-c", "1", "169.254.7.7")
c.Assert(err, check.IsNil)
}
func (s *DockerSuite) TestUserDefinedNetworkConnectDisconnectLink(c *check.C) { func (s *DockerSuite) TestUserDefinedNetworkConnectDisconnectLink(c *check.C) {
testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm) testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
dockerCmd(c, "network", "create", "-d", "bridge", "foo1") dockerCmd(c, "network", "create", "-d", "bridge", "foo1")

View file

@ -43,6 +43,7 @@ docker-create - Create a new container
[**-l**|**--label**[=*[]*]] [**-l**|**--label**[=*[]*]]
[**--label-file**[=*[]*]] [**--label-file**[=*[]*]]
[**--link**[=*[]*]] [**--link**[=*[]*]]
[**--link-local-ip**[=*[]*]]
[**--log-driver**[=*[]*]] [**--log-driver**[=*[]*]]
[**--log-opt**[=*[]*]] [**--log-opt**[=*[]*]]
[**-m**|**--memory**[=*MEMORY*]] [**-m**|**--memory**[=*MEMORY*]]
@ -220,6 +221,9 @@ millions of trillions.
Add link to another container in the form of <name or id>:alias or just Add link to another container in the form of <name or id>:alias or just
<name or id> in which case the alias will match the name. <name or id> in which case the alias will match the name.
**--link-local-ip**=[]
Add one or more link-local IPv4/IPv6 addresses to the container's interface
**--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*awslogs*|*splunk*|*etwlogs*|*gcplogs*|*none*" **--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*awslogs*|*splunk*|*etwlogs*|*gcplogs*|*none*"
Logging driver for container. Default is defined by daemon `--log-driver` flag. Logging driver for container. Default is defined by daemon `--log-driver` flag.
**Warning**: the `docker logs` command works only for the `json-file` and **Warning**: the `docker logs` command works only for the `json-file` and

View file

@ -45,6 +45,7 @@ docker-run - Run a command in a new container
[**-l**|**--label**[=*[]*]] [**-l**|**--label**[=*[]*]]
[**--label-file**[=*[]*]] [**--label-file**[=*[]*]]
[**--link**[=*[]*]] [**--link**[=*[]*]]
[**--link-local-ip**[=*[]*]]
[**--log-driver**[=*[]*]] [**--log-driver**[=*[]*]]
[**--log-opt**[=*[]*]] [**--log-opt**[=*[]*]]
[**-m**|**--memory**[=*MEMORY*]] [**-m**|**--memory**[=*MEMORY*]]
@ -326,6 +327,9 @@ container can access the exposed port via a private networking interface. Docker
will set some environment variables in the client container to help indicate will set some environment variables in the client container to help indicate
which interface and port to use. which interface and port to use.
**--link-local-ip**=[]
Add one or more link-local IPv4/IPv6 addresses to the container's interface
**--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*awslogs*|*splunk*|*etwlogs*|*gcplogs*|*none*" **--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*awslogs*|*splunk*|*etwlogs*|*gcplogs*|*none*"
Logging driver for container. Default is defined by daemon `--log-driver` flag. Logging driver for container. Default is defined by daemon `--log-driver` flag.
**Warning**: the `docker logs` command works only for the `json-file` and **Warning**: the `docker logs` command works only for the `json-file` and

View file

@ -32,6 +32,7 @@ type ContainerOptions struct {
flDeviceWriteBps ThrottledeviceOpt flDeviceWriteBps ThrottledeviceOpt
flLinks opts.ListOpts flLinks opts.ListOpts
flAliases opts.ListOpts flAliases opts.ListOpts
flLinkLocalIPs opts.ListOpts
flDeviceReadIOps ThrottledeviceOpt flDeviceReadIOps ThrottledeviceOpt
flDeviceWriteIOps ThrottledeviceOpt flDeviceWriteIOps ThrottledeviceOpt
flEnv opts.ListOpts flEnv opts.ListOpts
@ -117,6 +118,7 @@ func AddFlags(flags *pflag.FlagSet) *ContainerOptions {
flDeviceWriteBps: NewThrottledeviceOpt(ValidateThrottleBpsDevice), flDeviceWriteBps: NewThrottledeviceOpt(ValidateThrottleBpsDevice),
flLinks: opts.NewListOpts(ValidateLink), flLinks: opts.NewListOpts(ValidateLink),
flAliases: opts.NewListOpts(nil), flAliases: opts.NewListOpts(nil),
flLinkLocalIPs: opts.NewListOpts(nil),
flDeviceReadIOps: NewThrottledeviceOpt(ValidateThrottleIOpsDevice), flDeviceReadIOps: NewThrottledeviceOpt(ValidateThrottleIOpsDevice),
flDeviceWriteIOps: NewThrottledeviceOpt(ValidateThrottleIOpsDevice), flDeviceWriteIOps: NewThrottledeviceOpt(ValidateThrottleIOpsDevice),
flEnv: opts.NewListOpts(ValidateEnv), flEnv: opts.NewListOpts(ValidateEnv),
@ -201,6 +203,7 @@ func AddFlags(flags *pflag.FlagSet) *ContainerOptions {
flags.Var(&copts.flTmpfs, "tmpfs", "Mount a tmpfs directory") flags.Var(&copts.flTmpfs, "tmpfs", "Mount a tmpfs directory")
flags.Var(&copts.flLinks, "link", "Add link to another container") flags.Var(&copts.flLinks, "link", "Add link to another container")
flags.Var(&copts.flAliases, "net-alias", "Add network-scoped alias for the container") flags.Var(&copts.flAliases, "net-alias", "Add network-scoped alias for the container")
flags.Var(&copts.flLinkLocalIPs, "link-local-ip", "Container IPv4/IPv6 link-local addresses")
flags.Var(&copts.flDevices, "device", "Add a host device to the container") flags.Var(&copts.flDevices, "device", "Add a host device to the container")
flags.VarP(&copts.flLabels, "label", "l", "Set meta data on a container") flags.VarP(&copts.flLabels, "label", "l", "Set meta data on a container")
flags.Var(&copts.flLabelsFile, "label-file", "Read in a line delimited file of labels") flags.Var(&copts.flLabelsFile, "label-file", "Read in a line delimited file of labels")
@ -229,7 +232,6 @@ func AddFlags(flags *pflag.FlagSet) *ContainerOptions {
// a HostConfig and returns them with the specified command. // a HostConfig and returns them with the specified command.
// If the specified args are not valid, it will return an error. // If the specified args are not valid, it will return an error.
func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) { func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
var ( var (
attachStdin = copts.flAttach.Get("stdin") attachStdin = copts.flAttach.Get("stdin")
attachStdout = copts.flAttach.Get("stdout") attachStdout = copts.flAttach.Get("stdout")
@ -575,12 +577,18 @@ func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *c
EndpointsConfig: make(map[string]*networktypes.EndpointSettings), EndpointsConfig: make(map[string]*networktypes.EndpointSettings),
} }
if *copts.flIPv4Address != "" || *copts.flIPv6Address != "" { if *copts.flIPv4Address != "" || *copts.flIPv6Address != "" || copts.flLinkLocalIPs.Len() > 0 {
networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] = &networktypes.EndpointSettings{ epConfig := &networktypes.EndpointSettings{}
IPAMConfig: &networktypes.EndpointIPAMConfig{ networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] = epConfig
IPv4Address: *copts.flIPv4Address,
IPv6Address: *copts.flIPv6Address, epConfig.IPAMConfig = &networktypes.EndpointIPAMConfig{
}, IPv4Address: *copts.flIPv4Address,
IPv6Address: *copts.flIPv6Address,
}
if copts.flLinkLocalIPs.Len() > 0 {
epConfig.IPAMConfig.LinkLocalIPs = make([]string, copts.flLinkLocalIPs.Len())
copy(epConfig.IPAMConfig.LinkLocalIPs, copts.flLinkLocalIPs.GetAll())
} }
} }