我正在尝试解决我的docker网络设置问题,(docker 容器给出空白的 ipv6 地址)
我无法通过 localhost 上的 ipv6 访问服务,curl -4 http://localhost:8080
因此我必须使用curl http://localhost:8080
在调查时,我发现 docker ingress 网络没有启用 ipv6,因此我删除了旧的网络,并创建了具有 ipv6 地址的新 ingress 网络
sunils@sunils-pc ~ $ docker network inspect ingress
[
{
"Name": "ingress",
"Id": "8sn7034q646ayadix9nmsmv50",
"Created": "2018-09-29T04:42:10.857389865Z",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": true,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.11.0.0/24",
"Gateway": "172.11.0.1"
},
{
"Subnet": "2002:ac0b:0000::/48",
"Gateway": "2002:ac0b::1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": true,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": null,
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4106,4107"
},
"Labels": null
}
]
还创建了ipv6_overlay
我将在容器中使用的新覆盖网络,
sunils@sunils-pc ~ $ docker network inspect ipv6_overlay
[
{
"Name": "ipv6_overlay",
"Id": "n7fv85sqhm0wd1ekpo8evnit2",
"Created": "2018-09-29T06:47:17.363996665Z",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": true,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.10.0.0/24",
"Gateway": "172.10.0.1"
},
{
"Subnet": "2002:ac0a:0000::/48",
"Gateway": "2002:ac0a::1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": null,
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4113,4114"
},
"Labels": null
}
]
我将容器配置为使用具有预定义 IP 地址的覆盖网络 ipv6_overlay,
sunils@sunils-pc /mnt/share/sunils/repos/github/ec2-sample-docker $ cat docker-compose.yml
version: '3.2'
services:
sessions:
image: redis:4
ports:
- 6379:6379
networks:
web:
ipv4_address: 172.10.0.10
ipv6_address: 2002:ac0a:0000::10
aliases:
- redis
cowsay-service:
image: spsarolkar/cowsay
ports:
- 8000
environment:
- SERVICE_PORTS=8000
deploy:
replicas: 5
restart_policy:
condition: on-failure
max_attempts: 3
window: 120s
networks:
web:
ipv4_address: 172.10.0.9
ipv6_address: 2002:ac0a:0000::9
cowsay-proxy:
image: dockercloud/haproxy
depends_on:
- cowsay-service
environment:
- BALANCE=leastconn
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "8000:80"
networks:
web:
ipv4_address: 172.10.0.8
ipv6_address: 2002:ac0a:0000::8
aliases:
- cowsay
cowsay-ui:
image: spsarolkar/cowsay-ui
ports:
- "[::1]:8080:8080"
depends_on:
- redis
- cowsay
networks:
web:
ipv4_address: 172.10.0.7
ipv6_address: 2002:ac0a:0000::7
networks:
web:
external:
name: ipv6_overlay
但是当我启动我的 Swarm 服务时,出现错误/var/log/docker.log
,
time="2018-09-29T12:09:19.693307864+05:30" level=error msg="fatal task error" error="Invalid address 2002:ac0b::2: It does not belong to any of this network's subnets" module=node/agent/taskmanager node.id=luqw5to6dike43h88h25xj7tg service.id=tfttw36jqmsq3ew6wzn61gyku task.id=7jo89apxj585pdtacmr2d7jpe
我不确定即使我在 docker compose 中指定了自己的覆盖网络,它是否会回退到 ingress 网络。当我不指定任何 ip 地址时,我也会收到同样的错误。
有人可以帮我吗
答案1
我的情况完全一样,到目前为止我还没有想出真正的解决方案,而只是想出了一个简单的解决方法。我尝试创建不同类型的ingress
网络,修改docker_gwbridge
等等,但 IPv6 支持很差。即使在这个时代......
所以我想到的解决方法是。我创建了一个在之后启动的socat
小服务,因此它应该具有相当的弹性。假设您的实际服务想要监听端口 8080,那么就让它监听 8081 并从 8080 到 8081 socat IPv6 连接。systemd
docker.service
socat -ly TCP6-LISTEN:8080,fork,reuseaddr,bind=<my_ipv6_addr> TCP:0.0.0.0:8081
那里的绑定是可选的,但如果您想限制访问,它很方便。单位systemd
如下():/etc/systemd/system/[email protected]
[Unit]
Description=socat for docker swarm (%i)
After=docker.service
[Service]
Type=simple
EnvironmentFile=/etc/socat-%i.conf
ExecStart=/usr/bin/socat -ly TCP6-LISTEN:${SOURCEPORT},fork,reuseaddr TCP:0.0.0.0:${TARGETPORT}
Restart=on-failure
[Install]
WantedBy=multi-user.target
并且 env 文件仅包含两行为其提供端口,例如(/etc/socat-viz.conf
):
SOURCEPORT=8080
TARGETPORT=8081
我在示例中运行的服务是Docker Swarm 可视化工具。
docker service create \
--name=viz \
--publish published=8081,target=8080 \
--constraint=node.role==manager \
--mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
dockersamples/visualizer
然后只需启用并启动systemd
服务就可以了。
sudo systemctl enable [email protected]
sudo systemctl start [email protected]
答案2
Swarm 模式似乎不支持使用 ingress/service-mesh 网络的 IPv6。未决问题我建议您订阅并点赞以获得更多关注,不过目前,这将由社区或 Mirantis 来提供更新(据我所知,Docker 还没有为它分配任何开发人员)。
解决方法是,您可以跳过入口,部署一个具有“主机”网络模式的全局服务,该服务将同时接收 IPv4 和 IPv6。如果该服务是代理(如 traefik),它可以使用覆盖网络和容器的 IPv4 地址将请求路由到集群中的每个容器。以下是包含关键设置的部分撰写文件:
version: '3.8'
services:
proxy:
deploy:
mode: global
ports:
- target: 80
published: 80
protocol: "tcp"
mode: "host"
# ...