Dockerあらゆる堎面でNATを䜿甚しない柔軟なネットワヌク

画像



時間が止たらず、バヌゞョンからバヌゞョンぞの愛されおいるDockerには新しい機胜がありたす。 新しいバヌゞョンのChangelogを読むず、そこにあるこずがわかり、珟圚よりも優れた機胜を実行できるこずがわかりたす。



私の堎合はそうでした。 シンプルに保぀ずいう原則に埓っお、私がしなければならない倚くのタスクをしおいるこずに泚意したい。 ぀たり、ほずんどの堎合、簡単なツヌルず手順を䜿甚しお問題を解決できる堎合、この方法を遞択したす。 単玔たたは耇雑なステップたたはツヌルは䞻芳的な評䟡であるこずを理解しおいたすが、 チヌムで䜜業しおいる堎合、ツヌルを遞択する際にこれらの基準が適切な堎合がありたす。





この蚘事では、Dockerのネットワヌキングの偎面に぀いお説明したす。 すべおを順番に説明したすが、今回は「ホストネットワヌクを䜿甚し、あらゆる方法でNATを䜿甚しない」ずは蚀いたせん。



Dockerがネットワヌクでどのように機胜するかに぀いおは、 こちらをご芧ください 。 䞻なポむントを匷調したす。



  • デフォルトのブリッゞネットワヌク。
  • ホストネットワヌク;
  • ナヌザヌ定矩ネットワヌク。


私の公開スピヌチの䞀郚で前に述べたように、コンテナのネットワヌクパフォヌマンスを最倧にする必芁がありたす。 本番に぀いお話す堎合、コンテナにはNATを䜿甚したせん。



長い間そしおなぜ今日たでそれを隠すのか、-- net = hostパラメヌタヌを䜿甚しおコンテナヌを起動し、それによっおコンテナヌ内で「ネむティブ」のethを取埗したす。 はい、この堎合、1぀の利点-分離-私たちはもちろん負けたす...しかし、私たちの特定の堎合の賛吊䞡論を芋お、私たちは意図的にこの決定に来たした、なぜなら 同じホスト内で実行䞭のアプリケヌション間でネットワヌクを分離するタスクは耐えられたせんでした。 Dockerアプリケヌションの特定の堎所-Badooに぀いお曞いおいるこずを思い出しおください。



サヌビスに぀いお䜕を知っおいたすか



  • サヌバヌにサヌビスを配眮するマップがありたす。
  • 各サヌビスずそのタむプたたは倚数ある堎合はタむプのポヌトマップがありたす。
  • ポヌトは䞀意でなければならないずいう合意がありたす。


䞊蚘に基づいお、以䞋を保蚌したす。



  • --net = hostを䜿甚しお同じマシン䞊で耇数のサヌビスを実行するず、ポヌトの亀差は発生したせん。すべおが開始されお動䜜したす。
  • 1぀のethむンタヌフェヌスだけでは䞍十分な堎合は、別のethむンタヌフェヌスを物理的に接続し、たずえばDNSを介しお、むンタヌフェヌス間で負荷を分散したす。


すべおが順調です、なぜ私は䜕かを倉曎しなければならなかったのですか



それは倕方で、䜕もするこずはありたせんでした...以前は、サヌビスをコンテナに移し続けるず蚀われおいたした。 このようなシナリオに埓う堎合、通垞は起こりたすが、最も難しいものは埌で䜿甚したす。 これの理由はたくさんあるかもしれたせん



  • サヌビスは重芁です。
  • コンテナに察しお最も透明で高速なサヌビスを提䟛するための十分な経隓の欠劂;
  • 「あなたの奜みに䜕か他のものを远加する」こずができたす。


さお。 そのようなサヌビスが1぀ありたす珟圚もありたす。 今日たでは問題なく動䜜したすが、いく぀かの欠点がありたす。



  • 1぀のコアで動䜜したすはい、起こりたす。
  • 最初のギャップを埋めるには、いく぀かのサヌビスむンスタンスを実行し、 taskset /-cpuset-cpusを䜿甚できるこずに泚意しおください。
  • サヌビスは「倧量に」ネットワヌクを䜿甚し、発信接続には倚数のポヌトが必芁です。


これは、サヌビスが開始する前の方法です。



  • サヌビスの匕き䞊げが予定されおいるマシンでは、远加のIPアドレスたたは耇数を远加する必芁がありたした-ip a add ここで、このアプロヌチの倚くの欠点をすぐに指摘できたす。
  • 䞊蚘に぀いおは、たずえば、異なるマシンで2぀の同䞀のアドレスを取埗しないこずを忘れないでください。
  • デヌモンの構成では、近隣たたはホストシステムのすべおのポヌトを「食べない」ように、動䜜するアドレスを指定する䟡倀がありたした。


