スキップしてメイン コンテンツに移動

コンテナ上でのipvsおよびiptablesの利用

従来の仮想マシンと比較して軽量な仮想環境としてコンテナが注目されている。コンテナによる仮想環境での特徴としてコンテナで同じカーネルを共有している点があげられる。

また、コンテナで実際のサービスを提供する場合、アプリケーションがほかにカーネルの提供する機能も必要となる。そこで今回はコンテナ環境下でのカーネルの機能の利用について実際に試してみた。

コンテナ上でのカーネルの機能の利用

  • コンテナではapacheやmysqlといったプロセスはそれぞれの名前空間で実行されている
  • カーネルはすべてのコンテナでホストのカーネルを利用している。
  • ipvsやiptablesはカーネル側の機能
コンテナではホストのカーネルを共有しそれぞれのコンテナごとに独立した名前空間を作成して、その上でユーザプロセスを実行することによって仮想環境を実現している。
しかし、実際のサービスなどにおいてはhttpサーバやデータベースなどのユーザプロセスだけではなくカーネルの機能も合わせて利用される。例えば、ロードバランスやパケットのフィルタリングを行う場合などはipvsやiptablesといったカーネルの機能が必要になる。
コンテナ上でカーネルの機能を利用する場合、そのカーネルについてはすべてのコンテナで共有されている点において通常とは事情が異なる。
今回はipvsおよびiptablesについて実際にコンテナ上での利用を試してみた。

システム構成

コンテナ構成図
検証としてWebサーバへのアクセスをLVSを利用してロードバランスするシステムをコンテナを利用して構成することを考える(上図)
ホストマシン2台からなる構成で、それぞれのホストにipvsを利用してWebコンテナへのロードバランスを実行するLVSコンテナ、 iptablesとapacheを使ってLVSからロードバランスされてきたアクセスを受けるWebコンテナを作成する。
以下の説明ではそれぞれのホスト及びコンテナの構成方法についての詳細は割愛して、それぞれのコンテナ上でのipvsおよびiptablesの動作および設定についてのみ述べる

LVSコンテナ

LVSコンテナは2つのネットワークインターフェースeth0、eth1を持ちそれぞれが仮想ブリッジを介して仮想イーサネット(veth)によってホストマシン(物理マシン)のインターフェースに接続されている。eth0側が外部ネットワーク、eth1側がWebコンテナ側のネットワークになっている。

ipvsの設定

ipvsの設定はコンテナ上にipvsadmによって可能である。ただし、ipvsadmを利用してコンテナ上でipvsの設定を実行する前にホスト側でip_vsモジュールをmodprobeにより読み込んでおく必要がある。

lvshost# modprobe ip_vs

またコンテナ上でipvsadmで設定を行うためにはコンテナがroot権限で実行されている必要がある。いわゆる一般ユーザ権限による非特権コンテナではipvsの設定はできないようである。
実際にipvs設定を行うと次のようになる。今回はロードバランスするアドレスは10.10.0.100としてeth0のエイリアスとして設定してある。またLVSのパケットの転送方式はダイレクトルーティング(-gオプション)を選択している。

lvs1 # ipvsadm -A -t 10.10.0.100:80 -s lc
lvs1 # ipvsadm -a -t 10.10.0.100:80 -r 192.168.0.50 -g
lvs1 # ipvsadm -a -t 10.10.0.100:80 -r 192.168.0.51 -g
lvs1 # ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.10.0.100:80 lc
  -> 192.168.10.50:80             Route   1      0          0        
  -> 192.168.10.51:80             Route   1      0          0

lvs1 # ip addr add 10.10.0.100 label eth0:100 dev eth0
lvs1 # echo 1 > /proc/sys/net/ipv4/ip_forward

 このようにipvsの設定方法は普通のLinux Boxの場合とほとんど変わらない。

Webコンテナ 

Webコンテナのネットワークインターフェースは仮想ブリッジを介して仮想イーサネット(veth)によりホストマシ ンのインターフェースに接続されている。ホストマシンのネットワークインターフェースは先ほどのLVSホストのeth1側のネットワークに接続するように 構成されている。
Webコンテナはアドレスが異なる(192.168.0.50と192.168.0.51)2つのものを作成して、それそれにLVSコンテナからロードバランスされたパケットが転送されてくるようにする。
 またここではWebコンテナは検証のためいわゆる非特権コンテナで実行されている。つまりWebコンテナ上のrootはホスト上からみた場合一般ユーザになっている。

Webコンテナの設定

コンテナ上でiptablesコマンドによりiptablesの設定は可能である。ただし、ipvsの場合と同様に設定を実行する前にホスト側でip_tablesモジュールをmodprobeにより読み込んでおく必要がある。

webhost# modprobe ip_tables

