From e8bfedd26664974430c8c57ab1427c4f561345cd Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Mon, 8 Apr 2024 09:07:48 +0100 Subject: [PATCH 1/6] Fix TestNetworkConnectWithFlags The test didn't do anything useful... - Despite its name it used newCreateCommand() instead of newConnectCommand() with create flags/options instead of connect. - There was no fake networkCreateFunc(), so the result of the 'connect' wasn't checked. - The fake networkConnectFunc() was never called, so didn't spot the problem. Signed-off-by: Rob Murray --- cli/command/network/connect_test.go | 37 +++++++++++++++++++---------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/cli/command/network/connect_test.go b/cli/command/network/connect_test.go index 9a8b0e6d0d..1ba9d1df5a 100644 --- a/cli/command/network/connect_test.go +++ b/cli/command/network/connect_test.go @@ -43,27 +43,38 @@ func TestNetworkConnectErrors(t *testing.T) { } func TestNetworkConnectWithFlags(t *testing.T) { - expectedOpts := []network.IPAMConfig{ - { - Subnet: "192.168.4.0/24", - IPRange: "192.168.4.0/24", - Gateway: "192.168.4.1/24", - AuxAddress: map[string]string{}, + expectedConfig := &network.EndpointSettings{ + IPAMConfig: &network.EndpointIPAMConfig{ + IPv4Address: "192.168.4.1", + IPv6Address: "fdef:f401:8da0:1234::5678", + LinkLocalIPs: []string{"169.254.42.42"}, + }, + Links: []string{"otherctr"}, + Aliases: []string{"poor-yorick"}, + DriverOpts: map[string]string{ + "adriveropt": "anoptval", }, } cli := test.NewFakeCli(&fakeClient{ networkConnectFunc: func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error { - assert.Check(t, is.DeepEqual(expectedOpts, config.IPAMConfig), "not expected driver error") + assert.Check(t, is.DeepEqual(expectedConfig, config)) return nil }, }) - args := []string{"banana"} - cmd := newCreateCommand(cli) + args := []string{"mynet", "myctr"} + cmd := newConnectCommand(cli) cmd.SetArgs(args) - cmd.Flags().Set("driver", "foo") - cmd.Flags().Set("ip-range", "192.168.4.0/24") - cmd.Flags().Set("gateway", "192.168.4.1/24") - cmd.Flags().Set("subnet", "192.168.4.0/24") + for _, opt := range []struct{ name, value string }{ + {"alias", "poor-yorick"}, + {"driver-opt", "adriveropt=anoptval"}, + {"ip", "192.168.4.1"}, + {"ip6", "fdef:f401:8da0:1234::5678"}, + {"link", "otherctr"}, + {"link-local-ip", "169.254.42.42"}, + } { + err := cmd.Flags().Set(opt.name, opt.value) + assert.Check(t, err) + } assert.NilError(t, cmd.Execute()) } From 4758ed0b0db63622f7e31e8ec8a3e9bf1d1d0d09 Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Mon, 8 Apr 2024 09:16:17 +0100 Subject: [PATCH 2/6] Document the extended '--network' syntax Support for connecting more than one network using the container run command was added in v25.0 for API > 1.44 - describe that in the docs. Signed-off-by: Rob Murray --- docs/reference/commandline/container_run.md | 59 +++++++++++++++------ 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/docs/reference/commandline/container_run.md b/docs/reference/commandline/container_run.md index a18c67fdb5..d7c0c13efb 100644 --- a/docs/reference/commandline/container_run.md +++ b/docs/reference/commandline/container_run.md @@ -714,7 +714,24 @@ For additional information on working with labels, see To start a container and connect it to a network, use the `--network` option. -The following commands create a network named `my-net` and adds a `busybox` container +If you want to add a running container to a network use the `docker network connect` subcommand. + +You can connect multiple containers to the same network. Once connected, the +containers can communicate using only another container's IP address +or name. For `overlay` networks or custom plugins that support multi-host +connectivity, containers connected to the same multi-host network but launched +from different Engines can also communicate in this way. + +> **Note** +> +> The default bridge network only allows containers to communicate with each other using +> internal IP addresses. User-created bridge networks provide DNS resolution between +> containers using container names. + +You can disconnect a container from a network using the `docker network +disconnect` command. + +The following commands create a network named `my-net` and add a `busybox` container to the `my-net` network. ```console @@ -731,24 +748,36 @@ $ docker network create --subnet 192.0.2.0/24 my-net $ docker run -itd --network=my-net --ip=192.0.2.69 busybox ``` -If you want to add a running container to a network use the `docker network connect` subcommand. +To connect the container to more than one network, repeat the `--network` option. -You can connect multiple containers to the same network. Once connected, the -containers can communicate using only another container's IP address -or name. For `overlay` networks or custom plugins that support multi-host -connectivity, containers connected to the same multi-host network but launched -from different Engines can also communicate in this way. +```console +$ docker network create --subnet 192.0.2.0/24 my-net1 +$ docker network create --subnet 192.0.3.0/24 my-net2 +$ docker run -itd --network=my-net1 --network=my-net2 busybox +``` -> **Note** -> -> The default bridge network only allow containers to communicate with each other using -> internal IP addresses. User-created bridge networks provide DNS resolution between -> containers using container names. +To specify options when connecting to more than one network, use the extended syntax +for the `--network` flag. Comma-separated options that can be specified in the extended +`--network` syntax are: -You can disconnect a container from a network using the `docker network -disconnect` command. +| Option | Top-level Equivalent | Description | +|-----------------|---------------------------------------|-------------------------------------------------| +| `name` | | The name of the network (mandatory) | +| `alias` | `--network-alias` | Add network-scoped alias for the container | +| `ip` | `--ip` | IPv4 address (e.g., 172.30.100.104) | +| `ip6` | `--ip6` | IPv6 address (e.g., 2001:db8::33) | +| `mac-address` | `--mac-address` | Container MAC address (e.g., 92:d0:c6:0a:29:33) | +| `link-local-ip` | `--link-local-ip` | Container IPv4/IPv6 link-local addresses | +| `driver-opt` | `docker network connect --driver-opt` | Network driver options | -For more information on connecting a container to a network when using the `run` command, see the ["*Docker network overview*"](https://docs.docker.com/network/). +```console +$ docker network create --subnet 192.0.2.0/24 my-net1 +$ docker network create --subnet 192.0.3.0/24 my-net2 +$ docker run -itd --network=name=my-net1,ip=192.0.2.42 --network=name=my-net2,ip=192.0.3.42 busybox +``` + +For more information on connecting a container to a network when using the `run` command, +see the [Docker network overview](https://docs.docker.com/network/). ### Mount volumes from container (--volumes-from) From 068f118f88bfa96abf1b548b59b7c3c57c0bdbe3 Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Wed, 8 May 2024 14:16:40 +0000 Subject: [PATCH 3/6] Test quoted field in --network Signed-off-by: Rob Murray --- opts/network_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/opts/network_test.go b/opts/network_test.go index 424c5ad045..e44ce3490b 100644 --- a/opts/network_test.go +++ b/opts/network_test.go @@ -98,6 +98,20 @@ func TestNetworkOptAdvancedSyntax(t *testing.T) { }, }, }, + { + value: "name=docknet1,\"driver-opt=com.docker.network.endpoint.sysctls=net.ipv6.conf.IFNAME.accept_ra=2,net.ipv6.conf.IFNAME.forwarding=1\"", + expected: []NetworkAttachmentOpts{ + { + Target: "docknet1", + Aliases: []string{}, + DriverOpts: map[string]string{ + // The CLI converts IFNAME to ifname - it probably shouldn't, but the API + // allows ifname to cater for this. + "com.docker.network.endpoint.sysctls": "net.ipv6.conf.ifname.accept_ra=2,net.ipv6.conf.ifname.forwarding=1", + }, + }, + }, + }, } for _, tc := range testCases { tc := tc From b7583a2c28eb7116eaf4f8e3fc42f9104ce11a97 Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Wed, 8 May 2024 14:26:33 +0000 Subject: [PATCH 4/6] Explain how to use "--network driver-opt" to set sysctls Signed-off-by: Rob Murray --- docs/reference/commandline/container_run.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/reference/commandline/container_run.md b/docs/reference/commandline/container_run.md index d7c0c13efb..123917b6e5 100644 --- a/docs/reference/commandline/container_run.md +++ b/docs/reference/commandline/container_run.md @@ -776,6 +776,26 @@ $ docker network create --subnet 192.0.3.0/24 my-net2 $ docker run -itd --network=name=my-net1,ip=192.0.2.42 --network=name=my-net2,ip=192.0.3.42 busybox ``` +`sysctl` settings that start with `net.ipv4.`, `net.ipv6.` or `net.mpls.` can be +set per-interface using `driver-opt` label `com.docker.network.endpoint.sysctls`. +The interface name must be the string `IFNAME`. + +To set more than one `sysctl` for an interface, quote the whole `driver-opt` field, +remembering to escape the quotes for the shell if necessary. For example, if the +interface to `my-net` is given name `eth0`, the following example sets sysctls +`net.ipv4.conf.eth0.log_martians=1` and `net.ipv4.conf.eth0.forwarding=0`, and +assigns the IPv4 address `192.0.2.42`. + +```console +$ docker network create --subnet 192.0.2.0/24 my-net +$ docker run -itd --network=name=my-net,\"driver-opt=com.docker.network.endpoint.sysctls=net.ipv4.conf.IFNAME.log_martians=1,net.ipv4.conf.IFNAME.forwarding=0\",ip=192.0.2.42 busybox +``` + +> **Note** +> +> Network drivers may restrict the sysctl settings that can be modified and, to protect +> the operation of the network, new restrictions may be added in the future. + For more information on connecting a container to a network when using the `run` command, see the [Docker network overview](https://docs.docker.com/network/). From 7f9dba60e28f1c9150b5df47a25368b7192a5d35 Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Wed, 8 May 2024 15:59:56 +0100 Subject: [PATCH 5/6] Test quoted fields in --driver-opt Signed-off-by: Rob Murray --- cli/command/network/connect_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cli/command/network/connect_test.go b/cli/command/network/connect_test.go index 1ba9d1df5a..89c9b8e607 100644 --- a/cli/command/network/connect_test.go +++ b/cli/command/network/connect_test.go @@ -52,7 +52,8 @@ func TestNetworkConnectWithFlags(t *testing.T) { Links: []string{"otherctr"}, Aliases: []string{"poor-yorick"}, DriverOpts: map[string]string{ - "adriveropt": "anoptval", + "driveropt1": "optval1,optval2", + "driveropt2": "optval4", }, } cli := test.NewFakeCli(&fakeClient{ @@ -67,7 +68,9 @@ func TestNetworkConnectWithFlags(t *testing.T) { cmd.SetArgs(args) for _, opt := range []struct{ name, value string }{ {"alias", "poor-yorick"}, - {"driver-opt", "adriveropt=anoptval"}, + {"driver-opt", "\"driveropt1=optval1,optval2\""}, + {"driver-opt", "driveropt2=optval3"}, + {"driver-opt", "driveropt2=optval4"}, // replaces value {"ip", "192.168.4.1"}, {"ip6", "fdef:f401:8da0:1234::5678"}, {"link", "otherctr"}, From d5d94e46fc01b6c1bffbc2c203dc0f5bcc2d7b1f Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Wed, 8 May 2024 16:01:29 +0100 Subject: [PATCH 6/6] Explain how to use "network connect --driver-opt" to set sysctls Signed-off-by: Rob Murray --- docs/reference/commandline/network_connect.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/reference/commandline/network_connect.md b/docs/reference/commandline/network_connect.md index e2496503c6..b8840eb404 100644 --- a/docs/reference/commandline/network_connect.md +++ b/docs/reference/commandline/network_connect.md @@ -65,6 +65,26 @@ being connected to. $ docker network connect --alias db --alias mysql multi-host-network container2 ``` +### Set sysctls for a container's interface (--driver-opt) + +`sysctl` settings that start with `net.ipv4.` and `net.ipv6.` can be set per-interface +using `--driver-opt` label `com.docker.network.endpoint.sysctls`. The name of the +interface must be replaced by `IFNAME`. + +To set more than one `sysctl` for an interface, quote the whole value of the +`driver-opt` field, remembering to escape the quotes for the shell if necessary. +For example, if the interface to `my-net` is given name `eth3`, the following example +sets `net.ipv4.conf.eth3.log_martians=1` and `net.ipv4.conf.eth3.forwarding=0`. + +```console +$ docker network connect --driver-opt=\"com.docker.network.endpoint.sysctls=net.ipv4.conf.IFNAME.log_martians=1,net.ipv4.conf.IFNAME.forwarding=0\" multi-host-network container2 +``` + +> **Note** +> +> Network drivers may restrict the sysctl settings that can be modified and, to protect +> the operation of the network, new restrictions may be added in the future. + ### Network implications of stopping, pausing, or restarting containers You can pause, restart, and stop containers that are connected to a network.