The following parameters are global options that are set via $DOCKER_OPTS variable typically in the file /etc/default/docker
. Once you start the Docker daemon, if you want to modify any of those parameters it requires a restart of the daemon:
-b BRIDGE or --bridge=BRIDGE
--bip=CIDR
--fixed-cidr
--fixed-cidr-v6
-H SOCKET... or --host=SOCKET...
--icc=true|false
--ip=IP_ADDRESS
--ipv6=true|false
--ip-forward=true|false
--iptables=true|false
--mtu=BYTES
There are two networking options that can be supplied either at startup or when docker run is executed. If set in the Docker configuration /etc/default/docker
it is now a global option rather then a per-container configuration.
--dns=IP_ADDRESS...
--dns-search=DOMAIN...
Lastly the following are per-container configurations only when docker run
is invoked.
-h HOSTNAME or --hostname=HOSTNAME
--link=CONTAINER_NAME_or_ID:ALIAS
--net=bridge|none|container:NAME_or_ID|host
--mac-address=MACADDRESS...
-p SPEC or --publish=SPEC
-P or --publish-all=true|false
-b BRIDGE , --bridge = BRIDGE
--bip = CIDR
Note: If your Docker Host OS is using SysV init rather then Systemd replace the systemctl
commands with service
. More on that holy war here
systemctl start docker
# Failed to start docker.service: Unit docker.service is masked.
systemctl unmask docker
# Removed symlink /etc/systemd/system/docker.service.
systemctl unmask docker
# Removed symlink /etc/systemd/system/docker.service.
systemctl start docker
# root@deb-143:/home/brent# ps -eaf | grep dock
# root 5176 1 0 00:40 ? 00:00:00 /usr/bin/docker -d -p /var/run/docker.pid
systemctl stop docker
ip link set dev docker0 down
brctl delbr docker0
iptables -t nat -F POSTROUTING
At this point you don't have the docker0 default bridge anymore
brctl show
# bridge name bridge id STP enabled interfaces
Next setup a custom network bridge:
# Create our own bridge
brctl addbr bridge0
ip addr add 192.168.5.1/24 dev bridge0
ip link set dev bridge0 up
# View the Layer 2 portion of the new bridge
brctl show
# (output)
# bridge name bridge id STP enabled interfaces
# bridge0 8000.000000000000 no
# Confirming that our bridge is up and running
ip addr show bridge0
# (output)
# 32: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
# link/ether 0a:6d:18:0c:e9:00 brd ff:ff:ff:ff:ff:ff
# inet 192.168.5.1/24 scope global bridge0
# valid_lft forever preferred_lft forever
# inet6 fe80::86d:18ff:fe0c:e900/64 scope link
# valid_lft forever preferred_lft forever
# Tell Docker about it and restart (on Ubuntu)
#
# This adds lines to the file /etc/default/docker that
# makes the configuration persistent in between reboots.
# e.g. 'copy run start' || 'write mem' for netops folks
#
# Once you changed the file, start the docker service
# back up using the systemd client command (systemctl)
echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/default/docker
# Start the docker daemon back up
systemctl start docker
# Confirming new outgoing NAT masquerade is set up
iptables -t nat -L -n
# ...
# Chain POSTROUTING (policy ACCEPT)
# target prot opt source destination
# MASQUERADE all -- 192.168.5.0/24 0.0.0.0/0
Notice now when you look at the docker proc. It references the bridge OPT modification:
ps -eaf | grep dock
# root 1201 1 0 02:10 ? 00:00:00 /usr/bin/docker -d -H fd:// -b=bridge0
Next lets start a host:
# In the container, get the output of the 'ip address' command and look for the eth0 address.
ip addr
#1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
# link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# inet 127.0.0.1/8 scope host lo
# valid_lft forever preferred_lft forever
# inet6 ::1/128 scope host
# valid_lft forever preferred_lft forever
#34: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
# link/ether 02:42:0a:06:d4:2a brd ff:ff:ff:ff:ff:ff
# inet 172.17.0.1/16 scope global eth0
# valid_lft forever preferred_lft forever
# inet6 fe80::42:aff:fe06:d42a/64 scope link
# valid_lft forever preferred_lft forever
# or you can save some output and hotkey this:
ip -4 -o addr show dev eth0 |awk '{split($4,a,"/") ;print a[1]}'
# (output)
# 172.17.0.1
Lets run a container now.
As pointed out earlier, the default bridge to use is specified in the configuration file that the docker daemon reads DOCKER_OPTS from, not passed from the docker run
command.
For example, run docker run -it --rm ubuntu echo hello worlds
will execute echo hello worlds
in the new container and exit deleting the container in the process. Note, the --rm
parameter which means the container will be removed after the process it is asked to run completes. In this case it was the echo
command (echo hello worlds
).
docker ps
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 7ac0d1c11dbe ubuntu "/bin/bash" About a minute ago Up About a minute focused_bardeen
docker inspect 7ac0d1c11dbe
#[
#{
# "Id": "7ac0d1c11dbe8a98ec1f596bb9bde7799768fd18685a121f2263f07c48b6d669",
# "Created": "2015-05-16T22:43:59.779306509Z",
# "Path": "/bin/bash",
# "Args": [],
# "Config": {
# "Hostname": "7ac0d1c11dbe",
# "Domainname": "",
# "User": "",
# "AttachStdin": true,
# "AttachStdout": true,
# "AttachStderr": true,
# "PortSpecs": null,
# "ExposedPorts": null,
# "Tty": true,
# "OpenStdin": true,
# "StdinOnce": true,
# "Env": null,
# "Cmd": [
# "/bin/bash"
# ],
# "Image": "ubuntu",
# "Volumes": null,
# "WorkingDir": "",
# "Entrypoint": null,
# "NetworkDisabled": false,
# "MacAddress": "",
# "OnBuild": null,
# "Labels": {}
# },
# "State": {
# "Running": true,
# "Paused": false,
# "Restarting": false,
# "OOMKilled": false,
# "Dead": false,
# "Pid": 10441,
# "ExitCode": 0,
# "Error": "",
# "StartedAt": "2015-05-16T22:44:00.203181126Z",
# "FinishedAt": "0001-01-01T00:00:00Z"
# },
# "Image": "07f8e8c5e66084bef8f848877857537ffe1c47edd01a93af27e7161672ad0e95",
# "NetworkSettings": {
# "Bridge": "bridge0",
# "Gateway": "192.168.5.1",
# "GlobalIPv6Address": "",
# "GlobalIPv6PrefixLen": 0,
# "IPAddress": "192.168.5.2",
# "IPPrefixLen": 24,
# "IPv6Gateway": "",
# "LinkLocalIPv6Address": "",
# "LinkLocalIPv6PrefixLen": 0,
# "MacAddress": "02:42:4f:2f:45:57",
# "PortMapping": null,
# "Ports": {},
# "SecondaryIPAddresses": null,
# "SecondaryIPv6Addresses": null,
# "SandboxKey": "/var/run/netns/7ac0d1c11dbe",
# "NetworkID": "30b2ea4e443226a426b1618ceb954c30dcae9f0df88ba5da942033b0678a8793",
# "EndpointID": "384038aa3baed05d2da4f1f1e2eea68b3b4d3d753604e193826a2271bd86c636",
# "HairpinMode": false
# },
# "ResolvConfPath": "/var/lib/docker/containers/7ac0d1c11dbe8a98ec1f596bb9bde7799768fd18685a121f2263f07c48b6d669/resolv.conf",
# "HostnamePath": "/var/lib/docker/containers/7ac0d1c11dbe8a98ec1f596bb9bde7799768fd18685a121f2263f07c48b6d669/hostname",
# "HostsPath": "/var/lib/docker/containers/7ac0d1c11dbe8a98ec1f596bb9bde7799768fd18685a121f2263f07c48b6d669/hosts",
# "LogPath": "/var/lib/docker/containers/7ac0d1c11dbe8a98ec1f596bb9bde7799768fd18685a121f2263f07c48b6d669/7ac0d1c11dbe8a98ec1f596bb9bde7799768fd18685a121f2263f07c48b6d669-json.log",
# "Name": "/focused_bardeen",
# "RestartCount": 0,
# "Driver": "aufs",
# "ExecDriver": "native-0.2",
# "MountLabel": "",
# "ProcessLabel": "",
# "Volumes": {},
# "VolumesRW": {},
# "AppArmorProfile": "",
# "ExecIDs": null,
# "HostConfig": {
# "Binds": null,
# "ContainerIDFile": "",
# "LxcConf": [],
# "Memory": 0,
# "MemorySwap": 0,
# "CpuShares": 0,
# "CpuPeriod": 0,
# "CpusetCpus": "",
# "CpusetMems": "",
# "CpuQuota": 0,
# "BlkioWeight": 0,
# "OomKillDisable": false,
# "Privileged": false,
# "PortBindings": {},
# "Links": null,
# "PublishAllPorts": false,
# "Dns": null,
# "DnsSearch": null,
# "ExtraHosts": null,
# "VolumesFrom": null,
# "Devices": [],
# "NetworkMode": "bridge",
# "IpcMode": "",
# "PidMode": "",
# "CapAdd": null,
# "CapDrop": null,
# "RestartPolicy": {
# "Name": "no",
# "MaximumRetryCount": 0
# },
# "SecurityOpt": null,
# "ReadonlyRootfs": false,
# "Ulimits": null,
# "LogConfig": {
# "Type": "json-file",
# "Config": {}
# },
# "CgroupParent": ""
# }
#}
#]
You can pass a name with the docker run
like so:
docker run -it --rm --name="SOME_NAME" ubuntu /bin/bash
docker ps
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# d8d2027d6883 ubuntu "/bin/bash" 5 seconds ago Up 4 seconds SOME_NAME
Next start a service and expose a port mapping (PAT):
docker run --rm -p 80:80 -it nginx
In another window on the host get the IP address of the container:
docker inspect --format "{{ .NetworkSettings.IPAddress }}" 0000a6bfa465
192.168.5.10
Hit the new nginx service you just started. Keep in mind unless the bridge subnet is routed/flooded/forwarded/etc in some fashion it will only be reachable via the local docker host.
curl 192.168.5.10:80
# 192.168.5.1 - - [16/May/2015:22:58:48 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.42.1" "-"
Now notice the differences in the containers metadata with a port exposed:
docker inspect $(docker ps -ql)
#[
#{
# "Id": "0000a6bfa4650acd686cb63b70bc33dfcbd6e8bb23eaaff1ef43dff21983faa8",
# "Created": "2015-05-16T22:58:01.787299191Z",
# "Path": "nginx",
# "Args": [
# "-g",
# "daemon off;"
# ],
# "Config": {
# "Hostname": "0000a6bfa465",
# "Domainname": "",
# "User": "",
# "AttachStdin": true,
# "AttachStdout": true,
# "AttachStderr": true,
# "PortSpecs": null,
# "ExposedPorts": {
# "443/tcp": {},
# "80/tcp": {}
# },
# "Tty": true,
# "OpenStdin": true,
# "StdinOnce": true,
# "Env": [
# "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
# "NGINX_VERSION=1.9.0-1~jessie"
# ],
# "Cmd": [
# "nginx",
# "-g",
# "daemon off;"
# ],
# "Image": "nginx",
# "Volumes": {
# "/var/cache/nginx": {}
# },
# "WorkingDir": "",
# "Entrypoint": null,
# "NetworkDisabled": false,
# "MacAddress": "",
# "OnBuild": null,
# "Labels": {}
# },
# "State": {
# "Running": true,
# "Paused": false,
# "Restarting": false,
# "OOMKilled": false,
# "Dead": false,
# "Pid": 10921,
# "ExitCode": 0,
# "Error": "",
# "StartedAt": "2015-05-16T22:58:02.159142682Z",
# "FinishedAt": "0001-01-01T00:00:00Z"
# },
# "Image": "42a3cf88f3f0cce2b4bfb2ed714eec5ee937525b4c7e0a0f70daff18c3f2ee92",
# "NetworkSettings": {
# "Bridge": "bridge0",
# "Gateway": "192.168.5.1",
# "GlobalIPv6Address": "",
# "GlobalIPv6PrefixLen": 0,
# "IPAddress": "192.168.5.10",
# "IPPrefixLen": 24,
# "IPv6Gateway": "",
# "LinkLocalIPv6Address": "",
# "LinkLocalIPv6PrefixLen": 0,
# "MacAddress": "02:42:f7:b2:e4:16",
# "PortMapping": null,
# "Ports": {
# "443/tcp": [
# {
# "HostIp": "0.0.0.0",
# "HostPort": "32769"
# }
# ],
# "80/tcp": [
# {
# "HostIp": "0.0.0.0",
# "HostPort": "80"
# }
# ]
# },
# "SecondaryIPAddresses": null,
# "SecondaryIPv6Addresses": null,
# "SandboxKey": "/var/run/netns/0000a6bfa465",
# "NetworkID": "30b2ea4e443226a426b1618ceb954c30dcae9f0df88ba5da942033b0678a8793",
# "EndpointID": "da4a5d449238e97d1e6e949e570672de4f022ecb6c77ce114c58f7aa0ca9dbe3",
# "HairpinMode": false
# },
# "ResolvConfPath": "/var/lib/docker/containers/0000a6bfa4650acd686cb63b70bc33dfcbd6e8bb23eaaff1ef43dff21983faa8/resolv.conf",
# "HostnamePath": "/var/lib/docker/containers/0000a6bfa4650acd686cb63b70bc33dfcbd6e8bb23eaaff1ef43dff21983faa8/hostname",
# "HostsPath": "/var/lib/docker/containers/0000a6bfa4650acd686cb63b70bc33dfcbd6e8bb23eaaff1ef43dff21983faa8/hosts",
# "LogPath": "/var/lib/docker/containers/0000a6bfa4650acd686cb63b70bc33dfcbd6e8bb23eaaff1ef43dff21983faa8/0000a6bfa4650acd686cb63b70bc33dfcbd6e8bb23eaaff1ef43dff21983faa8-json.log",
# "Name": "/sad_sammet",
# "RestartCount": 0,
# "Driver": "aufs",
# "ExecDriver": "native-0.2",
# "MountLabel": "",
# "ProcessLabel": "",
# "Volumes": {
# "/var/cache/nginx": "/var/lib/docker/vfs/dir/8800dcd8ea7597a76a5ffb3fc62f37587d3f0b1d973558a02917b90365b5297e"
# },
# "VolumesRW": {
# "/var/cache/nginx": true
# },
# "AppArmorProfile": "",
# "ExecIDs": null,
# "HostConfig": {
# "Binds": null,
# "ContainerIDFile": "",
# "LxcConf": [],
# "Memory": 0,
# "MemorySwap": 0,
# "CpuShares": 0,
# "CpuPeriod": 0,
# "CpusetCpus": "",
# "CpusetMems": "",
# "CpuQuota": 0,
# "BlkioWeight": 0,
# "OomKillDisable": false,
# "Privileged": false,
# "PortBindings": {
# "80/tcp": [
# {
# "HostIp": "",
# "HostPort": "80"
# }
# ]
# },
# "Links": null,
# "PublishAllPorts": false,
# "Dns": null,
# "DnsSearch": null,
# "ExtraHosts": null,
# "VolumesFrom": null,
# "Devices": [],
# "NetworkMode": "bridge",
# "IpcMode": "",
# "PidMode": "",
# "CapAdd": null,
# "CapDrop": null,
# "RestartPolicy": {
# "Name": "no",
# "MaximumRetryCount": 0
# },
# "SecurityOpt": null,
# "ReadonlyRootfs": false,
# "Ulimits": null,
# "LogConfig": {
# "Type": "json-file",
# "Config": {}
# },
# "CgroupParent": ""
# }
#}
#]
If when you restart your machine and the bridge you created was not reinitialized in the Linux init configs, you need to recreate the bridges or put them in your OS network conf. E.g. for example /etc/network/interfaces
or /etc/sysconfig/network-scripts/ifcfg-<name>
FEEDBACK: Should this be initialized by default in future releases? That said, I like that the daemon aborts rather then start broken containers.
The error will look like so:
May 16 19:58:36 deb8-150 docker[586]: time="2015-05-16T19:58:36.778741276-04:00" level=fatal msg="Error starting daemon: Error initializing network controller: Error creating default \"bridge\" network: bridge device with non default name bridge0 must be created manually"
May 16 19:58:36 deb8-150 systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE
May 16 19:58:36 deb8-150 systemd[1]: Unit docker.service entered failed state.
May 16 20:01:49 deb8-150 docker[608]: time="2015-05-16T20:01:49.338579035-04:00" level=info msg="[graphdriver] using prior storage driver \"aufs\""
May 16 20:01:49 deb8-150 docker[608]: time="2015-05-16T20:01:49.351917230-04:00" level=warning msg="/!\\ DON'T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\"
May 16 20:01:49 deb8-150 docker[608]: time="2015-05-16T20:01:49.352432670-04:00" level=info msg="Listening for HTTP on tcp (0.0.0.0:2375)"
May 16 20:01:49 deb8-150 docker[608]: time="2015-05-16T20:01:49.427094152-04:00" level=fatal msg="Error starting daemon: Error initializing network controller: Error creating default \"bridge\" network: bridge device with non default name bridge0 must be created manually"
To resolve that issue, redefine the bridge specified in the /etc/default/docker
brctl addbr bridge0
ip addr add 192.168.5.1/24 dev bridge0
ip link set dev bridge0 up
ps -eaf | grep dock
root 1131 1 0 20:22 ? 00:00:00 /usr/bin/docker -d -H tcp://0.0.0.0:2375 -H fd:// --ip=192.168.5.20
docker run --rm -p 80:80 -it nginx
Error response from daemon: Cannot start container a6a67158adc97a84e7408664cdf8c735db139ab7307be89d62ce92a4abdee220: Error starting userland proxy: listen tcp 192.168.5.20:32777: bind: cannot assign requested address
Add a sub-interface to the iface w/ the desired network you want a secondary on. TODO: get the syntax/instructions for iproute2
ifconfig eth0:1 192.168.5.20 netmask 255.255.255.0 up
Now test the service:
curl 192.168.5.20:80
# <!DOCTYPE html>
# <html>
# <head>
# <title>Welcome to nginx!</title>
# <style>
These can be added to the docker run
command also. This is handy if the change is not desired globally be default.
# Add the following to /etc/default/docker (restart the daemon to enable the change)
DOCKER_OPTS="--dns=8.8.8.8 "
ps -eaf | grep docker
# root 2100 1 1 00:11 ? 00:00:00 /usr/bin/docker -d -H fd:// --dns=8.8.8.8
docker run --rm -it ubuntu /bin/bash
cat /etc/resolv.conf
# nameserver 8.8.8.8
# search localdomain
If you want to change the search domain, simply pop that into the DOCKER_OPTS ENV like so (bridge section isn't required, just showing compatabilities):
# Add the following to /etc/default/docker (restart the daemon to enable the change)
DOCKER_OPTS="-b=bridge0 --dns=8.8.8.8 --dns-search=foobahs"
ps -eaf | grep docker
# root 2270 1 1 00:34 ? 00:00:00 /usr/bin/docker -d -H fd:// -b=bridge0 --dns=8.8.8.8 --dns-search=foobahs
docker run --rm -it ubuntu /bin/bash
cat /etc/resolv.conf
# nameserver 8.8.8.8
# search foobahs
Specify the mac address with the ``docker runcommand using the
--mac-address=`. That can be used without changing anything in `/etc/default/docker`.
docker run --rm -it --mac-address=00:0c:29:58:FF:12 ubuntu /bin/bash
Verify the mac in the container
root@1a61c3349ca1:/# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
19: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 00:0c:29:58:ff:12 brd ff:ff:ff:ff:ff:ff
root@1a61c3349ca1:/# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=127 time=22.6 ms
If you want to block out a range of addresses that are a subset of the allocated bock you can do so with the following in /etc/default/docker
:
DOCKER_OPTS="--fixed-cidr=192.168.5.128/28 -b=bridge0 "
Notice the fixed ipv4 prefix falls within the subnet assigned to the bridge:
ip add show bridge0
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.5.1/24 scope global bridge0
Full output:
docker run --rm -it --mac-address=00:0c:29:58:FF:12 ubuntu /bin/bash
root@b6b692d26f90:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
21: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 00:0c:29:58:ff:12 brd ff:ff:ff:ff:ff:ff
inet 192.168.5.129/24 scope global eth0
To specify a custom global MTU for all docker containers on the host modify DOCKER_OPTS
DOCKER_OPTS="--mtu=8192"
This will modify both the docker0
bridge and the veth pair
Here are the docker host links:
6: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8192 qdisc noqueue state UP mode DEFAULT group default
link/ether 0e:4f:43:25:81:de brd ff:ff:ff:ff:ff:ff
30: veth7996fe4: <BROADCAST,UP,LOWER_UP> mtu 8192 qdisc pfifo_fast master docker0 state UP mode DEFAULT group default qlen 1000
link/ether 0e:4f:43:25:81:de brd ff:ff:ff:ff:ff:ff
The other side of the veth pair that is renamed to eth0 (by default) with the custom MTU
root@316895e0e52c:/# ip link show eth0
29: eth0: <BROADCAST,UP,LOWER_UP> mtu 8192 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:42:fa:c5:ce brd ff:ff:ff:ff:ff:ff
By default if you specify v6 support Docker provisions what is commonly referred to as a 'dual stack' meaning the host has both an IPv4 address and an IPv6 address.
The DOCKER_OPTS config for this example is as follows:
DOCKER_OPTS="-b=bridge0 --mtu=8192 --ipv6=true"
The Docker host side of the veth pair looks like this:
ip a show bridge0
3: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8192 qdisc noqueue state UP group default
link/ether 4a:c5:20:ab:04:1a brd ff:ff:ff:ff:ff:ff
inet 192.168.5.1/24 scope global bridge0
valid_lft forever preferred_lft forever
inet6 fe80::1/64 scope link
valid_lft forever preferred_lft forever
inet6 fe80::189c:73ff:fe9d:d11e/64 scope link
valid_lft forever preferred_lft forever
The docker container side of the pair is:
31: eth0: <BROADCAST,UP,LOWER_UP> mtu 8192 qdisc noqueue state UP group default
link/ether 02:42:c9:72:2e:3a brd ff:ff:ff:ff:ff:ff
inet 192.168.5.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::242:c972:2e3a/64 scope link
valid_lft forever preferred_lft forever
inet6 fe80::42:c9ff:fe72:2e3a/64 scope link
valid_lft forever preferred_lft forever
Note: when you are switching between a custom bridge and the default docker0 profiles, you currently need to destroy containers using the previous configuration. The daemon will refuse to start if it detects a collision like this in the configuration at runtime. This is actually a positive choice in the docker logic because the alternative would be to spin up a container that appears to be functioning but in reality is in a broken state.
The DOCKER_OPTS config for this example is as follows:
DOCKER_OPTS="--ipv6=true"
ip a show docker0
6: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 5a:4f:12:b4:93:ac brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::1/64 scope link
valid_lft forever preferred_lft forever
inet6 fe80::182e:1dff:fe64:cf3f/64 scope link
valid_lft forever preferred_lft forever
The docker container side of the veth pair
ip a show eth0
33: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:5c:b3:29:a2 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::242:5cb3:29a2/64 scope link
valid_lft forever preferred_lft forever
inet6 fe80::42:5cff:feb3:29a2/64 scope link
valid_lft forever preferred_lft forever
Lastly for testing v6 connectivity simply use the ping6
utility that is installed by default in most of the popular Linux images in the Docker Library.
root@167585be85a9:/# ping6 -c 2 fe80::182e:1dff:fe64:cf3f
PING fe80::182e:1dff:fe64:cf3f (fe80::182e:1dff:fe64:cf3f): 56 data bytes
64 bytes from fe80::182e:1dff:fe64:cf3f%eth0: icmp_seq=0 ttl=64 time=0.083 ms
64 bytes from fe80::182e:1dff:fe64:cf3f%eth0: icmp_seq=1 ttl=64 time=0.057 ms
--- fe80::182e:1dff:fe64:cf3f ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.057/0.070/0.083/0.000 ms
Simply pass the --hostname=FOO
option when you create a container:
docker run -it --rm -p 80:80 --hostname=ponyrides nginx /bin/bash
root@ponyrides:
This will update your /etc/hosts
config file also:
root@ponyrides:/# cat /etc/hosts
172.17.0.2 ponyrides
Locate the systemd docker.service unit file on the Docker host. On Ubuntu or Debian it is located at: /lib/systemd/system/docker.service
ExecStart
is the main one you will probably edit. As long as $DOCKER_OPTS
is in there as a value the /etc/default/docker
file will get read at initialization and added to the process exec. You can add it directly here is you so desire.
Note, on Ubuntu Vivid 15.04 I still need to manually kill -9 the docker process because Systemd just sits there in a state like so:
systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled)
Active: deactivating (stop-sigterm) since Sat 2015-05-16 18:35:47 EDT; 1min 0s ago
Docs: http://docs.docker.com
Main PID: 10312 (docker)
CGroup: /system.slice/docker.service
└─10312 /usr/bin/docker -d -H tcp://0.0.0.0:2375 -H fd:// -b=bridge0
It will finally time out and get killed with sig but hey its systemd ><
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.com
After=network.target docker.socket
Requires=docker.socket
[Service]
EnvironmentFile=-/etc/default/docker
ExecStart=/usr/bin/docker -d -H fd:// $DOCKER_OPTS
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
The above Systemd unit file coupled with the following '/etc/default/docker'
# Docker Upstart and SysVinit configuration file
# Customize location of Docker binary (especially for development testing).
#DOCKER="/usr/local/bin/docker"
# Use DOCKER_OPTS to modify the daemon startup options.
#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"
# If you need Docker to use an HTTP proxy, it can also be specified here.
#export http_proxy="http://127.0.0.1:3128/"
# This is also a handy place to tweak where Docker's temporary files go.
#export TMPDIR="/mnt/bigdrive/docker-tmp"
DOCKER_OPTS="-b=bridge0 -H tcp://0.0.0.0:2375"
Result in a running process of this:
ps -eaf | grep docker
# root 10375 1 0 18:39 ? 00:00:00 /usr/bin/docker -d -H tcp://0.0.0.0:2375 -H fd:// -b=bridge0 -H tcp://0.0.0.0:2375
and a systemd status docker
of this:
systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled)
Active: active (running) since Sat 2015-05-16 18:39:25 EDT; 5s ago
Docs: http://docs.docker.com
Main PID: 10375 (docker)
CGroup: /system.slice/docker.service
└─10375 /usr/bin/docker -d -H tcp://0.0.0.0:2375 -H fd:// -b=bridge0 -H tcp://0.0.0.0:2375
Note I have to DOCKER_OPTS parameters added along with the default configuration DOCKER_OPTS="-b=bridge0 -H tcp://0.0.0.0:2375"
.
-b=bridge0
instructs docker to use bridge0
rather then the default docker0
bridge.
-H tcp://0.0.0.0:2375
binds the remote API to port 2375 on all IP addresses for remote docker cli execution of the docker host.