返回
Featured image of post 一个简单开启 Docker IPv6 的方法

一个简单开启 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
{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}

似乎不适用,因为这个配置是固定的前缀,而运营商给的是通过 PD 下发的动态前缀,这个方法应该主要是面向服务器应用场景的,服务器有固定的 IP,通常还有可以得到一个前缀来使用,这样就可以通过上面的方法配置使容器都得到一个公网 IPv6 地址,这样配置就满足了情况一,但是,每个容器都有公网地址,有必要吗?似乎没有什么应用场景,主要是通常一个公网 IP 都对应一套防火墙配置,而如果每个容器都有 IP 了,容器的防火墙怎么搞?而我真正想达到的目的,只是想让容器可以访问 IPv6 网络,其他无所谓。

这样就类似 IPv4 情况了,IPv4 情况下,只有一个公网 IP,容器通过 NAT 连网,防火墙只需要配置宿主机的,IPv6 也可以达到同样的效果,就是 「IPv6 NAT」,不过需要额外的一点配置

  1. 配置中的 fixed-cidr-v6 改成一个 ULA 前缀,比如 fd00:dead:beef::/48
  2. 运行 Docker 容器 https://github.com/robbertkl/docker-ipv6nat#docker-container 命令不用改,直接运行就可以
  3. 把需要 IPv6 的容器中加入 bridge 网络

如何加入 bridge 网络

  1. docker run 时,加上 --network bridge 参数,如 docker run -it --network bridge --rm cielpy/curl-http3:7.76.0-0.7.0 curl -V
  2. docker-compose 配置中,加上 network_mode: bridge

这样,就可以访问 IPv6 网络了,比如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
➜  ~ docker run -it --network bridge  --rm cielpy/curl-http3:7.75.0-0.7.0 curl -ILv --http3 --max-time 8 https://www.cloudflare.com/ -6
*   Trying 2606:4700::6810:7c60:443...
* Connect socket 5 over QUIC to 2606:4700::6810:7c60:443
* Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27
* Connected to www.cloudflare.com () port 443 (#0)
* h3 [:method: HEAD]
* h3 [:path: /]
* h3 [:scheme: https]
* h3 [:authority: www.cloudflare.com]
* h3 [user-agent: curl/7.75.0-DEV]
* h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x555c4c7b4190)
> HEAD / HTTP/3
> Host: www.cloudflare.com
> user-agent: curl/7.75.0-DEV
> accept: */*
>
< HTTP/3 200
HTTP/3 200
< date: Wed, 31 Mar 2021 08:45:20 GMT
date: Wed, 31 Mar 2021 08:45:20 GMT
< content-type: text/html; charset=utf-8
content-type: text/html; charset=utf-8
< set-cookie: __cfduid=dfc666f32c2ecb7a932e7d34cb422f7e01617180320; expires=Fri, 30-Apr-21 08:45:20 GMT; path=/; domain=.www.cloudflare.com; HttpOnly; SameSite=Lax; Secure
set-cookie: __cfduid=dfc666f32c2ecb7a932e7d34cb422f7e01617180320; expires=Fri, 30-Apr-21 08:45:20 GMT; path=/; domain=.www.cloudflare.com; HttpOnly; SameSite=Lax; Secure
< cache-control: max-age=120
cache-control: max-age=120
< strict-transport-security: max-age=31536000
strict-transport-security: max-age=31536000
< x-content-type-options: nosniff
x-content-type-options: nosniff
< x-frame-options: SAMEORIGIN
x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
x-xss-protection: 1; mode=block
< cf-request-id: 09290e79a90000eef26b36e000000001
cf-request-id: 09290e79a90000eef26b36e000000001
< expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< set-cookie: __cf_bm=dae0cb4010ec3e3cae3ed5334d4f096877df271c-1617180320-1800-Aek+hf3elzDbv140HFOhxCs/gpOpmRWr8RVa4VtfW2+qZGe+tiQsjU9T2dlwgyDEU9KnPw1DGYlSsfkcyT7UNDUNfVDyol9kYfF+SoS7tZ4b; path=/; expires=Wed, 31-Mar-21 09:15:20 GMT; domain=.www.cloudflare.com; HttpOnly; Secure; SameSite=None
set-cookie: __cf_bm=dae0cb4010ec3e3cae3ed5334d4f096877df271c-1617180320-1800-Aek+hf3elzDbv140HFOhxCs/gpOpmRWr8RVa4VtfW2+qZGe+tiQsjU9T2dlwgyDEU9KnPw1DGYlSsfkcyT7UNDUNfVDyol9kYfF+SoS7tZ4b; path=/; expires=Wed, 31-Mar-21 09:15:20 GMT; domain=.www.cloudflare.com; HttpOnly; Secure; SameSite=None
< report-to: {"group":"cf-nel","endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=l%2Bk7DdqqOTHsYAGVH1Z1wX2HFPFnvjvAtJCqzAfCfJ5xHby4cKDLOQBSO7ZQFIA9qFgDJO%2Bhgl99ekIP1k2HDEzV9glsJt3kTG6gvuc2W3P8HvOCR0adBngnEBZ2Rxg%3D"}],"max_age":604800}
report-to: {"group":"cf-nel","endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=l%2Bk7DdqqOTHsYAGVH1Z1wX2HFPFnvjvAtJCqzAfCfJ5xHby4cKDLOQBSO7ZQFIA9qFgDJO%2Bhgl99ekIP1k2HDEzV9glsJt3kTG6gvuc2W3P8HvOCR0adBngnEBZ2Rxg%3D"}],"max_age":604800}
< nel: {"report_to":"cf-nel","max_age":604800}
nel: {"report_to":"cf-nel","max_age":604800}
< server: cloudflare
server: cloudflare
< cf-ray: 63884d090ce3eef2-LAX
cf-ray: 63884d090ce3eef2-LAX
< alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400
alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400
* Connection #0 to host www.cloudflare.com left intact

且容器没有公网地址,不用担心防火墙配置问题。

总结

  1. 如果有固定的 IP 前缀可以使用,可以使用官方的方法,使每个容器都有一个 IPv6 公网地址
  2. 如果仅仅是希望容器可以访问 IPv6 资源,且不想管容器的防火墙,那么可以使用 IPv6-nat
  3. 如果没有固定的前缀还希望每个容器有公网 IP,目前没有查到相关资料
Built with Hugo
Theme Stack designed by Jimmy