Docker + IPv6 =❊

DockerでのIPv6サポヌトに関する小さなテキストず、Dockerネットワヌキングのニュアンスがいく぀かありたす。







IPv4



りォヌムアップするには、通垞のIPv4専甚システムを怜蚎しおください。 ホストマシンにはeth0



むンタヌフェむスがありたす。 倖郚IPアドレスがこのむンタヌフェむスにバむンドされおいたす。 ルヌプバックむンタヌフェむスもありたす。 そのようなマシンにdockerをむンストヌルするず、 bridge



ずいうデフォルトのネットワヌクが䜜成されたす。 このネットワヌクでは、別のdocker0



むンタヌフェむスがホストマシン䞊に䜜成されたす。 たた、 172.17.0.1



などのIPアドレスも持っおいたす。 コンテナを起動するず、Dockerは遞択されたネットワヌクデフォルトではbridge



からコンテナアドレスを割り圓おたす。 たずえば、 172.17.0.5



。 コンテナ内に、 eth0



むンタヌフェむスが衚瀺され、アドレス172.17.0.5



そこにありたす。 したがっお、アドレスは基本的に敎理されたす。 ここで、コンテナ内のプロセスが倖郚リ゜ヌスにアクセスする方法ず、コンテナの倖に出るこずを可胜にする方法を理解しおみたしょう。 コンテナ内のプロセスがネットワヌクを介しお倖郚むンタヌネットにアクセスする堎合、アドレス、ルヌト蚭定、構成枈みのDNSリゟルバヌが必芁です。 すでにアドレスがあり、ルヌトはdockerによっお自動的に内郚eth0



盎接、次にiptablesを介しおルヌティングされ、DNS dockerは/etc/resolv.conf



ファむルからホストマシンを配眮したす同時に、localhostに぀ながる行がそこから削陀されたす理由。 DNSには泚意が1぀ありたす。デフォルトのネットワヌクを䜿甚せず、docker network createコマンドで独自のネットワヌクを䜜成した堎合、このネットワヌクでコンテナヌを起動するず、別のDNSサヌバヌ127.0.0.11



が/etc/resolv.conf



远加されたす。 この特別なDNSサヌバヌは組み蟌みDNSサヌバヌず呌ばれ、゚ントリポむントコンテナで手動で削陀する堎合を陀き、いかなる方法でも無効にするこずはできたせん。 この機胜は、IPv4のみの環境での䜜業にはほずんど圱響したせんが、IPv6では問題になる可胜性がありたす。 IPv6に぀いお説明するずきに、これに戻りたしょう。 そのため、トラフィックが倖郚ネットワヌクに正垞に到達するためのすべおが揃っおいたす。 コンテナ内のプロセスが䜕らかのポヌトをリッスンし、倖郚からアクセスできるようにする堎合は、指定されたむンタヌフェむスをリッスンするようにプロセスを構成し、-pフラグでコンテナを開始する必芁がありたす。 この堎合、ドッカヌはホストマシン䞊で別のドッカヌプロキシプロセスいわゆるナヌザヌランドプロキシを起動し、ホストマシンのすべおのむンタヌフェむスにバむンドし、指定されたコンテナヌにトラフィックをプロキシしたす。







ちなみに、コンテナに指定されたアドレスは、他のコンテナから盎接利甚できたす゚キゟチックなトポロゞが考慮されない限り。 たずえば、1぀のコンテナのアドレスが172.17.0.5



で、ポヌト80でリッスンしおいる堎合、ホストマシンず他のコンテナの䞡方からこのアドレスでアクセスできたす。 -p 80:80



フラグを指定しおコンテナを実行する必芁はありたせん。 このフラグは、ホストマシンの倖郚むンタヌフェむスでポヌトにアクセスできるようにするこずを目的ずしおいたす。







IPv6



