如何使用Docker Swarm Mode或Docker Compose部署一个IPv6容器

3
最终,我希望通过compose或swarm模式部署一个纯IPv6网络。目前,我只想部署一个仅支持IPv6的单一容器,不关心路由(只需容器之间的连接)。
我的设置:
- 操作系统: Centos 7 - dockerd --ipv6 --fixed-cidr-v6=2001:db8:1::/64 --iptables=true --ip-masq=true --mtu=1600 --experimental=true - docker-engine-17.05.0.ce-1.el7.centos.x86_64.rpm - 主机具有IPv4和IPv6地址。对于两者都开启了转发(这对我并不重要)。
我尝试了似乎每种组合(下面是其中几个示例):
自包含的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将被忽略。


外部预创建的网络 (根据https://dev59.com/JZvga4cB1Zd3GeqPvQKM#39818953

使用以下命令创建docker网络:--driver overlay --ipv6 --subnet=2001:3984:3989::/64 --attachable 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禁用ipv4尝试无法生效。
我目前没有安装docker-compose,下一步可能会尝试,但是在Docker Swarm模式下是否有运行纯IPv6容器的方法?
注意:我可以手动运行和配置一些仅支持IPv6的容器,而不需要Swarm/compose: (如上所述创建网络,甚至只使用默认桥接)
$ 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"
1个回答

0

我能够通过docker-compose进行丑陋的黑客攻击。如果你绝望了,这就是方法。(由于特权升级,此方法在Swarm模式下永远不会起作用)。

计划

  1. 授予容器管理IP的权限
  2. 在每个容器启动时从内部删除IPv4 IP地址。
  3. 使用一个卷来替代DNS(Docker中的DNS仅支持IPv4)。

步骤

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

文件

docker-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"]

server/files/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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接