IPv6 with Docker

Estimated reading time: 10 minutes

The information in this section explains IPv6 with the Docker default bridge. This is a bridgenetwork named bridge created automatically when you install Docker.

As we are running out of IPv4 addresses the IETF has standardized an IPv4 successor, Internet Protocol Version 6 , in RFC 2460. Both protocols, IPv4 and IPv6, reside on layer 3 of the OSI model.

How IPv6 works on Docker

By default, the Docker daemon configures the container network for IPv4 only. You can enable IPv4/IPv6 dualstack support by running the Docker daemon with the --ipv6 flag. Docker will set up the bridge docker0 with the IPv6 link-local address fe80::1.

By default, containers that are created will only get a link-local IPv6 address. To assign globally routable IPv6 addresses to your containers you have to specify an IPv6 subnet to pick the addresses from. Set the IPv6 subnet via the --fixed-cidr-v6 parameter when starting Docker daemon:

You can run dockerd with these flags directly, but it is recommended that you set them in thedaemon.json configuration file instead. The following example daemon.json enables IPv6 and sets the IPv6 subnet to 2001:db8:1::/64.

{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}

The subnet for Docker containers should at least have a size of /80, so that an IPv6 address can end with the container’s MAC address and you prevent NDP neighbor cache invalidation issues in the Docker layer.

By default, --fixed-cidr-v6 parameter causes Docker to add a new route to the routing table, by basically running the three commands below on your behalf. To prevent the automatic routing, set ip-forward to false in the daemon.json file or start the Docker daemon with the --ip-forward=false flag. Then, to get the same routing table that Docker would create automatically for you, issue the following commands:

$ ip -6 route add 2001:db8:1::/64 dev docker0

$ sysctl net.ipv6.conf.default.forwarding=1

$ sysctl net.ipv6.conf.all.forwarding=1

All traffic to the subnet 2001:db8:1::/64 will now be routed via the docker0 interface.

Note: IPv6 forwarding may interfere with your existing IPv6 configuration: If you are using Router Advertisements to get IPv6 settings for your host’s interfaces, set accept_ra to 2 using the following command. Otherwise IPv6 enabled forwarding will result in rejecting Router Advertisements.

$ sysctl net.ipv6.conf.eth0.accept_ra=2

Every new container will get an IPv6 address from the defined subnet, and a default route will be added on eth0 in the container via the address specified by the daemon option --default-gateway-v6 (or default-gateway-v6 in daemon.json) if present. The default gateway defaults to fe80::1.

This example provides a way to examine the IPv6 network settings within a running container.

docker run -it alpine ash -c "ip -6 addr show dev eth0; ip -6 route show"

15: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500
inet6 2001:db8:1:0:0:242:ac11:3/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:3/64 scope link
valid_lft forever preferred_lft forever 2001:db8:1::/64 dev eth0 proto kernel metric 256
fe80::/64 dev eth0 proto kernel metric 256
default via fe80::1 dev eth0 metric 1024

In this example, the container is assigned a link-local address with the subnet /64(fe80::42:acff:fe11:3/64) and a globally routable IPv6 address (2001:db8:1:0:0:242:ac11:3/64). The container will create connections to addresses outside of the 2001:db8:1::/64 network via the link-local gateway at fe80::1 on eth0.

Often servers or virtual machines get a /64 IPv6 subnet assigned (e.g.2001:db8:23:42::/64). In this case you can split it up further and provide Docker a /80subnet while using a separate /80 subnet for other applications on the host:

In this setup the subnet 2001:db8:23:42::/64 with a range from 2001:db8:23:42:0:0:0:0to 2001:db8:23:42:ffff:ffff:ffff:ffff is attached to eth0, with the host listening at 2001:db8:23:42::1. The subnet 2001:db8:23:42:1::/80 with an address range from 2001:db8:23:42:1:0:0:0 to 2001:db8:23:42:1:ffff:ffff:ffff is attached to docker0and will be used by containers.

Using NDP proxying

If your Docker host is the only part of an IPv6 subnet but does not have an IPv6 subnet assigned, you can use NDP proxying to connect your containers to the internet via IPv6. If the host with IPv6 address 2001:db8::c001 is part of the subnet 2001:db8::/64 and your IaaS provider allows you to configure the IPv6 addresses 2001:db8::c000 to 2001:db8::c00f, your network configuration may look like the following:

$ ip -6 addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
inet6 2001:db8::c001/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::601:3fff:fea1:9c01/64 scope link
valid_lft forever preferred_lft forever

To slit up the configurable address range into two subnets 2001:db8::c000/125 and 2001:db8::c008/125, use the following daemon.json settings. The first subnet will be used by non-Docker processes on the host, and the second will be used by Docker.

{
"ipv6": true,
"fixed-cidr-v6": "2001:db8::c008/125"
}

The Docker subnet is within the subnet managed by your router and connected to eth0. All containers with addresses assigned by Docker are expected to be found within the router subnet, and the router can communicate with these containers directly.

When the router wants to send an IPv6 packet to the first container, it transmits a neighbor solicitation request, asking “Who has 2001:db8::c009?” However, no host on the subnet has the address; the container with the address is hidden behind the Docker host. The Docker host therefore must listen for neighbor solicitation requests and respond that it is the device with the address. This functionality is called the NDP Proxy and is handled by the kernel on the host machine. To enable the NDP proxy, execute the following command:

$ sysctl net.ipv6.conf.eth0.proxy_ndp=1

Next, add the container’s IPv6 address to the NDP proxy table:

$ ip -6 neigh add proxy 2001:db8::c009 dev eth0