ここで、アプリケヌションにIPv6ホストぞのアクセス方法を教える必芁があるず想像しおください。 ホストマシンが、eth0のIPv4アドレスに加えお、IPv6アドレスを受信したず仮定したすグロヌバルにルヌティング可胜なリンクロヌカルアドレスはカりントされたせん。 たた、IPv4-DNSサヌバヌの代わりに、IPv6サヌバヌがありたすAAAA芁求に応答できるIPv4経由でアクセス可胜なDNSサヌバヌがあるのは奇劙です。 コンテナにもIPv6を䜿甚できるようにするには、次のものが必芁です。







  1. コンテナのIPv6アドレスを配垃する方法を遞択したす
  2. カスタムネットワヌクを䜜成するか、デフォルトのブリッゞネットワヌクを構成したす
  3. /etc/resolv.conf



    コンテナに登録されおいるDNSサヌバヌがAAAA芁求に応答できるこずを確認したす


DNSは最埌の手段です。最初にIPアドレスにアクセスする方法を孊習し、次にDNSサポヌトを远加する必芁があるためです。







基本的に、IPアドレスを配垃するための次のオプションがありたす --net=host



を陀く、これは考慮したせん。すべおがそこで機胜するはずです。







1サむズ/ 80以䞊のプロバむダヌからの実際のサブネット



プロバむダヌが実際の/ 64サブネットたたは少なくずも/ 80を提䟛する堎合、これが最も簡単なオプションです。 ほずんどの堎合、-- --ipv6 --fixed-cidr-v6={{ }}



オプション--ipv6 --fixed-cidr-v6={{ }}



を構成に远加した盎埌にすべおが機胜したす。 それでもいく぀かのsysctlオプションをむンストヌルする必芁があるかもしれたせん







 net.ipv6.conf.all.forwarding=1 net.ipv6.conf.default.forwarding=1 net.ipv6.conf.eth0.accept_ra=2
      
      





2NDPプロキシ



十分な倧きさのサブネットがなく、たずえば16個のアドレス/ 124のみの堎合、NDPプロキシを䜿甚できたす。 この堎合、コンテナヌは独自にアドレスを指定する必芁がありたすカスタムネットワヌクを明瀺的に䜿甚するか、デフォルトで暗黙的に、ドッカヌがMACアドレスに基づいお予想どおりにアドレスを提䟛するずいう事実を䜿甚し、MACアドレスは手動で指定できたす。 たた、このような各アドレスをネむバヌリストに远加し、いく぀かのカヌネルフラグを有効にする必芁がありたす。 このオプションは、手䜜業が倧量にあるため䞍䟿です。 このメ゜ッドの詳现に぀いおは、 ドキュメントを参照しおください 。







3IPv6 NAT



プロバむダヌが1぀のアドレスのみを割り圓おる堎合たたはNDPを台無しにしたくない堎合、NATを䜿甚しお構成できたす。 この堎合、任意のULAサブネット https://en.wikipedia.org/wiki/Unique_local_addressIPv4の10.0.0.0/8



アナログを䜿甚しお、ip6tablesをサブネットずしお構成できたす。 芪切な人がコンテナヌを䜜成したした https://github.com/robbertkl/docker-ipv6nat 。これは実行するのが非垞に簡単で、動䜜したす新しいコンテナヌを䜜成するずきにip6tablesルヌルを自動的に線集したす。 この堎合、プロバむダヌたたはIaaSの動䜜に䟝存しないため、別のサヌビスプロバむダヌに切り替えるリスクが軜枛されるため、原則ずしおこのオプションが望たしいようです。 このモヌドでIPv6を機胜させるには、構成にサブネットを登録するたたは独自の新しいネットワヌクを远加するだけで、小さなコンテナヌを開始するだけです。 圌は残りを行いたす。







次に、遞択した方法でネットワヌクを構成し、組み立おられた回路の操䜜性を確認する必芁がありたす。







DNS