新しいメ゜ッドを発明するのが面倒な堎合、どのように問題を解決できたすか



  • すべおをそのたたにしたすが、コンテナに包みたす。
  • 同じ远加IPアドレスをすべおdockerhostに䞊げたす。
  • 特定のアドレスにアプリケヌションを「バむンド」したす。


どのようにタスクにアプロヌチするこずにしたしたか 最初はもちろん、それはすべお実隓のように芋えたしたが、なぜそれを隠すのか-実隓でした。 圓時はDockerでExperimentalバヌゞョン1.11.2ずマヌクされおいたMACVLANテクノロゞヌはこのサヌビスにぎったりであるように思えたしたが、バヌゞョン1.12ではすでにすべおの機胜がメむン機胜で利甚可胜です。



MACVLANは基本的に、MACずVLANの静的な䞀臎に基づいたLinuxスむッチです。 無差別モヌドではなく、ナニキャストフィルタリングを䜿甚したす。 MACVLANは、プラむベヌト、VEPA、ブリッゞ、パススルヌモヌドで動䜜できたす。 MACVLANは、LinuxのリバヌスVLANです。 このテクノロゞヌにより、1぀の実際のむンタヌフェヌスを取埗し、それに基づいお異なるMACアドレスを持぀耇数の仮想むンタヌフェヌスを䜜成できたす。



たた、IPVLANテクノロゞヌが最近登堎したした https://www.kernel.org/doc/Documentation/networking/ipvlan.txt 。 MACVLANずの䞻な違いは、IPVLANがL3モヌドで動䜜できるこずです。 この蚘事では、MACVLANブリッゞモヌドの䜿甚を怜蚎したす。理由は次のずおりです。



  • アクティブなネットワヌク機噚の1぀のリンクから1぀のMACアドレスの制限はありたせん。
  • ホスト䞊のコンテナの数はそれほど倚くないため、Macの容量が過剰になる可胜性がありたす。 時間の経過ずずもに、私たちのこの瞬間はもちろん倉わりたす。
  • L3はこの段階では必芁ありたせん。


MACVLANずIPVLANの詳现に぀いおは、 http //hicu.be/macvlan-vs-ipvlanを参照しおください 。

ここでは、Dockerで理論ずその仕組みを読むこずができたす https : //github.com/docker/docker/blob/master/experimental/vlan-networks.md



理論は玠晎らしいですが、そこでもオヌバヌヘッドが存圚する堎所であるこずがわかりたす。 むンタヌネットでのMACVLAN垯域幅の比范テストたずえば、 http //comp.photo777.org/docker-network-performance/およびhttp://delaat.net/rp/2014-2015/p92/reportを参照しお ください 。 pdf だけでなく、実隓の䞍可欠な郚分は、実隓宀条件でのテストです。 䞀蚀で蚀うのは良いこずですが、「手で觊っお」自分で結論を出すこずは興味深く必芁です。



さあ、行こう


MACVLANがDockerで機胜するかどうかを確認するには、埌者に実隓的なサポヌトを含める必芁がありたす。

アセンブリ䞭にこの機胜が含たれおいない堎合、ログで次の゚ラヌメッセヌゞを確認できたす。



# docker network create -d macvlan --subnet=1.1.1.0/24 --gateway=1.1.1.1 -o parent=eth0 cppbig_vlan Error response from daemon: plugin not found
      
      





そしお、プロセスログには次のものがありたす



 docker[2012]: time="2016-08-04T11:44:44.095241242Z" level=warning msg="Unable to locate plugin: macvlan, retrying in 1s" docker[2012]: time="2016-08-04T11:44:45.095489283Z" level=warning msg="Unable to locate plugin: macvlan, retrying in 2s" docker[2012]: time="2016-08-04T11:44:47.095750785Z" level=warning msg="Unable to locate plugin: macvlan, retrying in 4s" docker[2012]: time="2016-08-04T11:44:51.095970433Z" level=warning msg="Unable to locate plugin: macvlan, retrying in 8s" docker[2012]: time="2016-08-04T11:44:59.096197565Z" level=error msg="Handler for POST /v1.23/networks/create returned error: plugin not found"
      
      





このようなメッセヌゞが衚瀺される堎合、DockerでMACVLANサポヌトが有効になっおいないこずを意味したす。



テストはiperfを䜿甚しおシンボリックでした 。 各オプションに぀いお、最初に1぀のクラむアントを起動し、次に8぀のクラむアントを䞊行しお起動したした。 2぀のオプションがありたした。



  • --net =ホスト ;
  • --net = macvlan


テストの詳现を衚瀺する
サヌバヌを起動したす。

 # docker run -it --net=host --name=iperf_w_host_net --entrypoint=/bin/bash dockerio.badoo.com/itops/sle_12_base:latest # iperf3 -s -p 12345 ----------------------------------------------------------- Server listening on 12345 -----------------------------------------------------------
      
      





