kobar9568のブログ

技術的なメモやその他諸々

Docker 20.03.2以降、デフォルト設定ではIPv6のポートが公開されなくなったっぽい(2021-03-05時点)

忙しい人向け

  • Docker 20.10.2の仕様変更で、インストール直後のデフォルト状態ではIPv6のポートがマッピングされなくなった。
  • 2021-03-05時点では、IPv6アドレッシング等のインフラを変えたくない場合はDocker 20.10.1を使う
    • 2021-03-04にリリースされたDocker 20.10.5時点で、この仕様変更はロールバック等はされていない。
  • ざっとissueを眺めた感じ、仕様変更と別に、IPv6のポートフォワード周りに問題が生じてるのかも?(未検証)

    • コンテナにユニークローカルユニキャストアドレス(ULA)を割り当てて、DockerホストのアドレスをNAPT(NAT66)で使った環境とかだと問題が起きてるのかもしれない?(未検証)
      • グローバルユニキャストをコンテナに回してくる、IPv6の考えとしてはあるべき構成も試してないのでこちらも不明
  • 動向はmobyのこの辺のissueを追ってると良さそう

以下色々試してた時の日記

問題発生

  • ESXiの導入とともにDockerホストもそちらに仮想マシンとして移設し、暫く運用していた。
  • Dockerに載せているMinecraftサーバーにIPv6で繋ごうとした友人から、繋がらないとの話があった。IPv4では問題なし。
  • 最初はAAAAを疑ったのだが、これは問題無し。経路中のルータのIPv6ファイアウォールsh access-listsで確認したが問題無くマッチしている。
  • おかしいと思って確認したところ、同一セグメントからもIPv6では繋がらない事が発覚。 グローバルユニキャストもリンクローカルもダメ。

パケットの調査

  • 取り敢えずパケットを取ってみたところ、クライアントからのTCP 3way-handshakeのSYNのパケットが出た後、サーバーが即RST,ACKを返して仮想回線の確立を拒否し、クライアントが接続要求を再送し、RSTを送りつけられる…という動きをしていた。
    • L3でのリーチャビリティはあるが、ポートが空いていない時に明示的に通信を切る動作。Webサービス(Dynmap)にブラウザで繋ごうとするとConnection refusedとなる。
    • 実際にICMPv6は通っており、ping6は成功していた。
  • IPv4では問題無くサービスが動作しており、IPv6のみこの現象が起きていた。

迷走

  • 私の環境ではESXiホストにしているマシン(普通の自作パソコンを流用)のオンボードNICRealtek RTL8111Gであり、これはESXi 7.0に対応しておらず、インストールすることが出来ない。
  • その為、USB3.0 to EthernetのチップであるASIX AX88179を搭載したUSBNICであるELECOM EDC-GUA3-Bを使っていた。
    • flingsで公開されているドライバを組み込んだイメージをインストールしたもので、ネットワーク周りは不安を抱えていた。
      • この為、ESXi側のどこかで起きた問題だろうと考えてしまい、問題の本質から離れてしまった。

発見

  • Dockerホストとしている仮想マシンでDockerに載せずに直接動かしているSSHにはIPv6で繋がることに気付き、漸くDockerの問題もしくは相性問題を疑い始める。
  • 一旦VMware Workstation Playerに構築したUbuntu ServerにDockerをインストールし、テストした所問題が再現した。
  • この時点でDockerとVMware系の仮想化との相性問題を疑い、物理マシンで試してみると、こちらでも再現。

  • そして色々と調べているうちに、Docker-proxyとIPv6の問題として仕様変更についてのissueを見つけた。

結論

  • 今までの環境では取り敢えずDockerをインストールしたそのままの状態でも、ホストにIPv6アドレスが割り当てられていればIPv4IPv6の双方でポートをコンテナに転送してくれていた。

  • 今回の仕様変更でその仕様が潰されたので、少なくともNAT64を使わずにULA+NAT66を使うか、ちゃんとグローバルユニキャストをコンテナまで回してくるインフラを整えてIPv6のあるべき姿にするべきなんだと思う

    • とはいっても色々面倒くさい… Dockerホストの側でその辺集約したいという感じが結構ある
      • もしくはプロキシ?
  • 正直その辺の使用を良く理解せずに、デフォルトでNAT64掛けてくれてるからそのままで良いやと使っていたが、ちゃんと考え直さないとなぁとなった。