From now on, the kernel answers neighbor solicitation addresses for this address on the device eth0. All traffic to this IPv6 address is routed through the Docker host, which will forward it to the container’s network according to its routing table via the docker0 device:

$ ip -6 route show

2001:db8::c008/125 dev docker0  metric 1
2001:db8::/64 dev eth0 proto kernel metric 256

You have to execute the ip -6 neigh add proxy ... command for every IPv6 address in your Docker subnet. Unfortunately there is no functionality for adding a whole subnet by executing one command. An alternative approach would be to use an NDP proxy daemon such as ndppd.

docker 支持ipv6 (核心要点是ndp需要把docker内的ip全部加入到ndplist中来)的更多相关文章

  1. docker支持ipv6

    方法 方法一.Pv6地址 不为容器中的服务特别分配IPv6地址. 只要Docker把外部的IPv6地址端口映射到容器的IPv4端口上,随后访问主机的IPv6相应端口即可. 方法二.为Docker网络分 ...

  2. 高级网络功能(Docker支持的网络定制配置)

    网络的高级知识,包括网络的启动和配置参数.DNS的使用配置.容器访问和端口映射的相关实现. 在一些具体场景中,Docker支持的网络定制配置,通过Linux命令来调整.补充.甚至替换Docker默认的 ...

  3. 阿里云开源镜像站支持IPv6访问

    阿里云开源镜像站在国内企业镜像站中率先支持IPv6访问! 点击立即试用https://developer.aliyun.com/mirror/ 同时基于阿里云OpenSearch的搜索能力,开源镜像站 ...

  4. Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理

    Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明:Java生鲜电商平台中,我们将进一步理解微服务架构的核心要点和实现原理,为读者的实践提供微服务的设计模式,以期让微服务 ...

  5. 最佳实践:阿里云VPC、ECS支持IPv6啦!

    12月6日,阿里云宣布为企业提供全栈IPv6解决方案. 阿里云专有网络VPC.云服务器ECS,作为阿里云的核心产品,也于2018年11月底上线双栈VPC.双栈ECS,目前正在对外公测中. 那么如何在阿 ...

  6. Android应用框架中的四个核心要点

    Android应用框架中的四个核心要点:活动(Activity).消息(Intent).视图(View).任务(Task) (一)活动Activity Android系统内部有专门的Activity堆 ...

  7. nfs 支持ipv6

    mount 一个ipv6 nfs 项目在docker里mount 一个nfs来读写,而现在需要支持ipv6,所以先写了各小demo,最后成功mount,这里记录一下 #include <sys/ ...

  8. 网络支持IPV6地址测试校验与思考

    概述 大背景:随着移动端的快速扩张,互联网的规模越来越广阔,早于2011年耗尽的IPV4地址越来越无法满足互联网的网络地址需求,IPV6地址推广进入快车道.实际情况:近期公司应上级部门邀请对公司的主域 ...

  9. iOS 支持 IPv6

    苹果的规定:2016年6月1日提交到App Store必须支持IPv6-only网络. 官方文档:https://developer.apple.com/library/mac/documentati ...

随机推荐

  1. Java day1

    1. 学习java,首先是jdk的安装,JDK是 Java 语言的软件开发工具包,主要用于移动设备.嵌入式设备上的java应用程序.JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+ ...

  2. Guava 6:Concurrency

    一.引子 有点经验的工程师一定对多线程比较熟悉,JDK封装的FutureTask实现了这一功能.如下图: FutureTask实现了RunnableFuture接口,而RunnableFuture接口 ...

  3. RouterOS限速更高级运用

    转自这里 一般我们用ros限速只是使用了max-limit,其实ros限速可以更好的运用.比如我们希望客户打开网页时速度可以快一些,下载时速度可以慢一些.ros2.9就可以实现. 看图片 max-li ...

  4. 关于APS在企业生产计划上的应用

    本人本身是一个码农,已经服务了共和国各项事业(好像是说得有点漂,没办法段子看多了)大约一半工作时候了(按60岁退休的话),从一线的小码农,到现在成了老农,出产了不少或优或劣的各种码,几乎啥都做过.近几 ...

  5. 双心一键获取winsxs的写入权限,解决VC运行库安装error1935错误

    @Echo offtitle 双心一键获取winsxs的写入权限,解决VC运行库安装error1935等错误set path=%path%;%~dp0setlocal EnableDelayedExp ...

  6. onOptionsItemSelected、onMenuItemSelected、onContextItemSelected 区别

         1.在点击选项菜单(OptionsMenu:点击menu弹出的菜单)的菜单项时即调用了onMenuItemSelected 也调用了onOptionsItemSelected ,于是疑惑他们 ...

  7. IIC时序详解

    Verilog IIC通信实验笔记 Write by Gianttank 我实验的是 AT24C08的单字节读,单字节写,页读和页写,在高于3.3V系统中他的通信速率最高400KHZ的,我实验里用的是 ...

  8. IDEA—— 找不到或无法加载主类Main

    最近使用idea,编写了一个项目,发现老是找不到main,网上找了一大圈的解决方案,都不行.灵机一动升级了jdk就可以了,之前用的是1.7的,换成了1.8的就好了.

  9. mybatis的typeHandler

    typeHandler作用: 1.传参时将javaType类型转换成jdbcType 2.结果集中ResultSet中取值时,jdbcType转换为javaType; 系统自定义的typeHandle ...

  10. 一些恶作剧的vbs程序代码

    恶作剧的vbs代码,这里提供的都是一些死循环或导致系统死机的vbs对机器没坏处,最多关机重启一下就可以了,将下面的任意一段代码保存为*.vbs即可 循环弹窗: do msgbox "hi&q ...