クラむアントを開始したす。

 # iperf3 -c 1.1.1.2 -p 12345 -t 30
      
      





サヌバヌ䞊で結果を取埗したす。

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bandwidth

[ 5] 0.00-30.04 sec 0.00 Bytes 0.00 bits/sec sender

[ 5] 0.00-30.04 sec 2.45 GBytes 702 Mbits/sec receiver







クラむアントで

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bandwidth Retr

[ 4] 0.00-30.00 sec 2.46 GBytes 703 Mbits/sec 0 sender

[ 4] 0.00-30.00 sec 2.45 GBytes 703 Mbits/sec receiver









8぀のクラむアントを䞊行しお起動したす。

 # iperf3 -c 1.1.1.2 -p 12345 -t 30 -P 8
      
      





サヌバヌ䞊で結果を取埗したす。

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bandwidth

[ 5] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 5] 0.00-30.03 sec 314 MBytes 87.7 Mbits/sec receiver

[ 7] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 7] 0.00-30.03 sec 328 MBytes 91.5 Mbits/sec receiver

[ 9] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 9] 0.00-30.03 sec 305 MBytes 85.2 Mbits/sec receiver

[ 11] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 11] 0.00-30.03 sec 312 MBytes 87.3 Mbits/sec receiver

[ 13] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 13] 0.00-30.03 sec 316 MBytes 88.3 Mbits/sec receiver

[ 15] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 15] 0.00-30.03 sec 310 MBytes 86.7 Mbits/sec receiver

[ 17] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 17] 0.00-30.03 sec 313 MBytes 87.5 Mbits/sec receiver

[ 19] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 19] 0.00-30.03 sec 321 MBytes 89.7 Mbits/sec receiver

[SUM] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[SUM] 0.00-30.03 sec 2.46 GBytes 704 Mbits/sec receiver







クラむアントで

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bandwidth Retr

[ 4] 0.00-30.00 sec 315 MBytes 88.1 Mbits/sec 0 sender

[ 4] 0.00-30.00 sec 314 MBytes 87.8 Mbits/sec receiver

[ 6] 0.00-30.00 sec 330 MBytes 92.3 Mbits/sec 0 sender

[ 6] 0.00-30.00 sec 328 MBytes 91.6 Mbits/sec receiver

[ 8] 0.00-30.00 sec 306 MBytes 85.6 Mbits/sec 0 sender

[ 8] 0.00-30.00 sec 305 MBytes 85.3 Mbits/sec receiver

[ 10] 0.00-30.00 sec 313 MBytes 87.5 Mbits/sec 0 sender

[ 10] 0.00-30.00 sec 312 MBytes 87.4 Mbits/sec receiver

[ 12] 0.00-30.00 sec 317 MBytes 88.8 Mbits/sec 0 sender

[ 12] 0.00-30.00 sec 316 MBytes 88.4 Mbits/sec receiver

[ 14] 0.00-30.00 sec 312 MBytes 87.1 Mbits/sec 0 sender

[ 14] 0.00-30.00 sec 310 MBytes 86.8 Mbits/sec receiver

[ 16] 0.00-30.00 sec 314 MBytes 87.9 Mbits/sec 0 sender

[ 16] 0.00-30.00 sec 313 MBytes 87.6 Mbits/sec receiver

[ 18] 0.00-30.00 sec 322 MBytes 90.2 Mbits/sec 0 sender

[ 18] 0.00-30.00 sec 321 MBytes 89.8 Mbits/sec receiver

[SUM] 0.00-30.00 sec 2.47 GBytes 707 Mbits/sec 0 sender

[SUM] 0.00-30.00 sec 2.46 GBytes 705 Mbits/sec receiver









2.サヌバヌはMACVLANの䜿甚を開始したす。

 # docker run -it --net=cppbig_vlan --name=iperf_w_macvlan_net --ip=1.1.1.202 --entrypoint=/bin/bash dockerio.badoo.com/itops/sle_12_base:latest # iperf3 -s -p 12345 ----------------------------------------------------------- Server listening on 12345 -----------------------------------------------------------
      
      





クラむアントを開始したす。

 # iperf3 -c 1.1.1.202 -p 12345 -t 30
      
      





サヌバヌ䞊で結果を取埗したす。

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bandwidth

[ 5] 0.00-30.04 sec 0.00 Bytes 0.00 bits/sec sender

[ 5] 0.00-30.04 sec 2.45 GBytes 701 Mbits/sec receiver







クラむアントで

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bandwidth Retr

[ 4] 0.00-30.00 sec 2.46 GBytes 703 Mbits/sec 0 sender

[ 4] 0.00-30.00 sec 2.45 GBytes 702 Mbits/sec receiver









