如何使用Docker Swarm模式或Docker Compose部署IPv6容器

最后,我想通过组合或群集模式部署纯IPv6networking。 现在,我只想使用IPv6(仅)部署一个容器。 我目前不感兴趣的路由(只是容器到容器连接)。

我的设置:

  • 操作系统:Centos 7
  • dockerd –ipv6 –fixed-cidr-v6 = 2001:db8:1 :: / 64 –iptables = true –ip-masq = true –mtu = 1600 –experimental = true
  • 泊坞窗,发动机17.05.0.ce-1.el7.centos.x86_64.rpm
  • 主机有IPv4和IPv6地址。 转发对这两个(不是对我来说很重要)。

我试过似乎每一种组合(我只列出一对夫妇)

独立的容器和networking的Docker堆栈:

version: '3' networks: app_net: driver: overlay driver_opts: com.docker.network.enable_ipv6: "true" ipam: driver: default config: - subnet: 172.16.238.0/24 - subnet: 2001:3984:3989::/64 services: app: image: alpine command: sleep 600 networks: app_net: ipv4_address: 0.0.0.0 ipv6_address: 2001:3984:3989::10 

结果:只有容器中的IPv4地址,0.0.0.0被忽略。


外部预先创build的networking (按照https://stackoverflow.com/a/39818953/1735931 )

dockernetworking创build – 驱动程序覆盖–ipv6 –subnet = 2001:3984:3989 :: / 64 – 可附加ext_net

 version: '3' networks: ext_net: external: name: ext_net services: app: image: alpine command: ifconfig eth0 0.0.0.0 ; sleep 600 cap_add: - NET_ADMIN networks: ext_net: ipv4_address: 0.0.0.0 ipv6_address: 2001:3984:3989::10 

结果:容器中的IPv4和IPv6地址都被忽略,但cap_add被忽略(Swarm模式中不支持),因此ifconfig disable ipv4尝试失败。

我目前没有安装Docker -compose,下次可能会尝试,但是有没有办法在Docker Swarm模式下运行纯IPv6容器?

注意:我可以手动运行和configuration几个仅支持IPv6的容器,而不需要swarm / compose :(创build上面的networking,甚至只使用默认网桥)

 $ docker run --cap-add=NET_ADMIN --rm -it alpine $$ ifconfig eth0 0.0.0.0 $$ ping6 other-container-ipv6-address # WORKS! 

或简写:

 $ docker run --cap-add=NET_ADMIN --rm -it alpine sh -c "/sbin/ifconfig eth0 0.0.0.0 ; sh" 

我可以用docker工作人员通过严重的丑陋手段来破解它。 如果你绝望,就在这里。 (由于权限提升,此方法无法用于Swarm模式)。

计划

  1. 授予容器pipe理IP的权限
  2. 在启动时从每个容器中删除IPv4 IP地址。
  3. 使用卷即兴主机文件来代替DNS(DNS仅在docker中为IPv4)。

脚步

  1. 在Docker守护进程中启用IPv6 。
  2. 创build一个docker-compose.yml文件,创build一个ipv6networking,共享文件的卷和两个容器
  3. 在执行上述步骤的每个容器中运行入口点脚本。

泊坞窗,compose.yml

 # Note: enable_ipv6 does not work in version 3! version: '2.1' networks: app_net: enable_ipv6: true driver: overlay ipam: driver: default config: - subnet: 172.16.238.0/24 - subnet: 2001:3984:3989::/64 services: app1: build: ./server hostname: server1 command: blablabla # example of arg passing to ipv6.sh cap_add: - NET_ADMIN volumes: - ipv6stuff:/ipv6stuff networks: - app_net app2: build: ./server hostname: server2 command: SOMETHING # example of arg passing to ipv6.sh cap_add: - NET_ADMIN volumes: - ipv6stuff:/ipv6stuff networks: - app_net volumes: ipv6stuff: 

服务器/ Dockerfile

 FROM alpine:latest ADD files / RUN apk --update add bash #simpler scripts # Has to be an array for parameters to work via command: x in compose file, if needed ENTRYPOINT ["/ipv6.sh"] 

服务器/文件/ ipv6.sh

 #!/bin/bash # Optionally conditional logic based on parameters here... # (for example, conditionally leave ipv4 address alone in some containers) # # Remove ipv4 ifconfig eth0 0.0.0.0 IP6=$(ip addr show eth0 | grep inet6 | grep global | awk '{print $2}' | cut -d / -f 1) echo "Host $HOSTNAME has ipv6 ip $IP6" # Store our entry in the shared volume echo "$IP6 $HOSTNAME" > /ipv6stuff/hosts.$HOSTNAME # Remove existing ipv4 line from /etc/hosts just to be thorough # Docker does not allow removal of this file and thus simple sed -i isn't going to work. cp /etc/hosts /tmp/1 ; sed -i "s/^.*\s$HOSTNAME//" /tmp/1 ; cat /tmp/1 > /etc/hosts # Wait for all containers to start sleep 2 # Put everyone's entries in our hosts file. cat /ipv6stuff/hosts.* >> /etc/hosts echo "My hosts file:" cat /etc/hosts # test connectivity (hardcoded) ping6 -c 3 server1 ping6 -c 3 server2