LVSでダイレクトルーティング方式での転送を選択しているので、ロードバランスされてWebコンテナに振り分けられてくるパケットの宛先はサービスアドレス(10.10.0.100)のまになっている。この宛先のパケットをWebコンテナで受け取るためにiptablesのREDIRECTターゲットを利用する。

root@web1# iptables -t nat -A PREROUTING -p tcp --dport 80 -d 10.10.0.100 -j REDIRECT

ipvsの場合と異なり、iptablesの設定はいわゆる非特権コンテナ上でも可能なようである。テスト時にWebコンテナの区別がつくようにindex.htmlにコンテナ名を記述しておく。

root@web1# echo "HELLO,This is web1" > /var/www/html/index.htm

同様にもう一つのWebコンテナ(web2)をipアドレスを変えて(192.168.0.51)作成する。本来であれば同じホストにコンテナ複数作成してロードバランスしたとしても負荷分散や冗長化という観点からはあまり意味がないが検証用にそのように構成した。

2つのWebコンテナを構成後、LVSコンテナのeth0側からサービスアドレスにアクセスするとロードバランスされていることが確認された。

$ curl http://10.10.0.100
HELLO,This is web1
$ curl http://10.10.0.100
HELLO,This is web2

コンテナ上のiptables/ipvsの設定について

作成した2つのWebコンテナでiptablesの設定を表示すると確認できるが、それぞれのコンテナで設定が独立していることがわかる。ipvsの設定も同様にコンテナごとに独立したものになる。

コンテナ上のiptablesのLOGターゲットについて

コンテナ上の場合、iptablesのLOGターゲットでのログの取得はできないようである。
これは一般的なカーネル空間のログの問題のようで、今のところカーネル空間のログをそれぞれのコンテナに関連するログごとに分けて記録するような仕組みがない。つまりコンテナからカーネル空間のログを記録する動作をした場合、すべてのコンテナおよびホストで共通になっている場所に記録される(あまり自信がありませんが)。その関係上、コンテナ上ではiptablesを利用してLOGターゲットでカーネル空間にログを出力することは、今のところ意図的にできないようになっているようである。
コンテナ上でiptablesのログを記録するには、ユーザ空間にログを出力するULOGやNFLOGターゲットを利用する必要がある。

その他

検証はしていないが、コンテナ上にインストールして実行するipvsadmやiptablesのコマンドはホストのカーネルバージョンとの互換性がある必要があるとおもわれる。

まとめ

  • iptableやipvsはコンテナでも同様に利用できる。
    • ただしホスト側での事前のモジュールの読み込みが必要である。
    • またipvsはroot権限でコンテナを実行していないと設定できない。
  • iptablesでログを取得したい場合はULOGかNFLOGを使うこと。 
これらの点に注意すれば、普通のLinux Boxと同様な方法で、コンテナを利用したロードバランサやファイアフォールをipvsやiptablesを使って構築することが可能である。ただしコンテナの場合、オーバーヘッドがなどの観点から、スループットなどについて別途検証が必要あると思われる。

参考文献
  • コンテナ上でiptablesのログターゲットが利用できない背景(カーネル空間のログの問題)はここを参考にさせていただきました。
  • 非特権コンテナについてはこちらを参考にさせていただきました(日本語約ページ)



コメント

このブログの人気の投稿

SuperMicro Update Managerを試してみる

SuperMicro社が提供している有償ツールのSuperMicro Update Manager(SUM)を試してみました。このツールを利用するとIPMIと同じ感覚でBIOS設定の確認や変更、BIOSファームウエアの更新が可能です。

SuperMicro Update Manager SUM紹介ベージhttps://www.supermicro.com/solutions/SMS_SUM.cfm

Linux起動中にBIOSの設定を確認したくなることありませんか。Windows環境のマシンであればそのようなツールもあるよう気もしますが、Linux上となるとあまり聞かないと思います。以前、Linux上でEFI変数を利用する方法を試してみたのですが、設定らしきものはバイナリデータになっていて詳細不明で、設定の変更はブートデバイスの優先順位くらいしか変更できませんでした。SuperMicro社が提供しているSuperMicro Update Managerを利用すると簡単に(同社のMB限定ですが)OS起動中にBIOSの設定を確認したり変更したりすることが可能になります。

SUMの機能などの詳細な説明は上記のWebページに詳しく紹介されていますのでそちらを参照ください。今回はBIOS周りの機能を試してみました。

