この投稿は、venetインターフェース上の異なるネットワークからのコンテナーへのOpenVZアドレスの割り当てに特化しています。 他の専門家がこの問題を気取らない方法で解決したか、venetの使用を完全に拒否した方法を見たので、この投稿を書くことにしました。
環境
実際のアドレスと内部ネットワーク上のアドレスを割り当てる必要があるコンテナを持つopenvzホスト名があります。 さらに、コンテナには、実アドレスまたは内部アドレス、または両方のアドレスを同時に指定できます。 実際のアドレスと内部ネットワークには、異なるネットワークセグメントを介してホストからアクセスできます。 私の例では、それらは異なるvlan-sにあり、内部ネットワークはアドレスのブロック
192.168.1/24
によって表されます。
ホストOS-CentOS 6。
問題
内部アドレスと外部アドレスをコンテナに追加するだけでは、コンテナ内のネットワークは正常に機能しません。すべての宛先に対して、最初のアドレスが常に発信アドレスとして選択され、ホストノードのルートを選択するときに、内部(外部)ネットワークに適さないルーティングテーブルが使用されます。
openvzのドキュメントとメーリングリストでは、このようなネットワーク構成にvethを使用する傾向があります。 ただし、次の理由でvethを使用しないようにしています。
- 低いパフォーマンス
- vethはコンテナにネットワーク制限を課しません。セキュリティの観点ではより悪いです
- vethには基本的にブリッジの使用が含まれます。 ブリッジメンバインターフェイスの構成が変更される(コンテナが開始または停止する)と、ブリッジのMACアドレスが、メンバインターフェイスのMACアドレスからの数値によって選択されます。 コンテナの起動または停止を停止し、現在のMACアドレスよりも小さい新しいMACアドレスを設定したり、ブリッジインターフェイス上に現在MACアドレスがあるコンテナを停止したりすることができない場合、スイッチ上の新しいMACがロックされるまで、このインターフェイス上のホストノードとの接続は失われます。 これは、場合によっては十数秒で起こります。 明らかに高いMACアドレスを仮想インターフェイスに割り当てることでこの問題を解決しましたが、これにはあまり熱心ではありませんでした。
したがって、このゲームには価値があります。このような構成でも、venet-interfacesのコンテナにネットワークを配置したいと思います。
解決策
上記のように、venetインターフェースの問題は、すべてが一緒に来ることであり、送信するとき、発信アドレスを区別し、それらに異なるルートを選択する必要があります。 管理者は、コンテナの内側でルールをずらすか、ifzスクリプトvzでコンテナにアドレスを追加するためのテンプレートを変更することにより、さまざまな方法でこの問題を解決します。 移行中に問題が発生しないように、ネットワーク構成はコンテナの外部にあるべきだと思います。
ホストノードで目的のルートを選択します
特に指定がない限り、アクションは
/etc/sysconfig/network-scripts
で実行されます。
内部インターフェイス:
[root@pve1 network-scripts]
外部インターフェース:
[root@pve1 network-scripts]
仮想マシンから内部ネットワークと外部ネットワークにパケットを送信するための2つの追加ルーティングテーブルを定義します。 以下のファイルの最後の2行は、ルーティングテーブル用にランダムに取得された2つの空き番号の名前を指定しています。
[root@pve1 network-scripts]# cat /etc/iproute2/rt_tables # # reserved values # 255 local 254 main 253 default 0 unspec # # local # #1 inr.ruhep 200 external 210 internal
これらのテーブルの内容を定義します。
[root@pve1 network-scripts]# cat route-vmbr0 192.168.1.0/24 dev vmbr0 table internal default via 192.168.1.3 table internal [root@pve1 network-scripts]# cat route-vmbr1 200.200.100.0/23 dev vmbr1 table external default via 200.200.100.30 table external
内部ネットワークはNATゲートウェイ(
192.168.1.3
)を介してインターネットに接続されていますが、直接サブネットとインターネットの両方には、内部アドレスと外部アドレスの両方からアクセスできます。 必要に応じて。
次に、どのルーティングルールをいつ適用するかを分離する必要があります。 ファイル自体は理解しにくいので、コメントを追加します。
[root@pve1 network-scripts]# cat rule-vmbr0 from 192.168.1.0/24 iif venet0 lookup internal from 192.168.1.0/24 to 192.168.1.0/24 iif venet0 lookup main
[root@pve1 network-scripts]# cat rule-vmbr1 from 200.200.100.0/23 iif venet0 lookup external from 200.200.100.0/23 to 200.200.100.0/23 iif venet0 lookup main
これらのPBRルールは下から上に追加されるため、2行目は1行目であり、その逆も同様です。また、ルール自体は、このインターフェイスが発生したときに追加することによってのみインターフェイスに関連付けられます。 結果のルールテーブル:
[root@pve1 network-scripts]# ip ru li 0: from all lookup local 32762: from 200.200.100.0/23 to 200.200.100.0/23 iif venet0 lookup main 32763: from 200.200.100.0/23 iif venet0 lookup external 32764: from 192.168.1.0/24 to 192.168.1.0/24 iif venet0 lookup main 32765: from 192.168.1.0/24 iif venet0 lookup internal 32766: from all lookup main 32767: from all lookup default
ここでは、venetを介して受信した外部ネットワークからのすべてが、外部ネットワークのルール(外部テーブル)に従ってルーティングされていることがわかります。 外部ネットワーク
200.200.100.0/23
からの1つまたは複数のアドレスは、同じマシン上の隣接する仮想マシンで発生する可能性があり、物理インターフェースではなく仮想インターフェースを介して通信する必要があります。 したがって、
200.200.100.0/23
から
200.200.100.0/23
に送信する場合、openvzが対応する
/32
ルートを追加し、他のすべての物理インターフェイスを介してルート
200.200.100.0/23
があるメインルーティングテーブルに依存します。
内部ネットワークについても同様です。
これでホストノードは、灰色のネットワークからのパケットを使用してインターネット上ですぐに消すものを理解でき、同じ静脈内の他のすべては不要です。
発信アドレスの選択方法をコンテナに伝えます
ここではすべてが簡単です。venetでは、コンテナに/ 32個のアドレスだけでなく、指定されたサブネットマスクを持つアドレスも追加できます。 これにより、このブロックのアドレスが隣接していること、およびそれらにアドレスを送信するときに次のsrcを使用することが望ましいというヒントがカーネルに与えられます。
[root@pve1 network-scripts]
[root@pve1 network-scripts]# vzctl exec 138 ip r 192.168.1.0/24 dev venet0 proto kernel scope link src 192.168.1.100 200.200.100.0/23 dev venet0 proto kernel scope link src 200.200.100.12 default dev venet0 scope link
デフォルトでは、最初のアドレスが選択されます。 したがって、コンテナ構成内のアドレスを交換すると、コンテナは内部IPを選択しようとし、ホストはNATゲートウェイを介してインターネットに送信します。
おわりに
私の意見では、venetはOpenVZの長所であり、可能であれば使用することをお勧めします。 上記のソリューションにより、コンテナはネットワーク構成から抽象化された方法でネットワークアドレスを使用できます。
さらに、主な目的に加えて、この投稿がLinuxでのポリシーベースのルーティングの使用の例として他の誰かに役立つことを願っています。