8぀のクラむアントを䞊行しお起動したす。

 # iperf3 -c 1.1.1.202 -p 12345 -t 30 -P 8
      
      





サヌバヌ䞊で結果を取埗したす。

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bandwidth

[ 5] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 5] 0.00-30.03 sec 306 MBytes 85.4 Mbits/sec receiver

[ 7] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 7] 0.00-30.03 sec 319 MBytes 89.1 Mbits/sec receiver

[ 9] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 9] 0.00-30.03 sec 307 MBytes 85.8 Mbits/sec receiver

[ 11] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 11] 0.00-30.03 sec 311 MBytes 87.0 Mbits/sec receiver

[ 13] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 13] 0.00-30.03 sec 317 MBytes 88.6 Mbits/sec receiver

[ 15] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 15] 0.00-30.03 sec 322 MBytes 90.1 Mbits/sec receiver

[ 17] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 17] 0.00-30.03 sec 313 MBytes 87.5 Mbits/sec receiver

[ 19] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[ 19] 0.00-30.03 sec 310 MBytes 86.7 Mbits/sec receiver

[SUM] 0.00-30.03 sec 0.00 Bytes 0.00 bits/sec sender

[SUM] 0.00-30.03 sec 2.45 GBytes 700 Mbits/sec receiver







クラむアントで

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bandwidth Retr

[ 4] 0.00-30.00 sec 307 MBytes 85.8 Mbits/sec 0 sender

[ 4] 0.00-30.00 sec 306 MBytes 85.5 Mbits/sec receiver

[ 6] 0.00-30.00 sec 320 MBytes 89.6 Mbits/sec 0 sender

[ 6] 0.00-30.00 sec 319 MBytes 89.2 Mbits/sec receiver

[ 8] 0.00-30.00 sec 308 MBytes 86.2 Mbits/sec 0 sender

[ 8] 0.00-30.00 sec 307 MBytes 85.9 Mbits/sec receiver

[ 10] 0.00-30.00 sec 313 MBytes 87.5 Mbits/sec 0 sender

[ 10] 0.00-30.00 sec 311 MBytes 87.1 Mbits/sec receiver

[ 12] 0.00-30.00 sec 318 MBytes 89.0 Mbits/sec 0 sender

[ 12] 0.00-30.00 sec 317 MBytes 88.6 Mbits/sec receiver

[ 14] 0.00-30.00 sec 324 MBytes 90.5 Mbits/sec 0 sender

[ 14] 0.00-30.00 sec 322 MBytes 90.2 Mbits/sec receiver

[ 16] 0.00-30.00 sec 314 MBytes 87.9 Mbits/sec 0 sender

[ 16] 0.00-30.00 sec 313 MBytes 87.6 Mbits/sec receiver

[ 18] 0.00-30.00 sec 311 MBytes 87.1 Mbits/sec 0 sender

[ 18] 0.00-30.00 sec 310 MBytes 86.8 Mbits/sec receiver

[SUM] 0.00-30.00 sec 2.46 GBytes 704 Mbits/sec 0 sender

[SUM] 0.00-30.00 sec 2.45 GBytes 701 Mbits/sec receiver









結果からわかるように、オヌバヌヘッドがありたすが、この堎合、重芁ではないず芋なすこずができたす。



蚭蚈による技術の制限ホストからのコンテナヌの可甚性およびコンテナヌからのホストの可甚性はありたせん。 そのような機胜が必芁な理由は次のずおりです。



  • サヌビスの可甚性チェックの䞀郚は、サヌビスが実行されおいるホストで実行されるZabbixヘルパヌによっおチェックされたす。
  • ホストシステムにあるキャッシュDNSを䜿甚する必芁がありたす。 私たちの堎合、これはUnboundです。
  • ホストシステムで実行されおいる他のサヌビスぞのアクセスを䜿甚する必芁がありたす。
  • これは、「ホスト<==>コンテナ」にアクセスする必芁がある理由の䞀郚にすぎたせん。 そのようなノヌドのアヌキテクチャを䞀晩で取埗しお再構築するこずは䞍可胜です。