SUMではツールを利用して以下のことが可能です。
BIOS設定の取得現在の設定やデフォルトの設定などをテキストファイルベースで確認できます。BIOS設定の変更テキストファイルベースで設定の変更ができます。ただし変更を反映するには再起動が必要です。BIOSファームウェアのアップデートBIOSをアップデートをそのままの環境で実行できます(DOS環境はいりません)。ただしアップデートを反映するには再起動が必要です。 また対象のサーバにアクセスする方法として二つの方法あります。
リモート(Out-band)でアクセスする。別のマシンでSUMを実行してネットワーク経由で対象サーバにアクセスするローカル(In-band)でアクセスする。対象サーバ上で起動しているOS(Llnux)上でSUMを実行して自分自身にアクセスする。 IPMIと同様に実際にBIOSの設定を取得したり変更したりするのを担っているのはMB上に搭載されているコントローラです。したがって、リモートでアクセスする場合…

SATA12台でのRAID構成可能な1Uサーバ

最近のサーバでは1Uサイズでも2.5インチのドライブを10台から12台搭載できます。しかし搭載しているRAIDカードが8ポートまで対応の製品のためにRAIDカードに接続可能なディスクは最大8台までという制限があり、残りのドライブは通常のSATAポート等に接続しなくてはならないという製品がほとんどでした。


そこでせっかく12台搭載できるのだから12台でRAIDを構成したいというご要望にお応えしてこちら(EZ1D-Scalable-SATA12)の製品をご用意しました。





サーバに搭載可能な2.5インチドライブ12台全てを利用してRAIDアレイを構成することができます。デュアルソケット対応でアプリケーションの処理性能も充分、12台で構成されたRAIDの性能をフルに発揮することが可能です。

12台でRAIDを構成することにより8台での構成の場合と比較してより柔軟にRAIDを構築することができるようになります。また8台の構成では現実的でなかった特殊なアレイ構成も可能となります。
12台のドライブによる大容量ストレージ2台のホットスペアを備えたRAID6 用途に応じた複数のRAIDアレイを1つのサーバ上に構築RAID50やRAID60といった特殊なアレイの構成
ありそうでなかった12台対応RAID搭載1Uサーバ。ぜひご検討ください。

製品の紹介ページ
EZ1D-Scalable-SATA12 主な仕様
CPU 対応CPU第2世代インテル® Xeon® スケーラブル・プロセッサー搭載CPU数2
メモリ 最大容量1.5TB(1536GB)スロット数24タイプECC対応 2666MHz DDR4 SDRAM
ネットワーク デュアルポート 1Gbpsイーサネットデュアルポート 10GbpsイーサネットRAIDコントローラSATA12ポート対応 RAIDコントローラ
RAID 0,1,5,6,10,50,60対応
キャッシュメモリプロテクションモジュール搭載ドライブベイ12 ホットスワップ対応 2.5インチ SATA/SAS ドライブベイ

GUIDパーティションとMBRブート

GUIDパーティションのディスクからGRUBで通常(MBR)起動する際のメモ。なんとなくやってできていたので気にしていませんでしたが、UEFIでのブートを試した際に今まで勘違いしていたことが分かったのでその点のまとめ GUIDパーティションディスクからの起動   GUIDパーティションテーブル(GPT)の規格はUEFI(EFI)の規格とセットであるが、GUIDパーティションテーブルのディスクからの起動にはEFIブートが必須というわけではない。
  Windowsの場合は無理な場合が多いが、LinuxではGPTのディスクからも従来通りの方法(MBRを利用した方法)での起動は可能。

GUIDパーティションテーブル   GUIDパーティションテーブルの先頭のセクタ(LBA0)は従来のMBRと同じものになっている。これは互換性や安全性のため。GPTに対応していない機器にディスクを接続してしまったときに、ディスクと認識されなかったり、さらには初期化のされていないディスクと勘違いされていきなり初期化されたりしないようにするため。
  従来のMBRパーティションでは、MBR内にパーティション情報を格納してたが、GPTではここにはパーティションを情報を格納しない。MBRにつづく第2セクタ(LBA1)にあるパーティションテーブルヘッダおよび第3セクタからはじまるパーティションエントリに情報を格納する。
  MBRパーテョンでは基本パーテョションが4つまでであったり、大きなサイズ(2TB以上)のディスクを扱えなかったりしたのは、MBR内のパーティション情報を格納する領域の大きさ的にそれが限界であったため。
  GPTではこのパーテョション情報を格納する領域は十分に広い。パーティションは128個まで、ディスクサイズは8ZiB(ゼビバイト)まで扱える(もちろん、情報が格納できるというだけで実際に使えるかどうかはOSなどの対応による)

MBRブート   MBRブートでのブートローダはMBR内に格納する。MBRのサイズは全体で512B(1セクタ)であるが上記のパーティションテーブル情報分があるのでブートローダに利用できる領域は446Bしか用意されていない。
  このサイズでは多機能なブートローダは格納できない。そこでGRUBなどの多機能なブートローダでは、MBR内には多機能なブートローダの本…