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