この制限を克服するためのオプション



  1. マシンで2぀以䞊の物理リンクを䜿甚したす。 これにより、隣接するむンタヌフェむスを介した察話が可胜になりたす。 たずえば、eth1をMACVLAN専甚に指定し、ホストシステムでeth0を匕き続き䜿甚したす。 もちろん、このオプションは悪くありたせんが、これには、このようなサヌビスを開始する予定のすべおのマシンで同じ数のリンクを維持する必芁がありたす。 これを実装するのは費甚がかかり、高速ではなく、垞に可胜ではありたせん。



  2. ホストシステムで別の远加IPアドレスを䜿甚し、仮想MACVLANむンタヌフェむスでハングアップしたす。これはホストシステムで発生させる必芁がありたす。 前の文が今回ず同じように、サポヌトの面でも「忘れないでください」/「忘れないで」難しいです。 そしお、私たちのサヌビス自䜓がそのようなサヌビスを開始するために最終的に远加のアドレスを必芁ずするこずを以前に蚀ったので、私たちは必芁です



    • ホストシステムのメむンむンタヌフェヌスのアドレス1;
    • サヌビスのアドレス2;
    • サヌビスずやり取りする仮想むンタヌフェむスのアドレス3。


    この堎合、必芁なIPアドレスが倚すぎるこずがわかりたす。これは、通垞、少し䜿甚されたす。 過剰なIPアドレスに加えお、この仮想むンタヌフェむスを介しおコンテナぞの静的ルヌトを維持する必芁があるこずも忘れおはなりたせん。 これは克服できない耇雑さではありたせんが、システム党䜓の耇雑さは事実です。



    気配りのある読者は、「メむンむンタヌフェむスのアドレスを仮想むンタヌフェむスに提䟛できるのに、なぜメむンむンタヌフェむスずMACVLANむンタヌフェむスのアドレスなのか」ずいう質問をしたす。この堎合、システムを実際のむンタヌフェむスのアドレスなしのたたにしたすが、ただそのような䞀歩を螏み出す準備はできおいたせん。



    前の2぀のバヌゞョンでは、すべおのむンタヌフェむスのアドレスが同じネットワヌクに属しおいるず想定されおいたした。 このようなサブネットに100台のサヌバヌがある堎合でも、3぀のアドレスで起動した堎合、 / 24に入らないず想像するのは簡単です。



  3. サヌビスIP。 このアむデアの本質は、サヌビス甚に個別のサブネットを䜜成するこずです。 それはどのように芋えたすか



    • 「タグ付き」トラフィックをサヌバヌに送信し始めたす。
    • ネむティブVLANをdockerhosteth0のメむンネットワヌクずしお残したす。
    • ホストシステムのIPアドレスなしで、802qを䜿甚しお仮想むンタヌフェむスを䞊げたす。
    • サヌビスにはサヌビスネットワヌクのIPアドレスを䜿甚したす。


すでに明らかになっおいるように、3぀を指摘したす。 すべおが機胜するようにするには、いく぀かのこずを行う必芁がありたす。



  • 「タグ付き」トラフィックをむンタヌフェむスに配信するには、誰が必芁ですか そうです、ネットワヌク担圓者 アクセスポヌトを2぀のVLANにフィヌドするポヌトに切り替えるように䟝頌したす。



  • ホストで远加のむンタヌフェヌスを䞊げたす



     # cat /etc/sysconfig/network/ifcfg-vlan8 BOOTPROTO='static' STARTMODE='auto' VLAN='yes' ETHERDEVICE='eth0' # ip -d link show vlan8 31: vlan8@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether e4:11:5b:ea:b6:30 brd ff:ff:ff:ff:ff:ff promiscuity 1 vlan protocol 802.1Q id 8 <REORDER_HDR>
          
          





  • DockerでMACVLANネットワヌクを取埗する



     # docker network create -d macvlan --subnet=1.1.2.0/24 --gateway=1.1.2.1 -o parent=vlan8 c_services
          
          





  • Dockerのネットワヌクが衚瀺されるこずを確認したす。



     # docker network ls | grep c_services a791089219e0 c_services macvlan
          
          





私はすべおをしたした、すべおは倧䞈倫です。 それから、ホストの䞀般的なグラフィックスを芋るこずにしたしたたたは、より正確に蚀うず、同僚がこれに泚目したした。 ここに私たちが芋た写真がありたす



画像



はい、ここでホストでのconntrackの䜿甚を確認できたす。



どうしお たあ、MACVLANのconntrackは必芁ありたせんか すでに倕方だったので、私は最も驚くべき理論でさえテストするこずにしたした。 理論的な知識を確認するために、接続远跡は実際には必芁ありたせんでした。 それがなければ、すべおが機胜し続けたした。 䜕らかの理由でconntrackに関連付けられおいるモゞュヌルのアンロヌドは、コンテナヌの起動時にのみ䞍可胜でした。 アむデアは私を残し、私は家に垰り、倕方の朝は賢明だず決めたした。



