即使无法获取足够数量的IPv6地址,也可以通过容器内进行IPv6通信

首先

IPv6已到来!我要在容器中使用IPv6!咦,不能获得/48的地址吗?太抠门了…orz

基本上是將以下網站上的內容拼湊而成,感謝。

    • robbertkl/docker-ipv6nat: Extend Docker with IPv6 NAT, similar to IPv4

 

    Ubuntu18.04でDockerコンテナのIPv6を有効にする方法

尽管是IPv6,为什么还要使用NAPT呢?

尽管废除NAPT是IPv6的一个目标,但目前阶段,对于在Docker中使用有限数量的IPv6地址,NAPT仍然是最便捷的解决方案。

我认为IPv6上的NAPT也很令我不舒服,也不是一个理智的做法,但光有美好的想法并不能顺利解决问题。有时候也需要以毒攻毒……真的,请给我一个正常的/64…

只能使用一个IPv6地址的情况下

    ホストで使えるIPv6は 2001:db8:1234:abcd:111:222:333:444/128 のみとします

准备

    • まずホストでちゃんとipv6が通ることを確認

ping6 -n -c 4 www.google.com

dockerdをipv6有効で起動

必要箇所のみ抜粋

{
  "ipv6": true,
  "fixed-cidr-v6": "fd00::/80"
}
    ip6tablesで-t natする
ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADE
ip6tables -t nat -A POSTROUTING -s fd00:1::/80 ! -o docker0 -j MASQUERADE

从容器内部到外部的IPv6访问

    • ping6をしてみる

daemon.jsonに書いてあるfd00::/80から割り当てられる
docker run –rm -t busybox sh -c “ip addr ; ping6 -n -c 4 www.google.com”

docker-composeでnetworks:を指定する場合の例

たとえばfd00:1::/80を明示的に指定する場合

networks:
  default:
    enable_ipv6: true
    ipam:
      config:
        - subnet: fd00:1::/80
    • いずれもip6tablesのMASQUERADEで出ていく

 

    うまくいかないときは、docker container ls, docker network ls等でゴミが残っていないことを確認

从外部到容器内的IPv6访问

    docker-ipv6natの起動
docker run -d --name ipv6nat \
  --privileged \
  --network host \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  -v /lib/modules:/lib/modules:ro \
  robbertkl/ipv6nat
    • コマンドラインの場合: 省略

 

    docker-composeの場合:
services:
  httpd6:
    image: busybox
    container_name: httpd6
    ports:
      - 8080:80
    command:
      - sh
      - -c
      - 'echo Hello world > index.html && httpd -f -v'
    • テスト

curl -v [2001:db8:1234:abcd:111:222:333:444]:8080

docker logs test でアクセス元が見える

如果能够使用不太多但可以指定的大量IPv6地址

例子

2001:db8:1234:abcd:111:222:333:444/128 がホストのIPv6アドレス

2001:db8:1234:abcd:a111:222:333:444{0,1,2,3…f}/128 が使用可能で、これをコンテナで使いたい

2001:db8:1234:abcd:a111:222:333::/112 をダミーのsubnetとする
要するに美雲このはちゃん

IPv6をVPSへ設定する|ConoHa VPSサポート

docker网络连接版本

    • ip -6つなげる

ip -6 addr add 2001:db8:1234:abcd:a111:222:333:4440/128 dev eth0

daemon.json, MASQUERADE, docker-ipv6natは前節と同じ
network作成

docker network create –ipv6 –subnet=2001:db8:1234:abcd:a111:222:333::/112 –gateway=2001:db8:1234:abcd:a111:222:333:4440 ipv6_exposed_hosts
gatewayで指定したのが外に露出する

2001:db8:1234:abcd:a111:222:333:dead をダミーとして使う

これはダミーなので、外からの経路はなくてもいい

コマンドラインの場合:

docker network connect –ip6 2001:db8:1234:abcd:a111:222:333:dead ipv6_exposed_hosts httpd6

docker-composeの場合:

networks:
  ipv6_exposed_hosts:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 2001:db8:1234:abcd:a111:222:333::/112
          gateway: 2001:db8:1234:abcd:a111:222:333:4440
services:
  httpd6:
    image: busybox
    container_name: httpd6
    ports:
      - 8080:80
    command:
      - sh
      - -c
      - 'echo "Hello world!" > index.html && httpd -f -v'
    networks:
      ipv6_exposed_hosts:
        ipv6_address: 2001:db8:1234:abcd:a111:222:333:dead
    • テスト

curl -6 [2001:db8:1234:abcd:a111:222:333:4440]:8080

ip6tables -t nat -j 使用 DNAT 规则

    • ip -6つなげる

ip -6 addr add 2001:db8:1234:abcd:a111:222:333:4440/128 dev eth0

daemon.json, MASQUERADEは前節と同じ
コンテナを普通に立ち上げる
そのコンテナのIPv6アドレスを取得(上記でいう末尾dead、無指定ならfd00::から選ばれるので調べる)

docker container inspect httpd6 | jq .[0].NetworkSettings.Networks[].GlobalIPv6Address

ip6tables -j DNATで繋げる

ip6tables -t nat -I DOCKER -i eth0 -d 2001:db8:1234:abcd:a111:222:333:4440 -p tcp -m tcp –dport 8080 -j DNAT –to-destination [${上記アドレス}]:80

テスト

curl -6 [2001:db8:1234:abcd:a111:222:333:4440]:8080

nd 代理版

    ホストのeth0にip aliasを追加するのではなく、nd proxyを繋げる
sysctl -w net.ipv6.conf.all.forwarding=1
sysctl -w net.ipv6.conf.eth0.proxy_ndp=1
ip -6 neigh add proxy 2001:db8:1234:abcd:a111:222:333:4441 dev eth0
    docker-composeであげる
networks:
  ipv6_exposed_hosts:
    driver: bridge
    enable_ipv6: true
    ipam:
      config:
        - subnet: 2001:db8:1234:abcd:a111:222:333::/112
services:
  httpd6:
    image: busybox
    container_name: httpd6
    command:
      - sh
      - -c
      - 'echo "Hello world!" > index.html && httpd -f -v'
    networks:
      ipv6_exposed_hosts:
        ipv6_address: 2001:db8:1234:abcd:a111:222:333:4441
    • ipv6_exposed_hostsのidを調べる

docker network ls

ufwで穴をあけて経路繋げる

ufw route allow in on eth0 out on br-${上記netowrkidの先頭}

テスト

curl -6 [2001:db8:1234:abcd:a111:222:333:4441]:80

通过ip6tables对容器地址通信进行过滤

    通常、IPv4のコンテナ宛はFORWARD(の子のDOCKER-USER)でフィルタリングしますが、この記事のnd proxy版以外の方法の場合INPUT chainになります

最后

    • IPv6アドレスもっとください。

 

    awsさん、IPv4は捨てるんで別に有償でも構わないけどEIPはIPv6対応しないんですか?

借鉴资料

    • IPv6 Subnet Calculator – subnettingpractice.com

 

    • DockerのコンテナにIPv6で接続すると接続元IPアドレスがコンテナネットワーク内のIPv4アドレスになる – Qiita

 

    • robbertkl/docker-ipv6nat: Extend Docker with IPv6 NAT, similar to IPv4

 

    • Ubuntu18.04でDockerコンテナのIPv6を有効にする方法

 

    • docker-composeでnginxをIPv6化 | mahori ブログ 本館

 

    RPi4 – Docker with IPv6 and Docker Compose
广告
将在 10 秒后关闭
bannerAds