Archive for the ‘iscsi’ tag
iSCSI Initiatorのタイムアウト設定
Linux環境のiscsi-initiator-utilsを用いた際に重要となるタイムアウト関連の設定について。
信頼性の高いシステムでは当然iSCSIストレージへの接続も冗長化するという要件があります。汎用的な実装だとdevice-mapper-multipathを使ってストレージネットワークの障害に対しての冗長構成でとることができます。また、OracleのASMを使ったStorage GRID構成では複数ストレージをストライピング&ミラーリングし、例えストレージが筐体ごとパワーダウンしてもオンラインで処理を継続することができます。このStorage GRID構成で重要なのがiSCSI Initiatorのタイムアウト設定です。
iSCSIストレージへの接続性に不具合が発生した場合、iSCSI Initiatorが死活監視によってそれを検出します。最終的にはiSCSI InitiatorがiSCSI Targetへの接続障害という判定を行い、それをI/Oエラーという形でOSに報告します。ASMはその報告をもってストレージの切り離しを行い、残るストレージで処理を再開、継続します。障害が起こってからiSCSI InitiatorがI/Oエラーを報告するまでの間は全てのI/Oが一旦保留されます。本番環境ではこの保留される時間を制御したいという要件が出てくるでしょう。
下記のような障害パターンで上記の保留期間を制御するためのiSCSI Initiator設定を紹介します。
- クライアント側のNIC故障
- iSCSIネットワーク断(ケーブル劣化、スイッチ故障)
- iSCSIストレージのパワーダウン、コントローラ故障
ちなみにiSCSI InitiatorはOracle Enterprise Linux 5.4にバンドルされるiscsi-initiator-utils-6.2.0で動作を確認しています。前後のバージョンでもデフォルト値は変更されている可能性はありますが、挙動に大きな違いはないと思います。
重要なパラメータは下記の3つです。
- node.conn[0].timeo.noop_out_interval(デフォルト5秒)
pingによるコネクションの死活監視間隔
- node.conn[0].timeo.noop_out_timeout (デフォルト5秒)
pingによるコネクションの死活監視がコネクションエラーと判定するまでの待ち時間
- node.session.timeo.replacement_timeout(デフォルト120秒)
コネクションエラーが発生してからI/Oエラーを返すまでの待ち時間。この時間までに死活監視がコネクション復帰を報告すればI/Oエラーは返らない。
デフォルト設定で障害が発生した場合、下記のような流れとなります。
- 死活監視のpingが発行される(タイミングによって障害発生から1〜5秒経過)
- pingがタイムアウトする(+5秒経過)
- 継続して死活監視のpingが発行され、最終的にpingが成功しないとOSにI/Oエラーが返る(+120秒経過)
- ASMがI/Oエラーを検出して障害ストレージを切り離し、残りのストレージで処理を再開する(即時)
経過時間をまとめると、(1〜5)+ 5 + 120 = 126〜130秒程の時間が切り替えまでに必要となります。
これを例えば障害試験等で確実に15秒程で切り替えを発動させたい場合は次のように設定すれば実現できます。
- node.conn[0].timeo.noop_out_interval = 1
- node.conn[0].timeo.noop_out_timeout = 5
- node.session.timeo.replacement_timeout = 10
この場合経過時間は(〜1)+ 5 + 10 = 15〜16秒となります。
このiSCSI Initiatorのパラメータ設定は下記のiscsiadmコマンドで設定できます。ただし、ログイン済みのセッションについては反映されません。反映させるには一旦ログアウトし、再度ログインしてセッションを再確立させる必要があります。
[root@~]# iscsiadm -m node -p [ターゲットのIP] -o update -n [パラメータ名] -v [設定値]
また、/etc/iscsi/iscsid.confを編集しておくことで新たに登録されるiSCSIターゲットについてのデフォルト値を変更することができます。これは既に登録されているiSCSIターゲットには反映されないので注意してください。
仮想化環境ではiSCSIとFibre Channel, どっちがお薦め?
よく「仮想化ではストレージはどの接続形態がお薦めですか?」と質問を受けます。つまりはFC (Fibre Channel), iSCSI, NFSのうち、どれ?ということです。今回はNFSは置いといてFCとiSCSIについて考察してみます。
多くの場合争点となるのは以下のポイントだと思います。
- 性能
一般にFCの方が性能的に優れていると認識されています。これはFC DiskかSAS Diskかというディスクの違いもありますが、明らかに違うのはネットワークの帯域でしょう。iSCSIが利用するバックボーンはEthernetであり現在ほとんどのiSCSIネットワークは1GbpsのEthernetで構成されています。10Gbpsの機材も販売されはじめていますが、コストがまだまだ高いのが現状です。一方FCのネットワークでは4Gbpsが主流で、理論値ではGigabit Ethernet約4倍の差があります。(また、8GbpsのFCも出てきつつありますね) ということでそもそもはこの帯域の差をもって「iSCSIだと性能が不安だ」ということになっていると思います。
*ドライバの安定に関する不安も少しあるかもしれませんね。
10Gbpsを使わない限りこの差があるのは事実ですが、ストレージの性能とはネットワーク帯域だけではありません。ストレージの性能にはボトルネックになり得るポイントがいくつかありますよね。
①サーバ側のネットワークポートの帯域幅
②ストレージ側のネットワークポートの帯域幅
③サーバのCPU
④ストレージのコントローラ
⑤ストレージのディスク
この中で①と②の「ネットワーク帯域幅」がiSCSiとFCで性能に明らかな差がある部分です。しかしこの中には帯域幅よりも先にボトルネックとなりがちなポイントがあります。
⑤ストレージのディスクです。
ディスクの本数にもよりますが12本程度のディスクでランダムRead/Writeの負荷をかけると、帯域幅という面では1Gbpsにも到達しないでしょう。実際はストレージには複数のポートが装備されているので帯域的にはかなり余裕のある状態です。となるとFCとiSCSIの差はなくなります(ディスク自体がFC, SASと違う場合にはその部分は依然として残る)。実際とあるストレージ機器ではFCモデルとiSCSIモデルでシーケンシャルRead/WriteではFCが勝るものの、ランダムRead/Writeではどちらも同じIOPSになっています。となると「うちはストレージの負荷がかなり高いからiSCSIなんて無理だよー」と思っている人もその負荷がランダムRead/WriteであるならばFCにこだわるよりもより「ディスクの本数を増やす」ことに注力すべきでしょう。あるいはSSDというのも熱い選択肢だと思います。
- コスト
FCストレージ自体がそもそもはハイエンドというイメージがあり、iSCSIは廉価というイメージがあります。実際はFCストレージでも価格のこなれたローエンドの機種も存在します。しかしFCスイッチやHBAはEthernetのL2スイッチやNICと比べて相当に高価であることは間違いありません。HBA等はたかだかカードだと思って見積もりをとってみるとその価格に驚きます。結果的にFCの方がコスト高になる傾向にあることは事実だと思います。
そしてこれはあまり注目されることはありませんが、特に仮想化環境で重要な要素に「管理性」があると思っています。
- 管理性
例えば一つのVM Server(ホストの方)上で20個のゲストOS(仮想マシン)を起動するとします。そしてそれぞれのゲストOSに対して専用のボリューム(Logical Unit)を作成して割り当てる場合、2通りの方法があります。一つは一度dom0でボリュームを認識し、それをゲストOSに貸し出す方法。これはFC, iSCSIともに可能です。もう一つはdom0は関知せずゲストOSが直接ストレージに接続してボリュームを認識する方法です。
詳しくはこのあたりの記事をご覧ください。
http://www.oracle.com/technology/global/jp/pub/jp/seminar/nakajima_ovm_bp1.html
後者はPCIパススルー等の特殊な手法を除いてFCでは実装できません。iSCSIのみで実現可能です。後者はdom0で貸し出すボリュームをマネージする必要がなくなるので管理作業(ボリュームをゲストOSに貸し出すという作業)を一つ省くことができ、よりシンプルです。そして重要なのがアクセス制御です。前者のdom0でボリュームをマネージする形態では20個のゲストOS用のボリュームをすべてdom0が「仕分け」しなければいけません。このボリュームはこのゲストOS、このボリュームはこのゲストOS・・・といった具合です。数が多くなるほどオエッとなる作業ですよね。一方iSCSIであればイニシエータIQN等で簡単にアクセス制御をかけることができます。つまりあらかじめストレージ側でボリュームの設定さえしておけば、すべてのゲストOSは同じようにストレージに接続するだけで自分用の領域だけが見える、という状態にできます。この場合仕分けは必要なくなるのでかなり管理が楽になるはずです。Linuxでは通常iSCSIイニシエータIQNはOS毎にランダムな値が自動生成されて/etc/iscsi/initiatorname.iscsiに設定されています。ただしこれは任意に設定することが可能です。僕は自分のVMテンプレートに、起動時にホスト名を元にイニシエータIQNを自動設定するロジックを組み込んでいます。例えばnkjm-001というホスト名だとすると、/etc/iscsi/initiatorname.iscsiは起動時に次のように自動生成されます。
InitiatorName=iqn.com.oracle.jp:nkjm-001
そうすることでいちいちゲストOSのイニシエータIQNを調べなくても、あらかじめ予測してストレージ側で設定しておくことが可能です。
*ちなみにこのイニシエータIQNによるアクセス制御は「セキュリティ」を意識したものではなく、「適切なボリュームに間違いなく接続するため」のものです。セキュリティを意識するのであればさらにCHAP認証等が必要でしょう。
ということで僕は特にFCを必要とする要件(シーケンシャルReadだらけ。帯域命。みたいな。)がない限りはiSCSIの方がお薦めだと思っています。
ただしサーバ側のネットワークポートの帯域が詰まった場合には少し工夫が必要です。最も単純なのはゲストOS毎にアタッチする物理ネットワークポートを切り替えることですが、これは少しばかりモサい運用であると言わざるを得ません。Bondingで帯域を増やせれば一番楽ですが、スイッチを冗長化した構成でActive/ActiveのBondingを動かすには注意が必要で、Active/Standbyのようにおいそれとは動きません。方式も単純なラウンドロビンから802.3adのようなプロトコルまであるため、機器の相性を確認しながらネットワークを慎重に構成する必要があるでしょう。あとはBondingではなくDevice Mapper Multipath等を使ったマルチパス。ただしマルチパスもストレージとの相性があり、とあるストレージは「このマルチパスドライバじゃないとダメ」とかいろいろあるので少し混沌としています。
このあたりは一口にどればベストと言い切るのは難しいところです。
共通して言えることは、
- iSCSIは試してみるべき。食わず嫌いは勿体ない。
- 負荷の特性を知るべき。その結果によって帯域が必要なのかディスクのスループットが必要なのか見極める。
- ディスクのスループットが必要な場合は単価の低い機器でディスク本数を増やすのがベスト。SSDも素晴らしい選択肢。
- 並べて増やしたディスクはASMで一つの大きなストレージに変身させる(ASMはOracleデータベースのすべてのエディションに基本機能として付属しているストレージ管理機構です)。ASMはデータベースだけでなくファイルシステムにも使えるあり得ないストレージ管理機構。複数のディスクをまとめてミラーリング、ストライピングし、さらにホットスワップが可能で自動的にオンラインリバランスする。ハイエンドストレージさん、さようなら。
ということでややもすれば強引な気もしますが最後にASM登場。でもこれ、正直ベースで個人的に最強の構成だと思ってるんですよね。
仮想化+ASM+iSCSIについては近々セミナーで「詳解xxx」みたいな形でお話する予定です。多分関西で。年明けに。
また正式にセッション構成を固めたらご案内させていただきヤス!
ZFSのiSCSI TargetをLinuxから利用するときのアクセス制御設定
仮想化環境でゲストOSにネットワーク経由(iSCSI)で直接ストレージを認識させる場合、ストレージ側で何らかの接続制御を行う必要に迫られます。何も制御してないと、ゲストOS: NKJMからゲストOS:SUZUKI用のボリュームに接続できてしまったりと、意図的であろうとなかろうと本来接続するボリュームとは違うボリュームに接続してしまう可能性があるからです。
ちなみにゲストOSから直接ストレージを認識させる形式ではなく、一旦ホストOS(dom0)に認識させてからゲストOSに貸し出すような形であればホストOS側で制御できるのでそこまでデリケートになる必要はないでしょう。
今回はiSCSIストレージにZFS、ゲストOSにLinux(Oracle Enterprise Linux 5.x, Redhat Enterprise Linux 5.x, CentOS 5.x)を使用しているときのアクセス制御についてまとめておきます。
「オペレーションミスを予防する」という目的であればInitiator IQNでアクセス制御する程度がシンプルでいいでしょう。しかしInitiator IQNは簡単に詐称できるので、セキュリティを真に確保しなければいけないPublicな環境であればより強固な認証を実施することが求められるでしょう。
それぞれの制御方法について順に紹介していきます。
Initiator IQNで認証
特定のTargetにアクセスできるInitiator IQNをあらかじめ定義しておき、アクセス時のInitiator IQNをベースに制御を行うものです。
Initiator側(Linux)
特に設定は必要ありませんが、Initiator IQNの情報だけ取得しておく必要があります。
[root@initiator1]# cat /etc/iscsi/initiatorname.iscsi InitiatorName=iqn.1994-05.com.redhat:123456
Target側(OpenSolaris)
まず接続を許可するInitiator IQNのオブジェクトを作成します。オブジェクト名は何でも構いませんが今回はinitiator1としています。
[root@target]# iscsitadm create initiator -n iqn.1994-05.com.redhat:123456 initiator1
次にそのInitiatorオブジェクトと、アクセスを許可したいTargetを紐づけます。
[root@target]# iscsitadm modify target -l initiator1 [TARGET_NAME]
これでTARGET_NAMEはinitiator1,つまりiqn.1994-05.com.redhat:123456からのアクセスのみを許可するようになります。
CHAP認証
CHAP認証ではInitiator IQNの検査に加えusername/passwordによる認証を行います。
Initiator側(Linux)
CHAPのusername/passwordを設定します。これには設定ファイルを編集する方法と、TargetをDiscoveryして登録し、登録されたTargetのプロファイルを設定する方法があります。前者はグローバルなデフォルト設定になるので、新しく登録されたTargetにはすべてこの設定ファイルに記載されているusername/passwordでログインしにいくようになります。Target個別に認証方法やusername/passwordを設定する場合は後者の方法で設定する必要があります。以下では前者の設定ファイルの編集を解説します。
[root@initiator1]# vi /etc/iscsi/iscsid.conf node.session.auth.authmethod = CHAP node.session.auth.username = user1 node.session.auth.password = zfszfszfszfs (12文字以上16文字以内)
編集が完了したら設定を反映させるためにiscsidをリスタートします。
[root@initiator1]# service iscsi restart
以上でInitiator側の設定は完了です。
Target側(OpenSolaris)
まず接続を許可するInitiator IQNのオブジェクトを作成します。オブジェクト名は何でも構いませんが今回はinitiator1としています。
[root@target]# iscsitadm create initiator -n iqn.1994-05.com.redhat:123456 initiator1
次にそのInitiatorにusername/passwordを設定します。これはInitiator側で設定したusername/passwordと一致しなければなりません。
まずはusernameです。
[root@target]# iscsitadm modify initiator -H initiator1 user1
次にpasswordです。
[root@target]# iscsitadm modify initiator -C initiator1 *プロンプトが表示され、パスワード(今回はzfszfszfszfs)を2度入力します。
次にそのInitiatorオブジェクトと、アクセスを許可したいTargetを紐づけます。
[root@target]# iscsitadm modify target -l initiator1 [TARGET_NAME]
これでTARGET_NAMEはinitiator1,つまりiqn.1994-05.com.redhat:123456からのアクセスのみを許可し、さらにCHAPの認証が通った場合だけアクセスできるようになります。以下のようにInitiator側から登録とログインを行ってみてください。
[root@initiator1]# iscsiadm -m discovery -t st -p [TARGET_IP] [root@initiator1]# iscsiadm -m node --login
なお、すでにInitiator側でTargetを登録した状態でiscsid.confを編集してservice iscsi restartしてもログインは成功しません。すでにそのTargetのプロファイルはCHAP認証なしということで作成されているからです。この場合は一度プロファイルをiscsiadm -m node -o deleteとして削除してdiscoverからやり直すか、Targetのプロファイルを個別に設定してやる必要があります。その方法を以下に記載しておきます。
[root@initiator1]# iscsiadm -m node -T [TARGET_IQN] -o update -n node.session.auth.authmethod -v CHAP [root@initiator1]# iscsiadm -m node -T [TARGET_IQN] -o update -n node.session.auth.username -n user1 [root@initiator1]# iscsiadm -m node -T [TARGET_IQN] -o update -n node.session.auth.password -n zfszfszfszfs
という感じです。
HPのiSCSIストレージ新製品LeftHand P4000シリーズがよさげ
http://www.atmarkit.co.jp/news/200907/27/lefthand.html
好みな感じ。
LeftHand P4000 SANは米HPが2008年に買収した米Lefthand Networksの製品 – @ITより -
とのこと。日本にはストレージのベンチャーなんてないので不思議な感覚。EqualLogicとかもそうだし海外はストレージ製品のベンチャー多いのかな。
さて、LeftHandの気になるのは以下のポイント。
- EqualLogicに似た考え方
- iSCSIのリダイレクトを使うのではなく、直接ターゲットのIPを特定できる
- Snapshotに事前容量割り当てが必要ない
- 10GbEサポート
- ちょうどいい価格帯(500〜1000)
2台程ほしい。貸していただけないかな。
iSCSI Enterprise Targetを使ってLinuxをiSCSI Storageにしてしまう
iet(iSCSI Enterprise Target)はLinuxマシンをiSCSIターゲット、つまりiSCSI Storageにすることができるオープンソースソフトウェアです。カーネルモジュールと管理ツールで構成されています。それでは早速インストールしましょう。
まずはソースを入手します。
http://sourceforge.net/projects/iscsitarget/files/
現時点での最新版は0.4.17です。今回はこのバージョンで話を進めます。ダウンロードしたら展開してコンパイルします。
[root@storage]# tar xvfz iscsitarget-0.4.17.tar.gz [root@storage]# cd iscsitarget-0..4.17/ [root@storage]# make [root@storage]# make install
という感じで基本的には猫でもできる系ですが、いくつかの開発パッケージが入っている必要があります。openssl-develとかkernel-xen-develとか(←準仮想化マシンを使っている場合)。もし怒られた場合はup2date kernel-xen-devel等としてインストールします。
これでもうインストールは完了です。次に設定に入ります。設定もシンプルで/etc/ietd.confにまとめられています。この設定ファイルを編集します。
Target net.nkjmkzk.storage:a Lun 0 Path=/dev/iscsi/a-DATA1,Type=fileio Lun 1 Path=/dev/iscsi/a-FRA1,Type=fileio MaxConnections 2 Target net.nkjmkzk.storage:b Lun 0 Path=/dev/iscsi/b-DATA1,Type=fileio Lun 1 Path=/dev/iscsi/b-FRA1,Type=fileio MaxConnections 2
設定ファイルを編集したらiscsi-targetデーモンを起動します。
[root@storage]# service iscsi-target start
以後設定ファイルの編集後はservice iscsi-target restartにてデーモンを再起動することで設定変更を反映することができます。上記設定ファイルの意味は次の通りです。
まずTargetでTarget IQNを設定します。Target IQNはいわばiSCSIにおける宛先アドレスです。Initiator(iSCSIにおける接続元)はまず以下のようにietを動かしているサーバのIPアドレスを指定してスキャンし、そのietサーバ上のTarget IQNを調べます。そして見つかったTargetを接続先として登録します。
[root@client]# iscsiadm -m discovery -t sendtargets -p storage.nkjmkzk.net 192.168.0.121:3260,1 net.nkjmkzk.storage:a 192.168.0.122:3260,1 net.nkjmkzk.storage:b
[root@client]# iscsiadm -m node -T net.nkjmkzk.storage:a --login
正常にietに接続できればdmesgコマンド等で論理ボリュームをどのように認識したか確認することができます。
ここまででとりあえずクライアントから使用可能な状態になります。あとは認証や細かな設定値を追加したり、というところでしょうか。
LinuxでiSCSIを利用する
LinuxでiSCSIのストレージを利用するにはカーネルでiSCSIのドライバが有効になっていて、iSCSIイニシエータのソフトウェアがインストールされている必要があります。ドライバはディストリビューション付属のカーネルであれば大抵有効になっていると思いますので、iSCSIイニシエータのセットアップから開始します。Redhatであればiscsi-initiator-utilsとしてRPMが用意されていますのでこれをインストールします。
# yum install iscsi-initiator-utils
次にiscsiデーモンを起動します。
# service iscsi start
ここからイニシエータの設定を行っていきます。イニシエータの情報はデータベース管理されており、iscsiadmコマンドを用いてこのデータベースを参照、更新できます。
最初にターゲットの情報を取得してデータベースに登録します。
# iscsiadm -m discovery -t sendtargets -p 192.168.12.146 192.168.12.146:3260,1 iqn.1994-04.jp.co.hitachi:rsd.d7h.t.11799.1a000 192.168.12.143:3260,1 iqn.1994-04.jp.co.hitachi:rsd.d7h.t.11799.0a000
-pオプションで指定したストレージのコントローラで接続可能なターゲットの情報一覧が表示されます。同時にデータベースへの登録も行われています。
次に接続したいターゲットを指定してログインします。
# iscsiadm -m node -T iqn.1994-04.jp.co.hitachi:rsd.d7h.t.11799.1a000 -p 192.168.12.146 --login
dmesgをみるとストレージが/dev/sdaとして認識されたことが確認できます。
# dmesg scsi0 : iSCSI Initiator over TCP/IP Vendor: HITACHI Model: DF600F Rev: 0000 Type: Direct-Access ANSI SCSI revision: 04 SCSI device sda: 503316480 512-byte hdwr sectors (257698 MB) sda: Write Protect is off sda: Mode Sense: 77 00 00 08 SCSI device sda: drive cache: write through SCSI device sda: 503316480 512-byte hdwr sectors (257698 MB) sda: Write Protect is off sda: Mode Sense: 77 00 00 08 SCSI device sda: drive cache: write through sda: unknown partition table sd 0:0:0:0: Attached scsi disk sda
この後は通常どおりのブロックデバイスの操作です。
普通にパーティションを作成するにはfdisk等を用います。
# fdisk /dev/sda
あるいはLVMを使用しているのであればpvcreateで物理ボリュームとして登録します。
# pvcreate /dev/sda
基本的なセットアップは完了です。
ターゲットについての設定情報を参照するには以下のようにします。
# iscsiadm -m node -T iqn.1994-04.jp.co.hitachi:rsd.d7h.t.11799.1a000 -p 192.168.12.146 node.name = iqn.1994-04.jp.co.hitachi:rsd.d7h.t.11799.1a000 node.transport_name = tcp node.tpgt = 1 node.active_conn = 1 node.startup = automatic node.session.initial_cmdsn = 0 node.session.auth.authmethod = None node.session.auth.username = node.session.auth.password = node.session.auth.username_in = node.session.auth.password_in = node.session.timeo.replacement_timeout = 120 node.session.err_timeo.abort_timeout = 10 node.session.err_timeo.reset_timeout = 30 node.session.iscsi.InitialR2T = No node.session.iscsi.ImmediateData = Yes node.session.iscsi.FirstBurstLength = 262144 node.session.iscsi.MaxBurstLength = 16776192 node.session.iscsi.DefaultTime2Retain = 0 node.session.iscsi.DefaultTime2Wait = 0 node.session.iscsi.MaxConnections = 1 node.session.iscsi.MaxOutstandingR2T = 1 node.session.iscsi.ERL = 0 node.conn[0].address = 192.168.12.146 node.conn[0].port = 3260 node.conn[0].startup = manual node.conn[0].tcp.window_size = 524288 node.conn[0].tcp.type_of_service = 0 node.conn[0].timeo.logout_timeout = 15 node.conn[0].timeo.login_timeout = 15 node.conn[0].timeo.auth_timeout = 45 node.conn[0].timeo.active_timeout = 5 node.conn[0].timeo.idle_timeout = 60 node.conn[0].timeo.ping_timeout = 5 node.conn[0].timeo.noop_out_interval = 10 node.conn[0].timeo.noop_out_timeout = 15 node.conn[0].iscsi.MaxRecvDataSegmentLength = 65536 node.conn[0].iscsi.HeaderDigest = None,CRC32C node.conn[0].iscsi.DataDigest = None node.conn[0].iscsi.IFMarker = No node.conn[0].iscsi.OFMarker = No
これらの設定情報を編集するには同じくiscsiadmコマンドをアップデートモード実行します。
* -o update : 操作モードをアップデートモードに指定
* -n : 設定項目を指定
* -v : 設定項目の値を指定