github.com/boynux/docker@v1.11.0-rc4/docs/userguide/networking/default_network/ipv6.md (about)

     1  <!--[metadata]>
     2  +++
     3  title = "IPv6 with Docker"
     4  description = "How do we connect docker containers within and across hosts ?"
     5  keywords = ["docker, network, IPv6"]
     6  [menu.main]
     7  parent = "smn_networking_def"
     8  weight = 3
     9  +++
    10  <![end-metadata]-->
    11  
    12  # IPv6 with Docker
    13  
    14  The information in this section explains IPv6 with the Docker default bridge.
    15  This is a `bridge` network named `bridge` created automatically when you install
    16  Docker.  
    17  
    18  As we are [running out of IPv4
    19  addresses](http://en.wikipedia.org/wiki/IPv4_address_exhaustion) the IETF has
    20  standardized an IPv4 successor, [Internet Protocol Version
    21  6](http://en.wikipedia.org/wiki/IPv6) , in [RFC
    22  2460](https://www.ietf.org/rfc/rfc2460.txt). Both protocols, IPv4 and IPv6,
    23  reside on layer 3 of the [OSI model](http://en.wikipedia.org/wiki/OSI_model).
    24  
    25  ## How IPv6 works on Docker
    26  
    27  By default, the Docker server configures the container network for IPv4 only.
    28  You can enable IPv4/IPv6 dualstack support by running the Docker daemon with the
    29  `--ipv6` flag. Docker will set up the bridge `docker0` with the IPv6 [link-local
    30  address](http://en.wikipedia.org/wiki/Link-local_address) `fe80::1`.
    31  
    32  By default, containers that are created will only get a link-local IPv6 address.
    33  To assign globally routable IPv6 addresses to your containers you have to
    34  specify an IPv6 subnet to pick the addresses from. Set the IPv6 subnet via the
    35  `--fixed-cidr-v6` parameter when starting Docker daemon:
    36  
    37  ```
    38  docker daemon --ipv6 --fixed-cidr-v6="2001:db8:1::/64"
    39  ```
    40  
    41  The subnet for Docker containers should at least have a size of `/80`. This way
    42  an IPv6 address can end with the container's MAC address and you prevent NDP
    43  neighbor cache invalidation issues in the Docker layer.
    44  
    45  With the `--fixed-cidr-v6` parameter set Docker will add a new route to the
    46  routing table. Further IPv6 routing will be enabled (you may prevent this by
    47  starting Docker daemon with `--ip-forward=false`):
    48  
    49  ```
    50  $ ip -6 route add 2001:db8:1::/64 dev docker0
    51  $ sysctl net.ipv6.conf.default.forwarding=1
    52  $ sysctl net.ipv6.conf.all.forwarding=1
    53  ```
    54  
    55  All traffic to the subnet `2001:db8:1::/64` will now be routed via the `docker0` interface.
    56  
    57  Be aware that IPv6 forwarding may interfere with your existing IPv6
    58  configuration: If you are using Router Advertisements to get IPv6 settings for
    59  your host's interfaces you should set `accept_ra` to `2`. Otherwise IPv6 enabled
    60  forwarding will result in rejecting Router Advertisements. E.g., if you want to
    61  configure `eth0` via Router Advertisements you should set:
    62  
    63  ```
    64  $ sysctl net.ipv6.conf.eth0.accept_ra=2
    65  ```
    66  
    67  ![](images/ipv6_basic_host_config.svg)
    68  
    69  Every new container will get an IPv6 address from the defined subnet. Further a
    70  default route will be added on `eth0` in the container via the address specified
    71  by the daemon option `--default-gateway-v6` if present, otherwise via `fe80::1`:
    72  ```
    73  docker run -it ubuntu bash -c "ip -6 addr show dev eth0; ip -6 route show"
    74  
    75  15: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500
    76     inet6 2001:db8:1:0:0:242:ac11:3/64 scope global
    77        valid_lft forever preferred_lft forever
    78     inet6 fe80::42:acff:fe11:3/64 scope link
    79        valid_lft forever preferred_lft forever
    80  
    81  2001:db8:1::/64 dev eth0  proto kernel  metric 256
    82  fe80::/64 dev eth0  proto kernel  metric 256
    83  default via fe80::1 dev eth0  metric 1024
    84  ```
    85  
    86  In this example the Docker container is assigned a link-local address with the
    87  network suffix `/64` (here: `fe80::42:acff:fe11:3/64`) and a globally routable
    88  IPv6 address (here: `2001:db8:1:0:0:242:ac11:3/64`). The container will create
    89  connections to addresses outside of the `2001:db8:1::/64` network via the
    90  link-local gateway at `fe80::1` on `eth0`.
    91  
    92  Often servers or virtual machines get a `/64` IPv6 subnet assigned (e.g.
    93  `2001:db8:23:42::/64`). In this case you can split it up further and provide
    94  Docker a `/80` subnet while using a separate `/80` subnet for other applications
    95  on the host:
    96  
    97  ![](images/ipv6_slash64_subnet_config.svg)
    98  
    99  In this setup the subnet `2001:db8:23:42::/80` with a range from
   100  `2001:db8:23:42:0:0:0:0` to `2001:db8:23:42:0:ffff:ffff:ffff` is attached to
   101  `eth0`, with the host listening at `2001:db8:23:42::1`. The subnet
   102  `2001:db8:23:42:1::/80` with an address range from `2001:db8:23:42:1:0:0:0` to
   103  `2001:db8:23:42:1:ffff:ffff:ffff` is attached to `docker0` and will be used by
   104  containers.
   105  
   106  ### Using NDP proxying
   107  
   108  If your Docker host is only part of an IPv6 subnet but has not got an IPv6
   109  subnet assigned you can use NDP proxying to connect your containers via IPv6 to
   110  the internet. For example your host has the IPv6 address `2001:db8::c001`, is
   111  part of the subnet `2001:db8::/64` and your IaaS provider allows you to
   112  configure the IPv6 addresses `2001:db8::c000` to `2001:db8::c00f`:
   113  
   114  ```
   115  $ ip -6 addr show
   116  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
   117      inet6 ::1/128 scope host
   118         valid_lft forever preferred_lft forever
   119  2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
   120      inet6 2001:db8::c001/64 scope global
   121         valid_lft forever preferred_lft forever
   122      inet6 fe80::601:3fff:fea1:9c01/64 scope link
   123         valid_lft forever preferred_lft forever
   124  ```
   125  
   126  Let's split up the configurable address range into two subnets
   127  `2001:db8::c000/125` and `2001:db8::c008/125`. The first one can be used by the
   128  host itself, the latter by Docker:
   129  
   130  ```
   131  docker daemon --ipv6 --fixed-cidr-v6 2001:db8::c008/125
   132  ```
   133  
   134  You notice the Docker subnet is within the subnet managed by your router that is
   135  connected to `eth0`. This means all devices (containers) with the addresses from
   136  the Docker subnet are expected to be found within the router subnet. Therefore
   137  the router thinks it can talk to these containers directly.
   138  
   139  ![](images/ipv6_ndp_proxying.svg)
   140  
   141  As soon as the router wants to send an IPv6 packet to the first container it
   142  will transmit a neighbor solicitation request, asking, who has `2001:db8::c009`?
   143  But it will get no answer because no one on this subnet has this address. The
   144  container with this address is hidden behind the Docker host. The Docker host
   145  has to listen to neighbor solicitation requests for the container address and
   146  send a response that itself is the device that is responsible for the address.
   147  This is done by a Kernel feature called `NDP Proxy`. You can enable it by
   148  executing
   149  
   150  ```
   151  $ sysctl net.ipv6.conf.eth0.proxy_ndp=1
   152  ```
   153  
   154  Now you can add the container's IPv6 address to the NDP proxy table:
   155  
   156  ```
   157  $ ip -6 neigh add proxy 2001:db8::c009 dev eth0
   158  ```
   159  
   160  This command tells the Kernel to answer to incoming neighbor solicitation
   161  requests regarding the IPv6 address `2001:db8::c009` on the device `eth0`. As a
   162  consequence of this all traffic to this IPv6 address will go into the Docker
   163  host and it will forward it according to its routing table via the `docker0`
   164  device to the container network:
   165  
   166  ```
   167  $ ip -6 route show
   168  2001:db8::c008/125 dev docker0  metric 1
   169  2001:db8::/64 dev eth0  proto kernel  metric 256
   170  ```
   171  
   172  You have to execute the `ip -6 neigh add proxy ...` command for every IPv6
   173  address in your Docker subnet. Unfortunately there is no functionality for
   174  adding a whole subnet by executing one command. An alternative approach would be
   175  to use an NDP proxy daemon such as
   176  [ndppd](https://github.com/DanielAdolfsson/ndppd).
   177  
   178  ## Docker IPv6 cluster
   179  
   180  ### Switched network environment
   181  Using routable IPv6 addresses allows you to realize communication between
   182  containers on different hosts. Let's have a look at a simple Docker IPv6 cluster
   183  example:
   184  
   185  ![](images/ipv6_switched_network_example.svg)
   186  
   187  The Docker hosts are in the `2001:db8:0::/64` subnet. Host1 is configured to
   188  provide addresses from the `2001:db8:1::/64` subnet to its containers. It has
   189  three routes configured:
   190  
   191  - Route all traffic to `2001:db8:0::/64` via `eth0`
   192  - Route all traffic to `2001:db8:1::/64` via `docker0`
   193  - Route all traffic to `2001:db8:2::/64` via Host2 with IP `2001:db8::2`
   194  
   195  Host1 also acts as a router on OSI layer 3. When one of the network clients
   196  tries to contact a target that is specified in Host1's routing table Host1 will
   197  forward the traffic accordingly. It acts as a router for all networks it knows:
   198  `2001:db8::/64`, `2001:db8:1::/64` and `2001:db8:2::/64`.
   199  
   200  On Host2 we have nearly the same configuration. Host2's containers will get IPv6
   201  addresses from `2001:db8:2::/64`. Host2 has three routes configured:
   202  
   203  - Route all traffic to `2001:db8:0::/64` via `eth0`
   204  - Route all traffic to `2001:db8:2::/64` via `docker0`
   205  - Route all traffic to `2001:db8:1::/64` via Host1 with IP `2001:db8:0::1`
   206  
   207  The difference to Host1 is that the network `2001:db8:2::/64` is directly
   208  attached to the host via its `docker0` interface whereas it reaches
   209  `2001:db8:1::/64` via Host1's IPv6 address `2001:db8::1`.
   210  
   211  This way every container is able to contact every other container. The
   212  containers `Container1-*` share the same subnet and contact each other directly.
   213  The traffic between `Container1-*` and `Container2-*` will be routed via Host1
   214  and Host2 because those containers do not share the same subnet.
   215  
   216  In a switched environment every host has to know all routes to every subnet.
   217  You always have to update the hosts' routing tables once you add or remove a
   218  host to the cluster.
   219  
   220  Every configuration in the diagram that is shown below the dashed line is
   221  handled by Docker: The `docker0` bridge IP address configuration, the route to
   222  the Docker subnet on the host, the container IP addresses and the routes on the
   223  containers. The configuration above the line is up to the user and can be
   224  adapted to the individual environment.
   225  
   226  ### Routed network environment
   227  In a routed network environment you replace the layer 2 switch with a layer 3
   228  router. Now the hosts just have to know their default gateway (the router) and
   229  the route to their own containers (managed by Docker). The router holds all
   230  routing information about the Docker subnets. When you add or remove a host to
   231  this environment you just have to update the routing table in the router - not
   232  on every host.
   233  
   234  ![](images/ipv6_routed_network_example.svg)
   235  
   236  In this scenario containers of the same host can communicate directly with each
   237  other. The traffic between containers on different hosts will be routed via
   238  their hosts and the router. For example packet from `Container1-1` to
   239  `Container2-1` will be routed through `Host1`, `Router` and `Host2` until it
   240  arrives at `Container2-1`.
   241  
   242  To keep the IPv6 addresses short in this example a `/48` network is assigned to
   243  every host. The hosts use a `/64` subnet of this for its own services and one
   244  for Docker. When adding a third host you would add a route for the subnet
   245  `2001:db8:3::/48` in the router and configure Docker on Host3 with
   246  `--fixed-cidr-v6=2001:db8:3:1::/64`.
   247  
   248  Remember the subnet for Docker containers should at least have a size of `/80`.
   249  This way an IPv6 address can end with the container's MAC address and you
   250  prevent NDP neighbor cache invalidation issues in the Docker layer. So if you
   251  have a `/64` for your whole environment use `/78` subnets for the hosts and
   252  `/80` for the containers. This way you can use 4096 hosts with 16 `/80` subnets
   253  each.
   254  
   255  Every configuration in the diagram that is visualized below the dashed line is
   256  handled by Docker: The `docker0` bridge IP address configuration, the route to
   257  the Docker subnet on the host, the container IP addresses and the routes on the
   258  containers. The configuration above the line is up to the user and can be
   259  adapted to the individual environment.