mirror of https://github.com/docker/docs.git
commit
47d87d3b92
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
|
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"github.com/docker/engine-api/types/filters"
|
"github.com/docker/engine-api/types/filters"
|
||||||
"github.com/docker/engine-api/types/network"
|
"github.com/docker/engine-api/types/network"
|
||||||
|
@ -112,6 +113,8 @@ func (cli *DockerCli) CmdNetworkConnect(args ...string) error {
|
||||||
cmd := Cli.Subcmd("network connect", []string{"NETWORK CONTAINER"}, "Connects a container to a network", false)
|
cmd := Cli.Subcmd("network connect", []string{"NETWORK CONTAINER"}, "Connects a container to a network", false)
|
||||||
flIPAddress := cmd.String([]string{"-ip"}, "", "IP Address")
|
flIPAddress := cmd.String([]string{"-ip"}, "", "IP Address")
|
||||||
flIPv6Address := cmd.String([]string{"-ip6"}, "", "IPv6 Address")
|
flIPv6Address := cmd.String([]string{"-ip6"}, "", "IPv6 Address")
|
||||||
|
flLinks := opts.NewListOpts(runconfigopts.ValidateLink)
|
||||||
|
cmd.Var(&flLinks, []string{"-link"}, "Add link to another container")
|
||||||
cmd.Require(flag.Min, 2)
|
cmd.Require(flag.Min, 2)
|
||||||
if err := cmd.ParseFlags(args, true); err != nil {
|
if err := cmd.ParseFlags(args, true); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -121,6 +124,7 @@ func (cli *DockerCli) CmdNetworkConnect(args ...string) error {
|
||||||
IPv4Address: *flIPAddress,
|
IPv4Address: *flIPAddress,
|
||||||
IPv6Address: *flIPv6Address,
|
IPv6Address: *flIPv6Address,
|
||||||
},
|
},
|
||||||
|
Links: flLinks.GetAll(),
|
||||||
}
|
}
|
||||||
return cli.client.NetworkConnect(cmd.Arg(0), cmd.Arg(1), epConfig)
|
return cli.client.NetworkConnect(cmd.Arg(0), cmd.Arg(1), epConfig)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/chrootarchive"
|
"github.com/docker/docker/pkg/chrootarchive"
|
||||||
"github.com/docker/docker/pkg/symlink"
|
"github.com/docker/docker/pkg/symlink"
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
|
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
"github.com/docker/docker/volume"
|
"github.com/docker/docker/volume"
|
||||||
"github.com/docker/engine-api/types/container"
|
"github.com/docker/engine-api/types/container"
|
||||||
|
@ -247,6 +248,21 @@ func (container *Container) UpdateSandboxNetworkSettings(sb libnetwork.Sandbox)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildJoinOptions builds endpoint Join options from a given network.
|
||||||
|
func (container *Container) BuildJoinOptions(n libnetwork.Network) ([]libnetwork.EndpointOption, error) {
|
||||||
|
var joinOptions []libnetwork.EndpointOption
|
||||||
|
if epConfig, ok := container.NetworkSettings.Networks[n.Name()]; ok {
|
||||||
|
for _, str := range epConfig.Links {
|
||||||
|
name, alias, err := runconfigopts.ParseLink(str)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
joinOptions = append(joinOptions, libnetwork.CreateOptionAlias(name, alias))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return joinOptions, nil
|
||||||
|
}
|
||||||
|
|
||||||
// BuildCreateEndpointOptions builds endpoint options from a given network.
|
// BuildCreateEndpointOptions builds endpoint options from a given network.
|
||||||
func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network) ([]libnetwork.EndpointOption, error) {
|
func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network) ([]libnetwork.EndpointOption, error) {
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -586,7 +586,7 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai
|
||||||
if container.NetworkSettings == nil {
|
if container.NetworkSettings == nil {
|
||||||
container.NetworkSettings = &network.Settings{}
|
container.NetworkSettings = &network.Settings{}
|
||||||
}
|
}
|
||||||
if endpointsConfig != nil {
|
if len(endpointsConfig) > 0 {
|
||||||
container.NetworkSettings.Networks = endpointsConfig
|
container.NetworkSettings.Networks = endpointsConfig
|
||||||
}
|
}
|
||||||
if container.NetworkSettings.Networks == nil {
|
if container.NetworkSettings.Networks == nil {
|
||||||
|
@ -816,7 +816,12 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName
|
||||||
container.UpdateSandboxNetworkSettings(sb)
|
container.UpdateSandboxNetworkSettings(sb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ep.Join(sb); err != nil {
|
joinOptions, err := container.BuildJoinOptions(n)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ep.Join(sb, joinOptions...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -868,7 +868,7 @@ func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error
|
||||||
|
|
||||||
// registerLinks writes the links to a file.
|
// registerLinks writes the links to a file.
|
||||||
func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error {
|
func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error {
|
||||||
if hostConfig == nil {
|
if hostConfig == nil || hostConfig.NetworkMode.IsUserDefined() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@ parent = "smn_cli"
|
||||||
Connects a container to a network
|
Connects a container to a network
|
||||||
|
|
||||||
--help Print usage
|
--help Print usage
|
||||||
|
--ip IP Address
|
||||||
|
--ip6 IPv6 Address
|
||||||
|
--link=[] Add a link to another container
|
||||||
|
|
||||||
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
|
||||||
|
@ -33,7 +36,13 @@ $ docker run -itd --net=multi-host-network busybox
|
||||||
You can specify the IP address you want to be assigned to the container's interface.
|
You can specify the IP address you want to be assigned to the container's interface.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker network connect multi-host-network --ip 10.10.36.122 container2
|
$ docker network connect --ip 10.10.36.122 multi-host-network container2
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use `--link` option to link another container with a prefered alias
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network connect --link container1:c1 multi-host-network container2
|
||||||
```
|
```
|
||||||
|
|
||||||
You can pause, restart, and stop containers that are connected to a network.
|
You can pause, restart, and stop containers that are connected to a network.
|
||||||
|
@ -60,3 +69,4 @@ You can connect a container to one or more networks. The networks need not be th
|
||||||
* [network ls](network_ls.md)
|
* [network ls](network_ls.md)
|
||||||
* [network rm](network_rm.md)
|
* [network rm](network_rm.md)
|
||||||
* [Understand Docker container networks](../../userguide/networking/dockernetworks.md)
|
* [Understand Docker container networks](../../userguide/networking/dockernetworks.md)
|
||||||
|
* [Work with networks](../../userguide/networking/work-with-networks.md)
|
||||||
|
|
|
@ -1301,12 +1301,12 @@ specifies `EXPOSE 80` in the Dockerfile). At runtime, the port might be
|
||||||
bound to 42800 on the host. To find the mapping between the host ports
|
bound to 42800 on the host. To find the mapping between the host ports
|
||||||
and the exposed ports, use `docker port`.
|
and the exposed ports, use `docker port`.
|
||||||
|
|
||||||
If the operator uses `--link` when starting a new client container, then the
|
If the operator uses `--link` when starting a new client container in the
|
||||||
client container can access the exposed port via a private networking interface.
|
default bridge network, then the client container can access the exposed
|
||||||
Linking is a legacy feature that is only supported on the default bridge
|
port via a private networking interface.
|
||||||
network. You should prefer the Docker networks feature instead. For more
|
If `--link` is used when starting a container in a user-defined network as
|
||||||
information on this feature, see the [*Docker network
|
described in [*Docker network overview*""](../userguide/networking/index.md)),
|
||||||
overview*""](../userguide/networking/index.md)).
|
it will provide a named alias for the container being linked to.
|
||||||
|
|
||||||
### ENV (environment variables)
|
### ENV (environment variables)
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,11 @@ Before the [Docker networks feature](../dockernetworks.md), you could use the
|
||||||
Docker link feature to allow containers to discover each other and securely
|
Docker link feature to allow containers to discover each other and securely
|
||||||
transfer information about one container to another container. With the
|
transfer information about one container to another container. With the
|
||||||
introduction of the Docker networks feature, you can still create links but they
|
introduction of the Docker networks feature, you can still create links but they
|
||||||
are only supported on the default `bridge` network named `bridge` and appearing
|
behave differently between default `bridge` network and
|
||||||
in your network stack as `docker0`.
|
[user defined networks](../work-with-networks.md#linking-containers-in-user-defined-networks)
|
||||||
|
|
||||||
This section briefly discusses connecting via a network port and then goes into
|
This section briefly discusses connecting via a network port and then goes into
|
||||||
detail on container linking. While links are still supported on Docker's default
|
detail on container linking in default `bridge` network.
|
||||||
network (`bridge`), you should avoid them in preference of the Docker
|
|
||||||
networks feature. Linking is expected to be deprecated and removed in a future
|
|
||||||
release.
|
|
||||||
|
|
||||||
## Connect using network port mapping
|
## Connect using network port mapping
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,7 @@ PING container3 (172.25.3.3): 56 data bytes
|
||||||
round-trip min/avg/max = 0.070/0.081/0.097 ms
|
round-trip min/avg/max = 0.070/0.081/0.097 ms
|
||||||
```
|
```
|
||||||
|
|
||||||
This isn't the case for the default bridge network. Both `container2` and `container1` are connected to the default bridge network. Docker does not support automatic service discovery on this network. For this reason, pinging `container1` by name fails as you would expect based on the `/etc/hosts` file:
|
This isn't the case for the default `bridge` network. Both `container2` and `container1` are connected to the default bridge network. Docker does not support automatic service discovery on this network. For this reason, pinging `container1` by name fails as you would expect based on the `/etc/hosts` file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/ # ping -w 4 container1
|
/ # ping -w 4 container1
|
||||||
|
@ -314,6 +314,192 @@ PING 172.17.0.2 (172.17.0.2): 56 data bytes
|
||||||
You can connect both running and non-running containers to a network. However,
|
You can connect both running and non-running containers to a network. However,
|
||||||
`docker network inspect` only displays information on running containers.
|
`docker network inspect` only displays information on running containers.
|
||||||
|
|
||||||
|
### Linking containers in user-defined networks
|
||||||
|
|
||||||
|
In the above example, container_2 was able to resolve container_3's name automatically
|
||||||
|
in the user defined network `isolated_nw`, but the name resolution did not succeed
|
||||||
|
automatically in the default `bridge` network. This is expected in order to maintain
|
||||||
|
backward compatibility with [legacy link](default_network/dockerlinks.md).
|
||||||
|
|
||||||
|
The `legacy link` provided 4 major functionalities to the default `bridge` network.
|
||||||
|
|
||||||
|
* name resolution
|
||||||
|
* name alias for the linked container using `--link=CONTAINER-NAME:ALIAS`
|
||||||
|
* secured container connectivity (in isolation via `--icc=false`)
|
||||||
|
* environment variable injection
|
||||||
|
|
||||||
|
Comparing the above 4 functionalities with the non-default user-defined networks such as
|
||||||
|
`isolated_nw` in this example, without any additional config, `docker network` provides
|
||||||
|
|
||||||
|
* automatic name resolution using DNS
|
||||||
|
* automatic secured isolated environment for the containers in a network
|
||||||
|
* ability to dynamically attach and detach to multiple networks
|
||||||
|
* supports the `--link` option to provide name alias for the linked container
|
||||||
|
|
||||||
|
Continuing with the above example, create another container `container_4` in `isolated_nw`
|
||||||
|
with `--link` to provide additional name resolution using alias for other containers in
|
||||||
|
the same network.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker run --net=isolated_nw -itd --name=container4 --link container5:c5 busybox
|
||||||
|
01b5df970834b77a9eadbaff39051f237957bd35c4c56f11193e0594cfd5117c
|
||||||
|
```
|
||||||
|
|
||||||
|
With the help of `--link` container4 will be able to reach container5 using the
|
||||||
|
aliased name `c5` as well.
|
||||||
|
|
||||||
|
Please note that while creating container4, we linked to a container named `container5`
|
||||||
|
which is not created yet. That is one of the differences in behavior between the
|
||||||
|
`legacy link` in default `bridge` network and the new `link` functionality in user defined
|
||||||
|
networks. The `legacy link` is static in nature and it hard-binds the container with the
|
||||||
|
alias and it doesnt tolerate linked container restarts. While the new `link` functionality
|
||||||
|
in user defined networks are dynamic in nature and supports linked container restarts
|
||||||
|
including tolerating ip-address changes on the linked container.
|
||||||
|
|
||||||
|
Now let us launch another container named `container5` linking container4 to c4.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker run --net=isolated_nw -itd --name=container5 --link container4:c4 busybox
|
||||||
|
72eccf2208336f31e9e33ba327734125af00d1e1d2657878e2ee8154fbb23c7a
|
||||||
|
```
|
||||||
|
|
||||||
|
As expected, container4 will be able to reach container5 by both its container name and
|
||||||
|
its alias c5 and container5 will be able to reach container4 by its container name and
|
||||||
|
its alias c4.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker attach container4
|
||||||
|
/ # ping -w 4 c5
|
||||||
|
PING c5 (172.25.0.5): 56 data bytes
|
||||||
|
64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms
|
||||||
|
|
||||||
|
--- c5 ping statistics ---
|
||||||
|
4 packets transmitted, 4 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.070/0.081/0.097 ms
|
||||||
|
|
||||||
|
/ # ping -w 4 container5
|
||||||
|
PING container5 (172.25.0.5): 56 data bytes
|
||||||
|
64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms
|
||||||
|
|
||||||
|
--- container5 ping statistics ---
|
||||||
|
4 packets transmitted, 4 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.070/0.081/0.097 ms
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker attach container5
|
||||||
|
/ # ping -w 4 c4
|
||||||
|
PING c4 (172.25.0.4): 56 data bytes
|
||||||
|
64 bytes from 172.25.0.4: seq=0 ttl=64 time=0.065 ms
|
||||||
|
64 bytes from 172.25.0.4: seq=1 ttl=64 time=0.070 ms
|
||||||
|
64 bytes from 172.25.0.4: seq=2 ttl=64 time=0.067 ms
|
||||||
|
64 bytes from 172.25.0.4: seq=3 ttl=64 time=0.082 ms
|
||||||
|
|
||||||
|
--- c4 ping statistics ---
|
||||||
|
4 packets transmitted, 4 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.065/0.070/0.082 ms
|
||||||
|
|
||||||
|
/ # ping -w 4 container4
|
||||||
|
PING container4 (172.25.0.4): 56 data bytes
|
||||||
|
64 bytes from 172.25.0.4: seq=0 ttl=64 time=0.065 ms
|
||||||
|
64 bytes from 172.25.0.4: seq=1 ttl=64 time=0.070 ms
|
||||||
|
64 bytes from 172.25.0.4: seq=2 ttl=64 time=0.067 ms
|
||||||
|
64 bytes from 172.25.0.4: seq=3 ttl=64 time=0.082 ms
|
||||||
|
|
||||||
|
--- container4 ping statistics ---
|
||||||
|
4 packets transmitted, 4 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.065/0.070/0.082 ms
|
||||||
|
```
|
||||||
|
|
||||||
|
Similar to the legacy link functionality the new link alias is localized to a container
|
||||||
|
and the aliased name has no meaning outside of the container using the `--link`.
|
||||||
|
|
||||||
|
Also, it is important to note that if a container belongs to multiple networks, the
|
||||||
|
linked alias is scoped within a given network. Hence the containers can be linked to
|
||||||
|
different aliases in different networks.
|
||||||
|
|
||||||
|
Extending the example, let us create another network named `local_alias`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network create -d bridge --subnet 172.26.0.0/24 local_alias
|
||||||
|
76b7dc932e037589e6553f59f76008e5b76fa069638cd39776b890607f567aaa
|
||||||
|
```
|
||||||
|
|
||||||
|
let us connect container4 and container5 to the new network `local_alias`
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker network connect --link container5:foo local_alias container4
|
||||||
|
$ docker network connect --link container4:bar local_alias container5
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker attach container4
|
||||||
|
|
||||||
|
/ # ping -w 4 foo
|
||||||
|
PING foo (172.26.0.3): 56 data bytes
|
||||||
|
64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.070 ms
|
||||||
|
64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.097 ms
|
||||||
|
|
||||||
|
--- foo ping statistics ---
|
||||||
|
4 packets transmitted, 4 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.070/0.081/0.097 ms
|
||||||
|
|
||||||
|
/ # ping -w 4 c5
|
||||||
|
PING c5 (172.25.0.5): 56 data bytes
|
||||||
|
64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms
|
||||||
|
|
||||||
|
--- c5 ping statistics ---
|
||||||
|
4 packets transmitted, 4 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.070/0.081/0.097 ms
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the ping succeeds for both the aliases but on different networks.
|
||||||
|
Let us conclude this section by disconnecting container5 from the `isolated_nw`
|
||||||
|
and observe the results
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker network disconnect isolated_nw container5
|
||||||
|
|
||||||
|
$ docker attach container4
|
||||||
|
|
||||||
|
/ # ping -w 4 c5
|
||||||
|
ping: bad address 'c5'
|
||||||
|
|
||||||
|
/ # ping -w 4 foo
|
||||||
|
PING foo (172.26.0.3): 56 data bytes
|
||||||
|
64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.070 ms
|
||||||
|
64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.080 ms
|
||||||
|
64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.097 ms
|
||||||
|
|
||||||
|
--- foo ping statistics ---
|
||||||
|
4 packets transmitted, 4 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.070/0.081/0.097 ms
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
In conclusion, the new link functionality in user defined networks provides all the
|
||||||
|
benefits of legacy links while avoiding most of the well-known issues with `legacy links`.
|
||||||
|
|
||||||
|
One notable missing functionality compared to `legacy links` is the injection of
|
||||||
|
environment variables. Though very useful, environment variable injection is static
|
||||||
|
in nature and must be injected when the container is started. One cannot inject
|
||||||
|
environment variables into a running container without significant effort and hence
|
||||||
|
it is not compatible with `docker network` which provides a dynamic way to connect/
|
||||||
|
disconnect containers to/from a network.
|
||||||
|
|
||||||
|
|
||||||
## Disconnecting containers
|
## Disconnecting containers
|
||||||
|
|
||||||
You can disconnect a container from a network using the `docker network
|
You can disconnect a container from a network using the `docker network
|
||||||
|
|
|
@ -1040,3 +1040,44 @@ func verifyIPAddresses(c *check.C, cName, nwname, ipv4, ipv6 string) {
|
||||||
out, _ = dockerCmd(c, "inspect", fmt.Sprintf("--format='{{ .NetworkSettings.Networks.%s.GlobalIPv6Address }}'", nwname), cName)
|
out, _ = dockerCmd(c, "inspect", fmt.Sprintf("--format='{{ .NetworkSettings.Networks.%s.GlobalIPv6Address }}'", nwname), cName)
|
||||||
c.Assert(strings.TrimSpace(out), check.Equals, ipv6)
|
c.Assert(strings.TrimSpace(out), check.Equals, ipv6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestUserDefinedNetworkConnectDisconnectLink(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||||
|
dockerCmd(c, "network", "create", "-d", "bridge", "foo1")
|
||||||
|
dockerCmd(c, "network", "create", "-d", "bridge", "foo2")
|
||||||
|
|
||||||
|
dockerCmd(c, "run", "-d", "--net=foo1", "--name=first", "busybox", "top")
|
||||||
|
c.Assert(waitRun("first"), check.IsNil)
|
||||||
|
|
||||||
|
// run a container in user-defined network udlinkNet with a link for an existing container
|
||||||
|
// and a link for a container that doesnt exist
|
||||||
|
dockerCmd(c, "run", "-d", "--net=foo1", "--name=second", "--link=first:FirstInFoo1",
|
||||||
|
"--link=third:bar", "busybox", "top")
|
||||||
|
c.Assert(waitRun("second"), check.IsNil)
|
||||||
|
|
||||||
|
// ping to first and its alias FirstInFoo1 must succeed
|
||||||
|
_, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "FirstInFoo1")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
// connect first container to foo2 network
|
||||||
|
dockerCmd(c, "network", "connect", "foo2", "first")
|
||||||
|
// connect second container to foo2 network with a different alias for first container
|
||||||
|
dockerCmd(c, "network", "connect", "--link=first:FirstInFoo2", "foo2", "second")
|
||||||
|
|
||||||
|
// ping the new alias in network foo2
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "FirstInFoo2")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
// disconnect first container from foo1 network
|
||||||
|
dockerCmd(c, "network", "disconnect", "foo1", "first")
|
||||||
|
|
||||||
|
// link in foo1 network must fail
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "FirstInFoo1")
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
|
||||||
|
// link in foo2 network must succeed
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "FirstInFoo2")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
}
|
||||||
|
|
|
@ -199,6 +199,80 @@ func (s *DockerSuite) TestRunLinksContainerWithContainerId(c *check.C) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestUserDefinedNetworkLinks(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||||
|
dockerCmd(c, "network", "create", "-d", "bridge", "udlinkNet")
|
||||||
|
|
||||||
|
dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=first", "busybox", "top")
|
||||||
|
c.Assert(waitRun("first"), check.IsNil)
|
||||||
|
|
||||||
|
// run a container in user-defined network udlinkNet with a link for an existing container
|
||||||
|
// and a link for a container that doesnt exist
|
||||||
|
dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=second", "--link=first:foo",
|
||||||
|
"--link=third:bar", "busybox", "top")
|
||||||
|
c.Assert(waitRun("second"), check.IsNil)
|
||||||
|
|
||||||
|
// ping to first and its alias foo must succeed
|
||||||
|
_, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
// ping to third and its alias must fail
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "third")
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "bar")
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
|
||||||
|
// start third container now
|
||||||
|
dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=third", "busybox", "top")
|
||||||
|
c.Assert(waitRun("third"), check.IsNil)
|
||||||
|
|
||||||
|
// ping to third and its alias must succeed now
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "third")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "bar")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestUserDefinedNetworkLinksWithRestart(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||||
|
dockerCmd(c, "network", "create", "-d", "bridge", "udlinkNet")
|
||||||
|
|
||||||
|
dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=first", "busybox", "top")
|
||||||
|
c.Assert(waitRun("first"), check.IsNil)
|
||||||
|
|
||||||
|
dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=second", "--link=first:foo",
|
||||||
|
"busybox", "top")
|
||||||
|
c.Assert(waitRun("second"), check.IsNil)
|
||||||
|
|
||||||
|
// ping to first and its alias foo must succeed
|
||||||
|
_, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
// Restart first container
|
||||||
|
dockerCmd(c, "restart", "first")
|
||||||
|
c.Assert(waitRun("first"), check.IsNil)
|
||||||
|
|
||||||
|
// ping to first and its alias foo must still succeed
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
// Restart second container
|
||||||
|
dockerCmd(c, "restart", "second")
|
||||||
|
c.Assert(waitRun("second"), check.IsNil)
|
||||||
|
|
||||||
|
// ping to first and its alias foo must still succeed
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
// Issue 9677.
|
// Issue 9677.
|
||||||
func (s *DockerSuite) TestRunWithDaemonFlags(c *check.C) {
|
func (s *DockerSuite) TestRunWithDaemonFlags(c *check.C) {
|
||||||
out, _, err := dockerCmdWithError("--exec-opt", "foo=bar", "run", "-i", "busybox", "true")
|
out, _, err := dockerCmdWithError("--exec-opt", "foo=bar", "run", "-i", "busybox", "true")
|
||||||
|
|
|
@ -48,10 +48,6 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
|
||||||
return ErrConflictContainerNetworkAndLinks
|
return ErrConflictContainerNetworkAndLinks
|
||||||
}
|
}
|
||||||
|
|
||||||
if hc.NetworkMode.IsUserDefined() && len(hc.Links) > 0 {
|
|
||||||
return ErrConflictUserDefinedNetworkAndLinks
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hc.NetworkMode.IsHost() || hc.NetworkMode.IsContainer()) && len(hc.DNS) > 0 {
|
if (hc.NetworkMode.IsHost() || hc.NetworkMode.IsContainer()) && len(hc.DNS) > 0 {
|
||||||
return ErrConflictNetworkAndDNS
|
return ErrConflictNetworkAndDNS
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,11 +417,11 @@ func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.Host
|
||||||
config.StdinOnce = true
|
config.StdinOnce = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var networkingConfig *networktypes.NetworkingConfig
|
networkingConfig := &networktypes.NetworkingConfig{
|
||||||
|
EndpointsConfig: make(map[string]*networktypes.EndpointSettings),
|
||||||
|
}
|
||||||
|
|
||||||
if *flIPv4Address != "" || *flIPv6Address != "" {
|
if *flIPv4Address != "" || *flIPv6Address != "" {
|
||||||
networkingConfig = &networktypes.NetworkingConfig{
|
|
||||||
EndpointsConfig: make(map[string]*networktypes.EndpointSettings),
|
|
||||||
}
|
|
||||||
networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] = &networktypes.EndpointSettings{
|
networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] = &networktypes.EndpointSettings{
|
||||||
IPAMConfig: &networktypes.EndpointIPAMConfig{
|
IPAMConfig: &networktypes.EndpointIPAMConfig{
|
||||||
IPv4Address: *flIPv4Address,
|
IPv4Address: *flIPv4Address,
|
||||||
|
@ -430,6 +430,16 @@ func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.Host
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if hostConfig.NetworkMode.IsUserDefined() && len(hostConfig.Links) > 0 {
|
||||||
|
epConfig := networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)]
|
||||||
|
if epConfig == nil {
|
||||||
|
epConfig = &networktypes.EndpointSettings{}
|
||||||
|
}
|
||||||
|
epConfig.Links = make([]string, len(hostConfig.Links))
|
||||||
|
copy(epConfig.Links, hostConfig.Links)
|
||||||
|
networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] = epConfig
|
||||||
|
}
|
||||||
|
|
||||||
return config, hostConfig, networkingConfig, cmd, nil
|
return config, hostConfig, networkingConfig, cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue