iptablesでの受信接続のバランス

着信接続を受け入れるサービスがあり、負荷やフォールトトレランスのバランスを取るタスクが発生したとします。



一般に、スキームは次のようになります。

----> ---> ()









特定のニーズに対応する既製のバランサーが多数あります。 たとえば、nginxはWebアプリケーション用の優れたバランサーであり 、tcp接続用のhaproxyです。







実際、それはすべて特定の状況に依存するので、レシピを書いて、それがどこで役立つかを自分で決めてください。



レシピ



バランスを取るために、統計、条件、およびラベル付けモジュールを使用します。

これらのモジュールのすべてがデフォルトではありません。 古いバージョンのLinuxでは、統計の代わりにn番目を探し、プロジェクトサイトから手動で条件を設定する必要がある場合があります



ここで、サービスがsmtpサーバーであるとします。

外部IPアドレスを10.0.0.1にします

サービスの内部IPアドレスは192.168.0.1と192.168.0.2になります



マングルテーブルに次のルールセットを作成します。



*マングル

:MAILMARK-[0:0]



-A MAILMARK -j CONNMARK --restore-mark

-A MAILMARK -m mark --mark 0x0 -m statistic --mode nth --every 2 -m condition! --condition mail1up -j MARK --set-mark 1

-A MAILMARK -m mark --mark 0x0 -m condition! --condition mail2up -j MARK --set-mark 2

-A MAILMARK -m mark --mark 0x0 -m condition! --condition mail1up -j MARK --set-mark 1

-A MAILMARK -j CONNMARK --save-mark



-A事前設定-d 10.0.0.1 -p tcp --dport 25 -j MAILMARK



コミット





また、natテーブルでは次のようになります。

-A PREROUTING -d 10.0.0.1 -p tcp --dport 25 -i bond0.204 -m mark --mark 1 -j DNAT --to-destination 192.168.0.1

-A PREROUTING -d 10.0.0.1 -p tcp --dport 25 -i bond0.204 -m mark --mark 2 -j DNAT --to-destination 192.168.0.2





以上で、すべての仕組みを説明することができます。



まず、ポート25の外部アドレス10.0.0.1への着信パケットは、マングルテーブルとラベル付けルールを通過します。

-A事前設定-d 10.0.0.1 -p tcp --dport 25 -j MAILMARK




マーキングのために、別個のMAILMARKチェーンが作成され、次のように機能します。

接続がすでにマークされている場合、パッケージを接続と同じ値でマークします。

-A MAILMARK -j CONNMARK --restore-mark


したがって、1つの接続のパケットは、その後1つのサービスバックエンドで終了します。

パッケージにマークが付いていない場合は、次のルールでマークしてください。

-A MAILMARK -m mark --mark 0x0 -m statistic --mode nth --every 2 -m condition! --condition mail1up -j MARK --set-mark 1


-m mark --mark 0x0
パッケージがまだマークされていないという条件

-m statistic --mode nth --every 2
2番目のパケットごとにマークします。 つまり 負荷のバランスは非常に単純に50/50ですが、これが唯一の可能性ではありません(ランダムと統計を参照)

-m状態! -条件mail1up
バックエンドが稼働している状態

-j MARK-セットマーク1
値1でパッケージをマークします



パケットにマークが付いていない場合、バックエンドが稼働している場合はラベル2でマークします

-A MAILMARK -m mark --mark 0x0 -m condition! --condition mail2up -j MARK --set-mark 2


パケットがまだマークされていない場合、明らかに2番目のバックエンドが停止し、最初のラベルが設定されていないようです。 50/50で不運だったか、最初のバックエンドも死にました。 最初のバックエンドがまだ動作している場合、パッケージにラベル1を付けます

-A MAILMARK -m mark --mark 0x0 -m condition! --condition mail1up -j MARK --set-mark 1


現在の接続について覚えておく最後のルールはラベルです

-A MAILMARK -j CONNMARK --save-mark




パッケージにマークが付けられた後、natテーブルに追加されたルールによって、選択されたバックエンドにパッケージが変換されます



バックエンドが生きていることをiptablesがどのように理解するかに関連する別のポイントを明らかにすることは残っています。

方法はありません。これを自分で行い、バックエンドが生きているか死んでいるかに応じて、ファイル/ proc / net / nf_condition / mail1upおよび/ proc / net / nf_condition / mail2up 0または1を入れる必要があります。

デフォルトでは、iptablesを起動すると、これらのファイルは0になります。

指定されたルールは、0がバックエンドが稼働していることを意味するように設計されています。

たとえば、SMTPサーバーを確認するには、次のbashスクリプトを使用します

 #!/bin/bash get () { response=$(echo "QUIT" | nc -w 5 $1 25 | head -1 | awk '{print $1}') if [ "$response" == "220" ] then echo "0" else echo "1" fi } echo $(get 192.168.0.1) > /proc/net/nf_condition/mail1up echo $(get 192.168.0.2) > /proc/net/nf_condition/mail2up
      
      







おわりに



一方では、おそらくそれだけを行う正当な理由はおそらくないでしょうが、他方では、それらについて考えることができます。

  1. iptablesはカーネルレベルで実行され、他のどのバランサーよりも高速である可能性が高い
  2. iptablesはより信頼性があります。 たとえば、バランサー間でフェイルオーバーが発生すると、同じhaproxyが正常に起動するという事実ではありません。 開始するにはもっと多くの条件が必要です。 たとえば、IPアドレス10.0.0.1をインターセプトする必要があり、その後でのみポート25でhaproxyを実行できます。 たとえば、この間に誰かが設定ファイルを台無しにしたため、まったく起動しません。



All Articles