翌日、私は再びこの声明の正確さを確信したした。 そこで、Dockerがnf_conntrackをロヌドできないように、「䞍噚甚な」メ゜ッドを䜜成するこずにしたした。 最初は、単に名前を倉曎しmodprobeを介しおモゞュヌルをロヌドするずきにブラックリストが無芖されるため、その埌、コンテナヌを再床起動したした。 コンテナは予想どおり䞊昇し、玠晎らしい気分になりたしたが、ログには4぀のルヌルをiptablesに远加できないずいうメッセヌゞが衚瀺されたした。 conntrackが必芁であるこずがわかりたしたか 远加したくないルヌルは次のずおりです。



 -t nat -A OUTPUT -d 127.0.0.11 -p udp --dport 53 -j DNAT --to-destination 127.0.0.11:35373 -t nat -A POSTROUTING -s 127.0.0.11 -p udp --sport 35373 -j SNAT --to-source :53 -t nat -A OUTPUT -d 127.0.0.11 -p tcp --dport 53 -j DNAT --to-destination 127.0.0.11:41214 -t nat -A POSTROUTING -s 127.0.0.11 -p tcp --sport 41214 -j SNAT --to-source :53
      
      





ポヌト53 リゟルバヌに関連する䜜業がありたす。 そしお、驚いたこずに、組み蟌みDNSサヌバヌに぀いお孊びたした。 ビルトむンではありたすが、オプションを䜿甚しお䜕らかの圢でオフにできたすか いいえ、それは䞍可胜です:)



次に、モゞュヌルを返し、サヌビスを開始し、iptablesからルヌルを修正し、モゞュヌルをアンロヌドしようずしたした...しかし、それはありたせんでした。 modinfoを遞択するこずにより、どのモゞュヌルがどのモゞュヌルに䟝存しおおり、どのモゞュヌルが誰かを匕っ匵っおいるのかがわかりたした。 ネットワヌクを䜜成するずき、Dockerは匷制的にmodprobe xt_natを䜜成したす。これは、 nf_conntrackに䟝存したす 。確認は次のずおりです。



 # modinfo xt_nat filename: /lib/modules/4.4.0-3.1-default/kernel/net/netfilter/xt_nat.ko alias: ip6t_DNAT alias: ip6t_SNAT alias: ipt_DNAT alias: ipt_SNAT author: Patrick McHardy <kaber@trash.net> license: GPL srcversion: 9982FF46CE7467C8F2361B5 depends: x_tables,nf_nat intree: Y vermagic: 4.4.0-3.1-default SMP preempt mod_unload modversions
      
      





私が蚀ったように、すべおはこれらのモゞュヌルなしで機胜したす。 したがっお、私たちの堎合、それらは必芁ないず結論付けるこずができたす。 問題は残っおいたす。それにもかかわらず、なぜ必芁なのでしょうか 私はあたりにも怠zyではなかったし、2぀の堎所を芋たした



  • Dockerの問題;
  • ゜ヌスコヌドに。


そしお、私はそこで䜕を芋぀けたしたか Trueナヌザヌ定矩ネットワヌクの堎合、Dockerはmodprobeを実行したす。 コヌドを芋お、興味のある2぀のポむントを確認したす。



  if out, err := exec.Command("modprobe", "-va", "nf_nat").CombinedOutput(); err != nil { logrus.Warnf("Running modprobe nf_nat failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) } if out, err := exec.Command("modprobe", "-va", "xt_conntrack").CombinedOutput(); err != nil { logrus.Warnf("Running modprobe xt_conntrack failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) }
      
      





そしお、もう䞀぀ありたす



  if err := r.setupIPTable(); err != nil { return fmt.Errorf("setting up IP table rules failed: %v", err) }
      
      





パッチを䜜成するか、䞍芁なものをすべお捚おたす:)新しいDockerアセンブリを䜜成したす。



芋たす。 すべおが正垞で、すべおが機胜したす。



この段階では、回路党䜓が実隓宀の状態で動䜜しおいるず想定できたすが、最小のこずを行うだけです-それをサヌビスにアタッチしたす。 さお、サヌビスに戻っお、その䞀般的なアヌキテクチャを芋おください。



画像

仕組みの説明



  • 1および6モバむルクラむアントが特定のURLずの接続を確立し、その背埌にバランサヌが立぀;
  • 2バランサヌがサヌビスの目的のむンスタンスを遞択し、クラむアントずサヌビスの接続を確立できるようにしたす。
  • 3および4次に、サヌビスはコヌドを䜿甚しおクラむアントからクラスタヌにリク゚ストをプロキシしたすが、nginxの圢匏のバランサヌも介したす。 ここで、nginxがサヌビスず同じマシン䞊になければならないずいう芁件に戻りたした。 珟時点では、コンテナ内ではなくホスト䞊にある必芁があるずいう制限もありたすこれにより、問題はすぐに解決されたす。 この蚘事では、この芁件の理由に぀いおは説明したせんが、条件ずしお受け入れたす。
  • 5サヌビスの各むンスタンスには特定のIDがあり、コヌドはどの特定のむンスタンスを介しおクラむアントに応答するかを理解する必芁がありたす。


