Creating user-defined networks

As we've seen so far, there are at least two different network drivers that are inherently part of every Docker installation, bridge, and host. In addition to those two, while not defined initially because of prerequisites, there is another Driver overlay that is available out-of-the-box as well. Later recipes in this chapter will cover specifics regarding the bridge and overlay drivers.

Because it wouldn't make sense to create another iteration of the host network using the host Driver, the built-in user-defined networks are limited to the bridge and overlay drivers. In this recipe, we'll show you the basics of creating a user-defined network as well as options that are relevant to the network create and network rm Docker subcommands.

Getting ready

The docker network subcommand was introduced in Docker 1.9, so you'll need a Docker host running at least that version. In our examples, we'll be using Docker version 1.12. You'll also want to have a good understanding of your current network layout, so you can follow along as we inspect the current configuration. It is assumed that each Docker host is in its native configuration.

Note

Warning: Creating network interfaces on a Linux host must be done with caution. Docker will do its best to prevent you from shooting yourself in the foot, but you must have a good idea of your network topology before defining new networks on a Docker host. A common mistake to avoid is to define a new network that overlaps with other subnets in your network. In the case of remote administration, this can cause host and container connectivity issues.

How to do it…

Networks are defined by using the network create subcommand, which has the following options:

user@docker1:~$ docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
--aux-address value    Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
-d, --driver string    Driver to manage the Network (default "bridge")
--gateway value        IPv4 or IPv6 Gateway for the master subnet (default [])
--help                 Print usage
--internal             Restrict external access to the network
--ip-range value       Allocate container ip from a sub-range (default [])
--ipam-driver string   IP Address Management Driver (default "default")
--ipam-opt value       Set IPAM driver specific options (default map[])
--ipv6                 Enable IPv6 networking
--label value          Set metadata on a network (default [])
-o, --opt value        Set driver specific options (default map[])
--subnet value         Subnet in CIDR format that represents a network segment (default [])
user@docker1:~$

Let's spend a little time discussing what each of these options means:

  • aux-address: This allows you to define IP addresses that Docker should not assign to containers when they are spawned. These are the equivalent of IP reservations in a DHCP scope.
  • Driver: Which Driver the network implements. The built-in options include bridge and overlay, but you can also use third-party drivers as well.
  • gateway: The Gateway for the network. If not specified, Docker will assume that it is the first available IP address in the subnet.
  • internal: This option allows you to isolate networks and is covered in greater detail later in this chapter.
  • ip-range: This allows you to specify a smaller subnet of the defined network subnet to use for container addressing.
  • ipam-driver: In addition to consuming third-party network drivers, you can also leverage third-party IPAM drivers. For the purposes of this book, we'll be focusing mostly on the default or built-in IPAM Driver.
  • ipv6: This enables IPv6 networking on the network.
  • label: This allows you to specify additional information about the network that will be stored as metadata.
  • ipam-opt: This allows you to specify options to pass to the IPAM Driver.
  • opt: This allows you to specify options that can be passed to the network Driver. Specific options for each built-in Driver will be discussed in the relevant recipes.
  • subnet: This defines the subnet associated with the network type you are creating.

You might notice some overlap here between some of the settings we can define at a service level for Docker networking and the user-defined options listed in the preceding term list. Examining the options, you may be tempted to compare the following configuration flags:

How to do it…

While these settings are largely equivalent, they are not all identical. The only two that act in the exact same fashion are --fixed-cidr and ip-range. Both of those options, define a smaller subnetwork of the larger master network to be used for container IP addressing. The other two options are similar, but not identical.

In the case of the service options, --bip applies to the docker0 bridge and --default-gateway applies to the containers themselves. On the user-defined side, the --subnet and the --gateway option, apply directly to the network construct being defined (in this comparison, a bridge). Recall that the --bip option expects to receive an IP address in a network, not the network itself. Having the bridge IP defined in this manner covers both the subnet as well as the gateway, which are defined separately when defining a user-defined network. That being said, the service definition is a little more flexible in that it allows you to define both the interface of the bridge as well as the gateway assigned to containers.

Keeping with the theme of having sane defaults, none of these options are actually required to create a user-defined network. You can create your first user-defined network by just giving it a name:

user@docker1:~$ docker network create mynetwork
3fea20c313e8880538ab50fd591398bdfdac2378abac29aacb1be131cbfab40f
user@docker1:~$

Upon inspection, we can see what Docker uses for defaults:

user@docker1:~$ docker network inspect mynetwork
[
    {
        "Name": "mynetwork",
        "Id": "a09b7617c5504d4afd80c26b82587000c64046f1483de604c51fa4ba53463b50",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1/16"
                }
            ]
        },
        "Internal": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
user@docker1:~$

Docker assumes that if you don't specify a Driver that you'd like to create a network using the bridge Driver. It also automatically chooses and assigns a subnet for this bridge if you don't define one when you create the network.

Note

It is always advisable that you specify subnets for network, you create. As we'll see later on, not all network topologies rely on hiding the container networks behind the host interfaces. In those cases, defining a routable non-overlapping subnet will be a necessity.

It also automatically selects the first useable IP address for the Subnet as the gateway. Because we didn't define any options specific to the Driver, the network has none but again, there are defaults that are used in this case. Those will be discussed in the recipes related to each specific Driver.

Networks that are empty, that is, they have no active endpoints, may be deleted using the network rm command:

user@docker1:~$ docker network rm mynetwork
user@docker1:~$

One other item that's worth noting here is that Docker makes user-defined networks persistent. In most cases, any Linux network constructs that are manually defined are lost when the system reboots. Docker records the network configuration and takes care of replaying it back when the Docker service restarts. This is a huge advantage to building the networks through Docker rather than on your own.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset