Docker IPv6

Docker IPv6

Created
Oct 4, 2021 08:01 AM
Tags
Docker
Published
Oct 4, 2021
Description
IPv6 in Docker along with gluetun
看完就感觉Docker对IPv6的支持还差很多

Experimental

步骤

docker 容器开启ipv6
容器中开启ipv6的方式可能有很多,其中一种就是在容器中分配公网ipv6地址,但是这样做就把容器中的端口全暴露到了公网中,用ip6tables 也不好管理,不安全。建议使用ipv6 nat的方式。 ipv6 nat 就是在容器中分配一个私有的ipv6地址,这和目前常用的ipv4桥接模式没有区别。 开启ipv6有什么好处,说下我的使用场景: 最近在树莓派(Ubuntu 20.04.1 LTS)中部署了aria2 进行bt下载(使用容器部署),但是没有真实的ipv4公网地址(因为是长沙移动的宽带), 如果开启ipv6, 就可以和其他的ipv6用户直接通讯了,理论上寻找资源和下载速度会提高。 开始之前: 宿主机已经有ipv6地址 了, (如果没有请先确认你的运营商是否支持,请自行网上冲浪找答案。 ) ifconfig 查看, inet6 为 global的ip就是ipv6地址 docker engine 的版本大于等于20.10.2,因为这个版本才开始支持ip6tables。(如果小于这个版本,就要用第三方的工具管理ip6tables的nat规则: robbertkl/docker-ipv6nat ) 正式开始: 编辑 /etc/docker/daemon.json ,加上以下内容。(如果没有这个文件直接创建。) 重启docker engine sudo systemctl restart docker 测试 sudo docker run --rm -it busybox ping -6 -c4 ipv6-test.com sudo docker run --rm -it busybox ifconfig 能ping通ipv6的公网地址了。容器中的eth0 也有fd00::/80段的地址。完成! 下面给一个我在用的aria2的docker-compose.yaml 可以上面这个网站扫描ipv6端口。
docker 容器开启ipv6
方法来自这个知乎的文章,但是这个daemon的选项,除了在一个issue里面,就没有搜到了,也不知道有没有进文档
修改 /etc/docker/daemon.json
{
  "ipv6": true,
  "fixed-cidr-v6": "fd00::/80",
  "experimental": true,
  "ip6tables": true
}
然后重启
sudo systemctl restart docker
然后默认的bridge的network就会有ipv6了
sudo docker run --rm -it busybox ping -6 -c4 ipv6-test.com
sudo docker run --rm -it busybox ifconfig
notion image
notion image
对于docker-compose,把网络修改为 network_mode: bridge 就可以了,

问题

1

我想创建一个新的网络,而不是用默认的网络
参考这个里面的docker compose https://github.com/qdm12/gluetun/issues/425
...
		networks:
      - gluetun
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=0

networks:
  gluetun:
    enable_ipv6: true
但是 docker-compose up 的时候会发生下面的错误
error: could not find an available, non-overlapping ipv6 address pool among the defaults to assign to the network
重写默认的network也会报相同的错误
networks:
  default:
    enable_ipv6: true

2

在最开始看到这个文章的时候,能够拿到ipv6的地址,也可以正常的使用,但是给gluetun的docker compose加上了network_mode的时候,在日志里面可以看到报错
ERROR vpn: cannot add route for interface: permission denied: when adding route: {Ifindex: 2 Dst: ::/0 Src: <nil> Gw: <nil> Flags: [] Table: 51820}
在里面查看网卡,发现 wg0 的网卡是没有正常运行起来的,然后就去看其他的东西了
但是尝试了很多东西之后,又试了试这个方法,发现正常了?
upd: 通过撤销发现,是我在尝试这个方法的时候,把之前的给删掉了
		sysctls:
      net.ipv6.conf.all.disable_ipv6: 0
但是在知乎的文章里面并没有配置这个参数,搞不懂为什么就可以了,并且在上面的docker run里面也是能够使用的
upd2: 发现不加 sysctls 的时候是 permission denied,并且进容器里面看, disable_ipv6 = 1
$ sysctl net.ipv6.conf.all.disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 1
查看ip的话,是拿到了ipv6的地址
406: eth0@if407: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fd00::242:ac11:2/80 scope global nodad 
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever
但是加了 sysctls 但是手动配置了 disable_ipv6 = 1 ,进容器里面看
$ sysctl net.ipv6.conf.all.disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 1
并且没有拿到ipv6的地址
408: eth0@if409: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
报错是报连不上导致的问题
ERROR peer(bmXO…fgyo) - Failed to send handshake initiation: cannot assign requested address

network: host

看起来用 host 的网络是最方便的
docker run ... --network=host ...
docker-compose.yaml
network_mode: host
但是这个不可以和gluetun直接用在一起,会出大问题

文档

文档里面就一点点,在 /etc/docker/daemon.json 里面设置 "ipv6": true ,并添加合适的前缀
{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}
最开始看到的就是这个,然后也没有改前缀,在docker compose里面设置了一下
		sysctls:
      - net.ipv6.conf.all.disable_ipv6=0
进容器里面之后,的确eth0有ipv6的本地地址了,但是ping外面的话是ping不通的,显示Unreachable Network,就是坏了
看到了这个,说要改合适的前缀,但是现在拿到的运营商给的ipv6的前缀一般而言也不是固定的,也会有防火墙的问题。也就没去试设置合适的前缀的方法了,对于后面的IPv6 NAT的方法,感觉不那么阳间,并且在看到这个文章的时候,也同时在看上面的用了experiment方法的文章,感觉这个不如上面的好用,也就没有尝试了
一个简单开启 Docker IPv6 的方法
配图: rows of yellow lounge chairs photo - Free Image on Unsplash IPv6 有了,运营商用 PD 协议下发了 240e:3b7:xxx:xxx::/60 这个前缀,理论上,就可以随便分配 IP 给下游设备了,虚机机之类的如果可以桥接,也是没有问题的,那 Docker 可以吗?Docker 支持 IPv6 大概有两种情况 每个容器都有 IPv6 地址 每个容器能访问 IPv6 网络,但是没有公网 IP 地址 官方对 IPv6 的支持不太积极,macOS 上的一些问题一起挂着没有解决,可能 macOS 比较特殊吧,官方文档中提到 IPv6 的支持很简单,需要修改 /etc/docker/daemon.json,加入两个选项 1 2 3 4 { &#34;ipv6&#34;: true, &#34;fixed-cidr-v6&#34;: &#34;2001:db8:1::/64&#34; } 似乎不适用,因为这个配置是固定的前缀,而运营商给的是通过 PD 下发的动态前缀,这个方法应该主要是面向服务器应用场景的,服务器有固定的 IP,通常还有可以得到一个前缀来使用,这样就可以通过上面的方法配置使容器都得到一个公网 IPv6 地址,这样配置就满足了情况一,但是,每个容器都有公网地址,有必要吗?似乎没有什么应用场景,主要是通常一个公网 IP 都对应一套防火墙配置,而如果每个容器都有 IP 了,容器的防火墙怎么搞?而我真正想达到的目的,只是想让容器可以访问 IPv6 网络,其他无所谓。 这样就类似 IPv4 情况了,IPv4 情况下,只有一个公网 IP,容器通过 NAT 连网,防火墙只需要配置宿主机的,IPv6 也可以达到同样的效果,就是 「IPv6 NAT」,不过需要额外的一点配置
一个简单开启 Docker IPv6 的方法
并且也没有看懂文档里面的 --ipv6 的flag对应到docker compose应该是哪个,不太清楚这个改如何进行配置

iptables

这个没有尝试

docker-ipv6nat

这个也没有尝试