From 1a6be1a26bb11f9f5103a2783bf70d1b342e22d5 Mon Sep 17 00:00:00 2001 From: David Karlsson Date: Wed, 31 May 2023 15:37:42 +0200 Subject: [PATCH] engine: networking editorial improvements and corrections Signed-off-by: David Karlsson --- config/daemon/ipv6.md | 26 ++++-------- engine/install/debian.md | 6 +-- engine/install/raspbian.md | 6 +-- engine/install/ubuntu.md | 6 +-- network/drivers/bridge.md | 7 +++- network/drivers/index.md | 23 +++++----- network/drivers/none.md | 2 +- network/drivers/overlay.md | 9 ++++ network/index.md | 60 ++++++++++----------------- network/packet-filtering-firewalls.md | 40 +++++++++--------- 10 files changed, 89 insertions(+), 96 deletions(-) diff --git a/config/daemon/ipv6.md b/config/daemon/ipv6.md index 0f76cf489b..5ecb464bb8 100644 --- a/config/daemon/ipv6.md +++ b/config/daemon/ipv6.md @@ -25,22 +25,14 @@ To enable IPv6, you must edit the Docker daemon configuration file located at "experimental": true, "ipv6": true, "ip6tables": true, + "fixed-cidr-v6": "2001:db8:1::/64", ... } ``` -You can optionally also configure the `fixed-cidr-v6` key, if you want to -assign an IPv6 subnet to the default bridge network: - -```diff -{ - "experimental": true, - "ipv6": true, - "ip6tables": true, -+ "fixed-cidr-v6": "2001:db8:1::/64", - ... -} -``` +This configuration makes IPv6 networking function as you would expect it to. +The `ipv6` and `fixed-cidr-v6` parameters are optional. +They assign an IPv6 subnet to the default bridge network. After saving the configuration file, restart the Docker daemon for your changes to take effect: @@ -49,8 +41,8 @@ changes to take effect: $ systemctl restart docker ``` -You can now create networks with the `--ipv6` flag and assign containers IPv6 -addresses using the `--ip6` flag. +Upon restart, the daemon assigns IPv6 addresses to containers connected to the +default bridge network, and to user-defined networks configured with an IPv6 subnet. ## Dynamic IPv6 subnet allocation @@ -79,10 +71,10 @@ The default address pool configuration is: { "base": "172.17.0.0/16", "size": 16 }, { "base": "172.18.0.0/16", "size": 16 }, { "base": "172.19.0.0/16", "size": 16 }, - { "base": "172.20.0.0/16", "size": 16 }, + { "base": "172.20.0.0/14", "size": 16 }, { "base": "172.24.0.0/14", "size": 16 }, { "base": "172.28.0.0/14", "size": 16 }, - { "base": "172.28.0.0/16", "size": 20 } + { "base": "192.168.0.0/16", "size": 20 } ] } ``` @@ -99,7 +91,7 @@ an IPv6 supernet, with a prefix length of 64 and a size of 80. { "base": "172.20.0.0/16", "size": 16 }, { "base": "172.24.0.0/14", "size": 16 }, { "base": "172.28.0.0/14", "size": 16 }, - { "base": "172.28.0.0/16", "size": 20 }, + { "base": "192.168.0.0/16", "size": 20 }, { "base": "2001:db8::/64", "size": 80 } ] } diff --git a/engine/install/debian.md b/engine/install/debian.md index 17bb851679..7816e186d9 100644 --- a/engine/install/debian.md +++ b/engine/install/debian.md @@ -19,9 +19,9 @@ To get started with Docker Engine on Debian, make sure you > **Note** > -> If you use ufw to manage firewall settings, it's important to be aware that -> when you expose container ports using Docker, these ports bypass any -> firewall rules set up with ufw. For more information, refer to +> If you use ufw or firewalld to manage firewall settings, be aware that +> when you expose container ports using Docker, these ports bypass your +> firewall rules. For more information, refer to > [Docker and ufw](../../network/packet-filtering-firewalls.md#docker-and-ufw). ### OS requirements diff --git a/engine/install/raspbian.md b/engine/install/raspbian.md index 176d528979..9ce4f8a348 100644 --- a/engine/install/raspbian.md +++ b/engine/install/raspbian.md @@ -16,9 +16,9 @@ To get started with Docker Engine on Raspbian, make sure you > **Note** > -> If you use ufw to manage firewall settings, it's important to be aware that -> when you expose container ports using Docker, these ports bypass any -> firewall rules set up with ufw. For more information, refer to +> If you use ufw or firewalld to manage firewall settings, be aware that +> when you expose container ports using Docker, these ports bypass your +> firewall rules. For more information, refer to > [Docker and ufw](../../network/packet-filtering-firewalls.md#docker-and-ufw). ### OS requirements diff --git a/engine/install/ubuntu.md b/engine/install/ubuntu.md index be55182a5b..b6a677bfd2 100644 --- a/engine/install/ubuntu.md +++ b/engine/install/ubuntu.md @@ -24,9 +24,9 @@ To get started with Docker Engine on Ubuntu, make sure you > **Note** > -> If you use ufw to manage firewall settings, it's important to be aware that -> when you expose container ports using Docker, these ports bypass any -> firewall rules set up with ufw. For more information, refer to +> If you use ufw or firewalld to manage firewall settings, be aware that +> when you expose container ports using Docker, these ports bypass your +> firewall rules. For more information, refer to > [Docker and ufw](../../network/packet-filtering-firewalls.md#docker-and-ufw). ### OS requirements diff --git a/network/drivers/bridge.md b/network/drivers/bridge.md index 2ae2d31190..d12e52ee56 100644 --- a/network/drivers/bridge.md +++ b/network/drivers/bridge.md @@ -107,7 +107,7 @@ The following table describes the driver-specific options that you can pass to | Option | Default | Description | | ------------------------------------------------ | -------------- | ----------------------------------------------------------- | -| `com.docker.network.bridge.name` | | Bridge name to be used when creating the Linux bridge. | +| `com.docker.network.bridge.name` | | Interface name to use when creating the Linux bridge. | | `com.docker.network.bridge.enable_ip_masquerade` | `true` | Enable IP masquerading. | | `com.docker.network.bridge.enable_icc` | `true` | Enable or Disable inter-container connectivity. | | `com.docker.network.bridge.host_binding_ipv4` | | Default IP when binding container ports. | @@ -252,7 +252,10 @@ user-defined bridges, you can't selectively disable IPv6 on the default bridge. Due to limitations set by the Linux kernel, bridge networks become unstable and inter-container communications may break when 1000 containers or more connect -to a single bridge network. +to a single network. + +For more information about this limitation, see +[moby/moby#44973](https://github.com/moby/moby/issues/44973#issuecomment-1543747718){: target="_blank" rel="noopener"}. ## Next steps diff --git a/network/drivers/index.md b/network/drivers/index.md index 8fd16163da..2f86a8298c 100644 --- a/network/drivers/index.md +++ b/network/drivers/index.md @@ -10,32 +10,35 @@ exist by default, and provide core networking functionality: - `bridge`: The default network driver. If you don't specify a driver, this is the type of network you are creating. Bridge networks are commonly used when your application runs in a container that needs to communicate with other - containers on the same host. See [bridge networks](bridge.md). + containers on the same host. + See [Bridge network driver](bridge.md). -- `host`: For standalone containers, remove network isolation between the - container and the Docker host, and use the host's networking directly. See - [use the host network](host.md). +- `host`: Remove network isolation between the container and the Docker host, + and use the host's networking directly. + See [Host network driver](host.md). - `overlay`: Overlay networks connect multiple Docker daemons together and enable Swarm services and containers to communicate across nodes. This strategy removes the need to do OS-level routing. - See [overlay networks](overlay.md). + See [Overlay network driver](overlay.md). - `ipvlan`: IPvlan networks give users total control over both IPv4 and IPv6 addressing. The VLAN driver builds on top of that in giving operators complete control of layer 2 VLAN tagging and even IPvlan L3 routing for users - interested in underlay network integration. See [IPvlan networks](ipvlan.md). + interested in underlay network integration. + See [IPvlan network driver](ipvlan.md). - `macvlan`: Macvlan networks allow you to assign a MAC address to a container, making it appear as a physical device on your network. The Docker daemon routes traffic to containers by their MAC addresses. Using the `macvlan` driver is sometimes the best choice when dealing with legacy applications that expect to be directly connected to the physical network, rather than routed - through the Docker host's network stack. See - [Macvlan networks](macvlan.md). + through the Docker host's network stack. + See [Macvlan network driver](macvlan.md). -- `none`: For this container, disable all networking. `none` is not available - for Swarm services. See [disable container networking](none.md). +- `none`: Completely isolate a container from the host and other containers. + `none` is not available for Swarm services. + See [None network driver](none.md). - [Network plugins](/engine/extend/plugins_services/): You can install and use third-party network plugins with Docker. diff --git a/network/drivers/none.md b/network/drivers/none.md index 6fdb6c7f7f..23885ee6f4 100644 --- a/network/drivers/none.md +++ b/network/drivers/none.md @@ -10,7 +10,7 @@ If you want to completely disable the networking stack on a container, you can use the `--network none` flag when starting the container. Within the container, only the loopback device is created. -The following example runs shows the output of `ip link show` in an `alpine` +The following example shows the output of `ip link show` in an `alpine` container using the `none` network driver. ```console diff --git a/network/drivers/overlay.md b/network/drivers/overlay.md index ed9dd66fdb..da76963df8 100644 --- a/network/drivers/overlay.md +++ b/network/drivers/overlay.md @@ -285,6 +285,15 @@ routing on the individual Docker daemon hosts. For most situations, you should connect to the service name, which is load-balanced and handled by all containers ("tasks") backing the service. To get a list of all tasks backing the service, do a DNS lookup for `tasks..` +## Connection limit for overlay networks + +Due to limitations set by the Linux kernel, overlay networks become unstable and +inter-container communications may break when 1000 containers are co-located on +the same host. + +For more information about this limitation, see +[moby/moby#44973](https://github.com/moby/moby/issues/44973#issuecomment-1543747718){: target="_blank" rel="noopener"}. + ## Next steps - Go through the [overlay networking tutorial](../network-tutorial-overlay.md) diff --git a/network/index.md b/network/index.md index 49c4d19b33..0f794dd4f8 100644 --- a/network/index.md +++ b/network/index.md @@ -21,9 +21,9 @@ or whether their peers are also Docker workloads or not. A container only sees a network interface with an IP address, a gateway, a routing table, DNS services, and other networking details. That is, unless the container uses the `none` network driver. -This page describes networking from the point of view of the container. -This page also describes the concepts around container networking. +This page describes networking from the point of view of the container, +and the concepts around container networking. This page doesn't describe OS-specific details about how Docker networks work. For information about how Docker manipulates `iptables` rules on Linux, see [Packet filtering and firewalls](packet-filtering-firewalls.md). @@ -32,9 +32,8 @@ see [Packet filtering and firewalls](packet-filtering-firewalls.md). By default, when you create or run a container using `docker create` or `docker run`, the container doesn't expose any of its ports to the outside world. -To make a port available to services outside of Docker, -or to Docker containers running on a different network, -use the `--publish` or `-p` flag. +Use the `--publish` or `-p` flag to make a port available to services +outside of Docker. This creates a firewall rule in the host, mapping a container port to a port on the Docker host to the outside world. Here are some examples: @@ -60,6 +59,11 @@ Here are some examples: > ``` {: .important } +If you want to make a container accessible to other containers, +it isn't necessary to publish the container's ports. +Inter-container communication is enabled by connecting the containers to the +same network, usually a [bridge network](./drivers/bridge.md). + ## IP address and hostname By default, the container gets an IP address for every Docker network it attaches to. @@ -67,15 +71,15 @@ A container receives an IP address out of the IP subnet of the network. The Docker daemon performs dynamic subnetting and IP address allocation for containers. Each network also has a default subnet mask and gateway. +When you connect an existing container to a different network using `docker network connect`, +you can use the `--ip` or `--ip6` flags on that command +to specify the container's IP address on the additional network. + When a container starts, it can only attach to a single network, using the `--network` flag. You can connect a running container to multiple networks using the `docker network connect` command. When you start a container using the `--network` flag, you can specify the IP address for the container on that network using the `--ip` or `--ip6` flags. -When you connect an existing container to a different network using `docker network connect`, -you can use the `--ip` or `--ip6` flags on that command -to specify the container's IP address on the additional network. - In the same way, a container's hostname defaults to be the container's ID in Docker. You can override the hostname using `--hostname`. When connecting to an existing network using `docker network connect`, @@ -92,8 +96,9 @@ use Docker's embedded DNS server. The embedded DNS server forwards external DNS lookups to the DNS servers configured on the host. You can configure DNS resolution on a per-container basis, using flags for the -`docker run` command when you start the container. The following table -describes the available `docker run` flags related to DNS configuration. +`docker run` or `docker create` command used to start the container. +The following table describes the available `docker run` flags related to DNS +configuration. | Flag | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -102,39 +107,20 @@ describes the available `docker run` flags related to DNS configuration. | `--dns-opt` | A key-value pair representing a DNS option and its value. See your operating system's documentation for `resolv.conf` for valid options. | | `--hostname` | The hostname a container uses for itself. Defaults to the container's ID if not specified. | -### Name resolution with multiple nameservers +### Nameservers with IPv6 addresses -When you specify multiple DNS servers using `--dns` flags, name resolution may -work in a surprising or unexpected way. DNS lookup behavior depends on a number -of different factors: +If the `/etc/resolv.conf` file on the host system contains one or more +nameserver entries with an IPv6 address, those nameserver entries get copied +over to `/etc/resolv.conf` in containers that you run. -- Whether the container OS runs on [musl or glibc](https://wiki.musl-libc.org/functional-differences-from-glibc.html#Name_Resolver/DNS){: target="blank" rel="noopener" } -- Whether the Docker daemon binary is [statically or dynamically linked](https://pkg.go.dev/net#hdr-Name_Resolution){: target="blank" rel="noopener" } -- If dynamically linked, which version of glibc that's used -- Whether or not [nsswitch.conf is present](https://tldp.org/LDP/nag2/x-087-2-resolv.library.html#X-087-2-RESOLV.NSSWITCH-CONF){: target="blank" rel="noopener" } - -Under most circumstances, name resolution with multiple nameservers should work -as follows: - -1. The container emits requests to all nameservers that you specify. -2. The container uses the first response returned by any of the nameservers. - Even if the first response is `NXDOMAIN`, or similar. - -### IPv6 name resolution - -The embedded DNS server handles both IPv4 and IPv6 name resolution. However, -there is a caveat in name resolution for IPv6. - -Any IPv6 addresses specified in the `/etc/resolv.conf` file on the host system -get copied over to the `/etc/resolv.conf` file in containers that you run. - -For containers running on musl libc (Alpine Linux), hostname resolution might +For containers using musl libc (in other words, Alpine Linux), this results in +a race condition for hostname lookup. As a result, hostname resolution might sporadically fail if the external IPv6 DNS server wins the race condition against the embedded DNS server. It's rare that the external DNS server is faster than the embedded one. But things like garbage collection, or large numbers of concurrent DNS requests, -can result in a roundtrip to the external server be faster than the local +can result in a roundtrip to the external server being faster than local resolution, on some occasions. ### Custom hosts diff --git a/network/packet-filtering-firewalls.md b/network/packet-filtering-firewalls.md index 17d80270e9..52c68cbfb9 100644 --- a/network/packet-filtering-firewalls.md +++ b/network/packet-filtering-firewalls.md @@ -125,25 +125,24 @@ kernel level, the port gets published on both IPv4 and IPv6. You can change the default binding address for published container ports so that they're only accessible to the Docker host by default. To do that, you can -configure the daemon to use the loopback address (`127.0.0.1`) instead. You -have two options for how to do this: +configure the daemon to use the loopback address (`127.0.0.1`) instead. +To do so, configure the `"ip"` key in the `daemon.json` configuration file: -- Set the `--ip` flag on the `dockerd` CLI when you run the daemon +```json +{ + "ip": "127.0.0.1" +} +``` - ```console - $ dockerd --ip 127.0.0.1 - ``` - -- Configure the `"ip"` key in the `daemon.json` configuration file before startup - - ```json - { - "ip": "127.0.0.1" - } - ``` - -This changes the default binding port to `127.0.0.1` for published container +This changes the default binding address to `127.0.0.1` for published container ports on the default bridge network. +Restart the daemon for this change to take effect. +Alternatively, you can use the `dockerd --ip` flag when starting the daemon. + +> **Note** +> +> Changing the default bind address doesn't have any effect on Swarm services. +> Swarm services are always exposed on the `0.0.0.0` network interface. To configure this setting for user-defined bridge networks, use the `com.docker.network.bridge.host_binding_ipv4` @@ -173,13 +172,14 @@ Restarting `dockerd` daemon inserts the interface into the `docker` zone. ## Docker and ufw -Uncomplicated Firewall (ufw) is a frontend that ships with Debian and Ubuntu, +[Uncomplicated Firewall](https://launchpad.net/ufw){: target="_blank" rel="noopener"} +(ufw) is a frontend that ships with Debian and Ubuntu, and it lets you manage firewall rules. Docker and ufw use iptables in ways that make them incompatible with each other. When you publish a container's ports using Docker, traffic to and from that container gets diverted before it goes through the ufw firewall settings. Docker routes container traffic in the `nat` table, which means that packets -are diverted before it reaches the `filter` table that ufw uses. Packets are -routed before the firewall rules can be applied, effectively ignoring your -firewall configuration. +are diverted before it reaches the `INPUT` and `OUTPUT` chains that ufw uses. +Packets are routed before the firewall rules can be applied, +effectively ignoring your firewall configuration.