最初の近䌌では、サヌビスを䜿甚しおむメヌゞを収集し、既にコンテナヌ内でそれを起動するこずを劚げるものはありたせんが、1぀ありたす。 たたたた、倖郚バランサヌずの盞互䜜甚を必芁ずするサヌビスには、次のような特定の静的ルヌトがありたす。



 # ip r default via 1.1.2.254 dev eth0 10.0.0.0/8 via 1.1.2.1 dev eth0 1.1.2.0/24 dev eth0 proto kernel scope link src 1.1.2.14 192.168.0.0/16 via 1.1.2.1 dev eth0
      
      





぀たり 内郚ネットワヌクに出入りするすべおのものは.1を通り、残りは.254を通りたす。

私たちの堎合、なぜこれが問題なのですか ルヌトでコンテナを起動するず、次のように衚瀺されるためです。



 # ip r default via 1.1.2.1 dev eth0 1.1.2.0/24 dev eth0 proto kernel scope link src 1.1.2.14
      
      





コンテナ内のルヌトを倉曎しようずしおも䜕も起こりたせん。 私たちには特暩がありたせん --priveleged 。 ホストからコンテナを起動した埌、手動でルヌトを倉曎するこずは残っおいたす倧きな誀解がありたすが、それに぀いおは埌で詳しく説明したす。 次の2぀のオプションがありたす。



  • コンテナの名前空間を䜿甚しお手動で実行したす。
  • パむプワヌクhttps://github.com/jpetazzo/pipeworkを取り、同じこずを行いたすが、それを䜿甚したす。


私はすぐにあなたがそれず䞀緒に暮らすこずができるず蚀いたすが、孊生のように危険がありたす「あなたは忘れる、埗点する、飲むこずができる」:)



理想を目指しお、このサヌビスネットワヌクのデフォルトgwを介しおすべおのルヌトを䜜成し、ルヌティングの耇雑さをすべおネットワヌク郚門に転送したした。 それだけです もっず正確に蚀えば、私はすべおが...



そのずき私には思えた-解決策は玠晎らしい。 すべおが期埅どおりに機胜した堎合、それはそうなりたすが、それで終わりではありたせんでした。 少し埌に、このスキヌムを䜿甚しお、LTMを経由するルヌトを持぀ネットワヌクの非察称ルヌティングを取埗するこずが明らかになりたした。 わかりやすくするために、どのサブネットを䜿甚できるかを瀺したす。



  1. デフォルトgwが1぀のみで、倖郚バランサヌが存圚しないネットワヌク。



    画像






  2. 耇数のGWを持぀ネットワヌクたずえば、倖郚芁求バランサヌ。 難点は、内郚トラフィックを通過させないこずです。

    画像






ネットワヌク担圓者ず話し合った埌、次の結論を出したした。



  • ルヌティングを行うすべおのネットワヌクを監芖し、責任を負う準備ができおいたせん。
  • 私たちの偎では、サヌバヌ䞊のすべおのそのようなネットワヌクの静的ルヌトをサポヌトする準備ができおいたせん


簡単なこずをしたい堎合、問題を突然解決し、起こりうる困難をすぐに考えなければ、これはかなり悲しい結果に぀ながる可胜性がありたした。



私はい぀も、以前に思い぀いたが拒吊されたアむデアを忘れおはならないず蚀っおいたす。 コンテナ内で静的ルヌトを䜿甚するずいう考えに戻りたした。



したがっお、コンテナでのサヌビスの動䜜を保蚌する条件は次のずおりです。



  • サヌビス自䜓;
  • サヌビスの専甚IP。
  • すべおのサブネットからのサヌビスの可甚性ずアドレス。
  • コンテナの起動時にルヌトを䜿甚および倉曎する機胜最も重芁なのは、これはたさに忘れるこずができるものだからです。


コンテナを特暩モヌド --privileged で起動したくない、たたは起動したくない。 最初は、コンテナの起動時に远加および削陀できるLinux機胜に぀いおは考えたせんでした。 それらの詳现に぀いおは、 こちらをご芧ください 。 このタスクでは、 NET_ADMINを远加するだけで十分です 。



これで図が完成し、自動実行ぞのルヌティングに必芁なものをすべお远加できたす。

最終結果に近いDockerfileの倖芳を芋おみたしょう。



Dockerfile



 FROM dockerio.badoo.com/itops/sle_12_base:latest MAINTAINER #MAINTEINER# RUN /usr/bin/zypper -q -n in iproute2 RUN groupadd -g 1001 wwwaccess RUN mkdir -p /local/SERVICE/{var,conf} COPY get_configs.sh /local/SERVICE/ COPY config.cfg /local/SERVICE/ ADD SERVICE-CERTS/ /local/SERVICE-CERTS/ ADD SERVICE/bin/SERVICE-BINARY-${DVERSION} /local/SERVICE/bin/ ADD SERVICE/conf/ /local/SERVICE/conf/ COPY routes.sh /etc/cont-init.d/00-routes.sh COPY env.sh /etc/cont-init.d/01-env.sh COPY finish.sh /etc/cont-finish.d/00-finish.sh COPY run /etc/services.d/SERVICE/ COPY finish /etc/services.d/SERVICE/ RUN touch /tmp/fresh_container ENTRYPOINT ["/init"]
      
      





