我的环境:
- OS: CentOS 7.9
- Docker:20.10.7
1. 启用Docker守护进程对ipv6的支持
要想在Docker容器或者Swarm服务中使用ipv6,首先需要在Docker守护进程中启用对ipv6的支持,具体做法如下:
-
编辑docker守护进程的配置文件
/etc/docker/daemon.json
(若不存在需要手动创建该文件){ "experimental": true, "ip6tables": true, "ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64" }
ipv6
设置为true,启用对ipv6的支持。fixed-cidr-v6
,配置ipv6子网。ip6tables
,启用ip6tables,docker会在ip6tables中配置docker网络相关的规则链。experimental
,启用实验特性,ip6tables是docker的一个实验功能,所以需要设为true。 -
重载配置文件
sudo systemctl reload docker && sudo systemctl restart docker
现在你可以使用
docker network create --ipv6 ...
创建一个支持ipv6的网络了。另外你也可以在启动容器时使用--ip6
参数来使容器支持ipv6。 -
审查默认
bridge
网络sudo docker network inspect bridge
可以看到已经配置成功!
接下来就可以在容器中使用ipv6了!
2. 在Docker容器中使用ipv6
注意:以下演示依赖于上一步的配置
2.1 创建一个容器
使用nginx做演示:
启动一个容器,此处并没有指定网络所以默认使用名为bridge
的网络,该网络在上一步已经支持ipv6了!
docker run --name test -p 81:80 -d nginx:1.21.6
进入容器内部查看网阔配置:
$ docker exec -it test ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.156.10.2 netmask 255.255.255.0 broadcast 10.156.10.255
inet6 fe80::42:aff:fe9c:a02 prefixlen 64 scopeid 0x20<link>
inet6 2001:db8:1::242:a9c:a02 prefixlen 64 scopeid 0x0<global>
ether 02:42:0a:9c:0a:02 txqueuelen 0 (Ethernet)
RX packets 3923 bytes 9184337 (8.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2836 bytes 192127 (187.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
容器内部已经分配了一个ipv6地址!
2.2 容器与宿主机通信
在上一步容器已经有一个ipv6地址了,但是如果宿主机没有一个合适的ipv6地址还是不能通过ipv6与宿主机通信。比如下面我用的宿主机网络配置:
$ ifconfig ens192
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.30.72 netmask 255.255.0.0 broadcast 192.168.255.255
inet6 fe80::54f2:a4e2:f5cc:711a prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c7:26:f5 txqueuelen 1000 (Ethernet)
RX packets 38098236 bytes 6981689290 (6.5 GiB)
RX errors 0 dropped 3567426 overruns 0 frame 0
TX packets 953026 bytes 578286181 (551.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
尽管该接口有一个ipv6地址fe80::54f2:a4e2:f5cc:711a
但是它是本地链路上的私有地址(fe80开头的地址属于私有地址)。私有地址是允许在本地链路上使用,且数据包不会跨链路转发。
所以,容器要想和宿主机通信,宿主机必须有一个非私有ipv6地址,如果默认没有就需要手动配置一个:
编辑网络接口配置文件/etc/sysconfig/network-scripts/ifcfg-ifName
,例如我的测试宿主机网卡名称为ens192
,那就编辑/etc/sysconfig/network-scripts/ifcfg-ens192
:
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6_DEFROUTE=yes
IPV6_PRIVACY=no
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
IPV6ADDR=2018::27
NAME=ens192
UUID=08b8bead-340c-4708-8656-2af2394a7c1c
DEVICE=ens192
ONBOOT=yes
IPADDR=192.168.30.72
PREFIX=16
GATEWAY=192.168.30.1
DNS1=223.5.5.5
保存,执行网络服务重启:
sudo systemctl restart network
查看网卡配置:
$ ifconfig ens192
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.30.72 netmask 255.255.0.0 broadcast 192.168.255.255
inet6 2018::27 prefixlen 64 scopeid 0x0<global>
inet6 fe80::54f2:a4e2:f5cc:711a prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c7:26:f5 txqueuelen 1000 (Ethernet)
RX packets 38106119 bytes 6982319769 (6.5 GiB)
RX errors 0 dropped 3568059 overruns 0 frame 0
TX packets 953451 bytes 578328655 (551.5 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
再次进行容器内ping宿主机:
$ sudo docker exec -it test ping6 2018::27
PING 2018::27(2018::27) 56 data bytes
64 bytes from 2018::27: icmp_seq=1 ttl=64 time=0.135 ms
64 bytes from 2018::27: icmp_seq=2 ttl=64 time=0.137 ms
64 bytes from 2018::27: icmp_seq=3 ttl=64 time=0.145 ms
64 bytes from 2018::27: icmp_seq=4 ttl=64 time=0.137 ms
64 bytes from 2018::27: icmp_seq=5 ttl=64 time=0.152 ms
^C
--- 2018::27 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.135/0.141/0.152/0.006 ms
已经通了!
3. 使docker-compose 编排文件启动的服务支持ipv6
以下操作也须在docker引擎开启ipv6下进行。
3.1 对于版本2的编排文件
对于版本2的编排文件,可以直接在networks
配置节点下启用ipv6,下面是个例子:
version: '2'
# 其他services定义省略。。。
networks:
example:
enable_ipv6: true
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "true"
ipam:
config:
- subnet: 172.23.0.0/16
- subnet: "2607:f0d0:1002:51:4000::/66"
3.2 对于版本3的编排文件
对于版本3的编排文件,无法像上边那样直接在编排文件中配置网络并开启ipv6,需要按照下面的方式进行:
首先需要通过命令行创建一个网络并启用ipv6:
$ sudo docker network create -d bridge \
--ipv6 --subnet 2001:db8:1::1/64 \
--subnet 10.156.11.0/24 extnetwork
通过上面的命令创建了一个子网为2001:db8:1::1/64
的名字为extnetwork
的ipv6网络且支持ipv4。文章来源:https://www.toymoban.com/news/detail-430708.html
编排文件:文章来源地址https://www.toymoban.com/news/detail-430708.html
version: '3'
services:
app:
image: app:7.16.1
container_name: app
restart: always
privileged: true
networks:
- extnetwork
#省略其他服务。。。
networks:
extnetwork:
external: true
到了这里,关于启用Docker对ipv6的支持的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!