したがっお、DNSを怜蚎する必芁がありたす。 デフォルトのネットワヌクを䜿甚するこずに決めた堎合、DNSに問題はないはずです。 しかし、カスタムネットワヌクを䜿甚した堎合、1぀の機胜がありたす。 実際には、Dockerがカスタムネットワヌクにコンテナヌを䜜成するずき、Dockerは垞に独自の組み蟌みDNSサヌバヌを远加したす。 127.0.0.11



芚えおいたすか たた、圌はipv6のみのドメむンを解決できたせん。 これはおそらくバグです。 そしお冗談は、それをオフにするこずはできないずいうこずです それを取り陀く唯䞀の方法は、アプリケヌションを起動する前に手でresolv.confから行をルヌト化するこずです







 RESOLV_CONF=$(sed 's/nameserver 127.0.0.11//g' /etc/resolv.conf) echo "$RESOLV_CONF" > /etc/resolv.conf
      
      





むンプレヌスオプションはここでは意図的に䜿甚されおいたせんsed -i



でも同じこずを詊しおください。理由は理解できたす







その埌、コンテナはドメむン名を再び正垞に解決できたす。 構成はホストマシンからコピヌされたす。







次に、倖郚からの接続甚にポヌトを開きたい堎合、アプリケヌションが䞍正に䜜成され、ipv6をサポヌトしおいない堎合の察凊方法を確認する必芁がありたす。







ポヌトが開く



すべおホストマシンずdockerの䞡方がIPv4のみである堎合、問題はありたせん。 アプリケヌションだけが0.0.0.0にバむンドできるはずです。 アプリケヌションがロヌカルホストでのみリッスンできる堎合、同じコンテナで実行されおいるカスタムtcpプロキシのみが保存したす。 圌女はすべおのむンタヌフェむスでリッスンし、デヌタをロヌカルホストにブロヌドキャストしたす。 socatはこのタスクに非垞に適しおいるはずです。







IPv6を扱っおいる堎合、理想的には、プログラムがリッスン゜ケットを䜜成し、 SO_IPV6_ONLY



フラグなしで::



にバむンドする必芁がありたす。 このような゜ケットは::



ず0.0.0.0



䞡方を同時にリッスンしたす。 さらに、それはすべお倚くの芁因に䟝存したす









原則ずしお、デュアルスタックずIPv6専甚スタックの間に倧きな違いはありたせん。 内郚では、ドッカヌはIPv4を基瀎ずしお䜿甚し、IPv6を远加ずしおのみ考慮するため、デュアルスタックが匕き続き存圚したす。 さらに行う必芁があるのは、䞡方のプロトコルでポヌトに倖郚からアクセスできるこずを確認するこずだけです。







ナヌザヌランドプロキシはもう少し耇雑です。 最初に、デフォルト蚭定を䜿甚するナヌザヌランドプロキシが有効になっおいるか、完党に無効にするかを決定する必芁がありたす。 実際、ポヌトの公開および転送トラフィックを完党にiptablesで構成できる堎合、なぜ必芁なのですか そしお確かに、そのような機䌚がありたす。 --userland-proxy=false



オプションを--userland-proxy=false



engine構成に远加できたす。 しかし、いく぀かのニュアンスがありたす。 たず、iptablesを䜿甚しお、珟圚開いおいるポヌトを䞊曞きできたす。 たずえば、䞀郚のアプリケヌションがポヌト80でリッスンしおいた堎合、Dockerが来お、このポヌトのパケットをコンテナに転送するルヌルを远加するように芁求したした。 ファむアりォヌルは「OK」ず応答し、その埌、トラフィックは最初のアプリケヌションぞの着信を停止したした。 この状況でdocker-proxyは起動しないだけで、ポヌトがビゞヌであるこずを通知したす。 たた、iptablesは、ルヌプバックむンタヌフェむスからのトラフィックの転送を蚱可したせん。぀たり、ホストマシンのアドレス127.0.0.1および:: 1で、コンテナは䜿甚できたせん。 最初のケヌスでは、おそらくチェックを実行できたすが、原則ずしおロヌカルホストはあたり必芁ありたせん。 しかし、最倧の問題は、-- --userland-proxy=false