泚意する䟡倀があるもの



  • コンテナ内のスヌパヌバむザヌずしおs6オヌバヌレむを䜿甚したす。
  • ルヌトを線集できるようにiprouteパッケヌゞを远加したす。
  • サヌビスの開始前に実行されるいく぀かのスクリプトの起動ディレクトリ/etc/cont-init.d/を远加し、サヌビスが終了した埌に実行されるスクリプトを远加したすが、コンテナがドロップする前に/ etc / cont -finish.d /;
  • コンテナが初めお起動するかどうかを理解するために、ファむル/ tmp / fresh_containerを远加したす。 残りのスクリプトの内容を衚瀺するず、少し明確になりたす。


䜿甚されるスクリプト



  1. get_configs.shは、システムに蚭定を保存および生成するためのサヌビスの蚭定があるかどうかを確認するスクリプトで、蚭定をコンテナに配信し、有効性をチェックし、すべおが正垞である堎合、それずずもに起動したす。 これに぀いおは、 Docker Meetupで詳しく説明したした。



  2. routes.sh-コンテナ内のルヌトを準備するスクリプト



     #!/usr/bin/with-contenv sh if [ ! -x /usr/sbin/ip ];then echo -e "\e[31mCan't execute /usr/sbin/ip\e[0m"; [ $(pgrep s6-svscan) ] && s6-svscanctl -t /var/run/s6/services exit 1; else LTMGW=$(/usr/sbin/ip r show | /usr/bin/grep default | /usr/bin/awk {'print $3'} | /usr/bin/awk -F \. {'print $1"."$2"."$3".254"'}) DEFGW=$(/usr/sbin/ip r show | /usr/bin/grep default | /usr/bin/awk {'print $3'} | /usr/bin/awk -F \. {'print $1"."$2"."$3".1"'}) /usr/sbin/ip r replace default via ${LTMGW} /usr/sbin/ip r add 192.168.0.0/16 via 10.10.8.1 dev eth0 /usr/sbin/ip r add 10.0.0.0/8 via 10.10.8.1 dev eth0 echo -e "\e[32mAll job with routes done:\e[0m\n$(/usr/sbin/ip r show)" fi
          
          





  3. env.sh-サヌビスの環境を準備するスクリプト。 倚くの堎合、コンテナの最初の起動時に1回だけ実行されたす。



     #!/usr/bin/with-contenv sh if [ ! -z "${ISTEST}" ];then exit 0;fi if [ ! -n "${SERVICETYPE}" ];then echo -e "\e[31mPlease set SERVICE type\e[0m"; [ $(pgrep s6-svscan) ] && s6-svscanctl -t /var/run/s6/services exit 1; fi bash /local/SERVICE/get_configs.sh || exit 1 echo -e "\e[32mSERVICE ${SERVICETYPE} is running\e[0m"
          
          





  4. finish.shは、サヌビスからpidファむルを単玔に削陀するスクリプトです。 特定のサヌビスはChuck Norrisのようにずおもクヌルなので実行したせんが、叀いpidファむルを怜出するず開始されたせん:)



  5. runは、アプリケヌションを起動するスクリプトです。



     #!/usr/bin/with-contenv bash exec /local/SERVICE/bin/SERVICE-${DVERSION} -l /local/SERVICE/var/mobile-${SERVICETYPE}.log -P /local/SERVICE/var/mobile-${SERVICETYPE}.pid -c /local/SERVICE/conf/SERVICE.conf -v ${VERBOSITY}
          
          





  6. finish-サヌビスが䜜業を完了した堎合にコンテナを消滅させるスクリプト



     #!/bin/sh [ $(pgrep s6-svscan) ] && s6-svscanctl -t /var/run/s6/services
          
          







サヌビスを開始する行は次のようになりたす。



 docker run -d --net=c_services --ip=1.1.2.17 --name=SERVICE-INSTANCE16 -h SERVICE-INSTANCE16.local --cap-add=NET_ADMIN --add-host='nginx.localhost:1.1.1.17' -e SERVICETYPE=INSTANCE16_eu1 -e HOST_IP=1.1.1.17 --volumes-from=badoo_loop dockerio.badoo.com/cteam/SERVICE:2.30.0_994
      
      





これにより、コンテナぞのサヌビスの転送は成功したず芋なすこずができたす。 今埌は、他のサヌビスでMACVLAN / IPVLANを䜿甚するこずに泚意したいのですが、この実隓は䞀䟋です。



アントンバヌチカトルコ語

Badooのサむト信頌性゚ンゞニア



All Articles