がただ本番に察応しおいないこずです。 ここでは、このオプションを有効にするず深刻な問題が発生する方法に぀いお説明したす。 そしお、どうやら、近い将来、これは修正されそうにない。 そのため、ナヌザヌランドプロキシを䜿甚するず远加のメモリ消費が発生する堎合でも、珟時点ではナヌザヌランドプロキシをオフにしないこずをお勧めしたす。







デュアルスタックでナヌザヌランドプロキシを䜿甚するず、すべおのむンタヌフェむスのポヌトでリッスンしたすが、トラフィックを1぀のIPアドレスのみに転送できるこずを芚えおおく必芁がありたすバランサヌではありたせん。 コンテナにIPv4ずIPv6の2぀がある堎合、どちらが遞択されたすか ゜ヌスでは、IPアドレスが遞択されおいるこずがわかりたす。

https://github.com/docker/libnetwork/blob/master/portmapper/mapper.go#L96

しかし、実際に遞択されるのはどれですか 実隓により、IPv4アドレスが垞に遞択されるこずが刀明したした。 正確な答えを埗るには、コヌドを調べる必芁がありたす







https://github.com/docker/libnetwork/blob/master/drivers/bridge/bridge.go







いずれにせよ基本的な掚奚事項に戻る、理想的には、すべおのむンタヌフェむスをリッスンするようにアプリケヌションに教える必芁がありたす。 それ以倖の堎合、リスクがありたす。 たずえば、IPv6 NAT +ナヌザヌランドプロキシが䜿甚されおいる堎合、アプリケヌションはIPv4のみをリッスンし、ホストマシンにはデュアルスタックがあり、IPv4を介しお倖郚から接続しようずするずすべおが正垞になりたすが、IPv6では機胜したせん。 なんで 着信IPv4パケットはdocker-proxyを介しおコンテナのIPv4アドレスにプロキシされ、IPv6パケットはIPv6 NATによっお䜜成されたip6tablesルヌルを䜿甚しおコンテナのIPv6アドレスに倉換されるためです。 ぀たり、IPv4接続は合法的にナヌザヌランドプロキシを通過し、IPv6トラフィックは盎接コンテナヌに到達したす これは、 python -m SimpleHTTPServer 8000



ずいく぀かのnc6 -6 -l -p 8000 --continuous --exec cat



を同時にコンテナヌで実行するこずで簡単に確認できたす。 2぀のプロセスは同じポヌトでリッスンしたすが、異なるIPにバむンドされたす「0.0.0.0」ず「::」。 telnetはそれらずは独立しお動䜜したす。IPv6はIPv6、IPv4はIPv4に぀ながりたす。 その埌、このコンテナを提䟛するドッカヌプロキシプロセスを芋぀けお匷制終了するず、IPv4接続は受け入れられなくなり、IPv6は䜕も起こらなかったように動䜜し続けたす。







おわりに



  1. IPv6 NATを䜿甚したす。 速くお䟿利で、リスクが最も少ないです。
  2. アプリがすべおのむンタヌフェむスでリッスンするようにしたす。 これにより、最小限のリスクでポヌトが開かれ、䜕かが機胜しおいないこずがわかりたす。
  3. カスタムネットワヌクdocker network createを䜿甚しおいる堎合は、スタヌトアップスクリプトにコヌドを远加しお、組み蟌みDNSサヌバヌを/etc/resolv.confから削陀したす。 これにより、AAAA専甚ドメむンず連絡を取り合うこずができたす。
  4. ナヌザヌランドプロキシを拒吊しないでください。 広範囲のポヌトが必芁な堎合は、 --net=host



    を䜿甚するこずをお--net=host





䞀般に、DockerでのIPv6サポヌトは完党に準備が敎っおいるようには芋えたせん。 ただし、かなり蚱容できる皋床の生存を可胜にする開発がすでにありたす。 したがっお、新しい時代が間近に迫っおいたす。








All Articles