ネットワーク試験の覚え書き

お仕事柄、検証とか試験とかやることが多いのだけど、特に最近「とにかく時間がない」ので「それなりに設計わかってて機材を扱えて手が動かせる奴」みたいな呼ばれ方でそういう仕事をすることが多いんだよね。どうもこの先じり貧になることが予想されるような呼び方で…というかそんな都合のいい奴おらんつの普通……、と…話を戻して。ちょっと見方を変えれば、設計とか構成とか機材知識とか諸々がなければ試験とか検証とかできない訳で、いきなり投入されても動けないし、効率的に回そうと思うとある程度場数を踏んでいないといけない仕事でもあるんだよね。

一仕事明けた週末と言うことで、そういう作業をやったことない人を対象に、個人的にはこういうことを知っておいて欲しいというアタリを書き出してみる。

作業計画

  • そもそも試験で何を見たいのかを明確にすること。機器の動作確認? エンドユーザへのサービス影響? バグの再現? 見たいものに寄ってみるべきものや指標が変わる。この試験項目に対して、どういう状態になるべきか・どういう動作をするべきなのか。成功と判断できる指標は何か。「予期しない動作」というのであれば予期していた動作がなければいけない。事前の予測なしに試験をしても意味がない。
  • 理想的には、何も考えずに作業が実施できるレベルの作業計画・作業手順ができていることが望ましい。「手順」についてはまあ後述するとして…作業中に「このコマンド何だっけ」とか「あ、途中からコマンドのオプション変えて取ってた」とか「手順一つ飛ばしちゃった」とかゆらゆら作業をしていていいことなんて一つもない。場合によっては、確認したい事象は数秒から数十秒で変化する動的な事象だったりする。作業中は観測したい事象に注力できるようになっているべきである。
  • 通信やサービスの確認方法、影響の基準(試験の正否の判定基準)を決めておくこと。
    • 単に通信ができれば良い、であれば ping でよいだろう。その場合も、ping の間隔、Timeout の時間など、設定を決めておく必要がある。ping 中断しなければ成功? 5秒未満の停止なら成功? とか。
    • LBの動作確認などであれば HTTP/HTTPS で通信した状況で作業を行う必要がある。サーバのヘルスチェックや Cookie 情報、Keepalive、HTTP/1.0 なのか 1.1 なのか、とか、アプリやサーバの設定・確認したいことによって試験用通信を設定する。
  • 通信はフローで考える。どこからどこに対してどういう通信を発生させるか、障害が起きたときにどういう経路に切り替わるか、あらかじめ想定しておくこと。「予想したとおりにそこを通っていること」をどう確認するか? traceroute? Packet Count? Packet Capture?

特定の障害や設定変更があったときに、何がどう変わるか? あるいは変わらない(はず)か? それを確認するためには、どこからどこに、どういう通信を発生させておく必要があるか? 予想したとおりに動作していることを確認するためには、何をしたら良いか? 正否をどのように判断するか?

えーとね。試験項目考えて来てってお願いしてよくわからない項目があるのできいたら「前もやっていたので」とかそういうのは無意味だからやめてくださいってことです。

作業手順作成

  • バグ対応依頼などを行う際などは特に、再現性が重要。どういった手順で何を行うとバグが再現するのか? 操作の際は手順を記録すること。TeraTermなら自動的にログを取得するように設定できる。Linuxなら script コマンドを最初に実行する、とか。ログ取得まで含めて自動化するのがベストだろう。
    • スクリプト化するなら、OS Version とか機器ステータス情報とかその辺の機器情報等に出力まで含めてしまうのが吉。
  • 前述の通り、考えなくても試験が実施できるレベルが理想。
    • 手順書はコマンドの羅列で良いが、時刻確認、状態確認など発行するコマンドをいちいちすべて列挙しておくべき。「ここは前の(X)と同じ」、とか省略してはいけない*1
    • 手順やコマンドの追加・変更・削除をした場合はその理由を付記しておくこと。明確な手順があれば再現性が確保できる。他の人でも実行できるレベルの記録が必要。
  • 複数回試験をするのであれば、設定や手順を固定してからやること。毎回手順や確認方法が違うような試験をすると結果の比較ができない。一度手順を確定してしまえば、試験自体は機械的に進められる。あと実行結果が定型のテキストベースのデータで残っているなら diff でチェックができるようになる(変更前後によるログの比較・異なる試験とのログの比較)。目grep/目diffは技能であって技術ではないので人力に頼らないで確実にやれる方法を選択すること。

操作ログとして含める情報には以下のものがある。

  • このログファイルを見て一目で何の試験を行ったのかがわかるか?
    • 試験名とか試験番号などの情報。ログにコメントを入れておくことも有効 "# start TEST 1.2" とか。後でログを検索することを想定すること。確認すべきチェックポイントに検索ワードを入れておくと後からの確認が楽になる。
  • 事前状態・事後状態を記録しておくこと。イベントや変更の前後で必要。冗長化設定・Act/Stbなどの状態、コンフィグ、ログレベル、デバッグコマンド設定、インタフェース状態など。確認しておきたい事象の他に付随する環境情報を取っておく(事前・事後で確認できるようにしておく)必要がある。
  • 時刻情報
    • 操作ログは時刻付きで取ること。Ciscoなら "exec prompt timestamp", Linux なら "date; " とかしながら作業を行う。操作は時刻出力コマンドをつけた上でスクリプト化・自動化するのが望ましい。
  • 作業記録(何月何日の何時から何時はこの試験、などの記録)などとの突き合わせを考えるとちゃんと実時間を使用した時刻同期をした方がよい。

だいたい、あまりこういう作業の経験がない新人さんとかにとりあえずやってもらうと、このへん端折ってしまう傾向がある気がする。手順や基準を変えてしまうと再現性の保証が難しくなるし、作業後とのチェック漏れや複数の作業での変化・比較が非常に困難になる。
または観測手段を用意しないまま作業を始めて確認できていないことに気づいて手戻り、とか…。観測手段の例として、LB がらみの試験である程度通信が継続した状態を維持したいというような場合はこういうことをよくやる。

  • dd で 1GB くらいのファイル用意して、クライアント側 NIC の通信速度を 10Mbps とかに落とした上で試験
  • テストページに Cookie 確認するための javascript とかを仕込んでおけると動作確認がしやすい

他には FTP で /dev/null コピーでひたすら通信を発生させる、なんてのもあったなあ…

[追記 2011-08-01]
ICMP で通信チェックする際、サーバだけに icmp 打っていると、切れたときにサーバ側に原因があるのか、中間経路に問題があるのかはっきりしないことがある。サーバに対してだけでなく、サーバのいるセグメントのデフォルトゲートウェイ (HSRP/VRRP VIP) や中間の主要な箇所(障害試験で切り替えや何らかの状態変更がある箇所)に対しても ping 打っておくのが良い。

あと実務上地味に面倒なのがこの辺

  • 文字コード
    • ずれると面倒なので LANG=C してください…
  • 端末幅・ページング
    • Ciscoなら "terminal length 0", "terminal width 0"
  • リモートログイン時のログ表示設定
    • Ciscoなら "terminal monitor"
  • Console Timeout
    • 試験中は切っておくのが楽。後でちゃんと戻すことを忘れなければだけど。

あと、設定変更を伴う作業手順を書いたら、その変更した設定を元に戻すところまで忘れずに手順化しておくこと。たとえば debug コマンドを設定した場合、放置すると機器に負荷をかけっぱなし、みたいなことがあり得る。

観測箇所の集中

  • 試験の際は複数の機材が・同時に・どう動いているか、を確認しなければいけない。試験用の機材は極力リモートで扱えるようにする。そんでもって操作や各機器の状況は極力1カ所で集中管理できるようにする。そのためにも機材がリモートで使用できることが重要。
  • 場合によっては機器LEDとか確認しないといけないケースもあるけどね。逆にLEDを見ていて問題に気づくケースというのもある (たとえば、STPが悪さしていて予期しないポートがブロックになっているとか)。試験の前後・あるいは試験中に LED 見て回るというのはやっておいて損しない。

時刻同期設定(NTP)

  • 前述したように、複数の機材を複数の人が操作して、トータルとしてシステムがどう動いているのかを確認していく。ばらばらに出てくる大量のログを素に現象(たとえばバグと思われる動作)を洗っていく作業をどのように行うか? これは結局、操作のタイミングや機器の情報を時系列に並び直すしかない。よって、記録に時刻情報を含めること・記録される時刻情報がすべて NTP で同期されたものであること、が非常に重要になる。

ログ取得設定(Syslog)

  • 障害試験においては Syslog や Trap など、どういったイベントがあがるのかを必ず監視しながら行うこと。新規構築の環境の場合、監視要件との突き合わせをすべく監視システム(あるいはその担当者)と連携しながら行うこと。既存環境に対する変更や拡張の場合、不要なアラートが上がらないように注意すること。
  • シリアルコンソールサーバが欲しい!
    • 通信障害模擬でリモート接続が切れるような場合は、シリアルコンソールサーバやKVM機器を使用してアウトバウンドな接続があるのが望ましい。
    • 機材の停止や再起動を伴う際は、起動ログを確認しながら行うべき。起動のタイミングによる環境の状態変化があるので。そのためにも集中して複数のコンソールを見ることができるシリアルコンソールサーバがあると非常に便利。
  • ログレベル設定やデバッグレコマンド設定を各機器で適切に設定しているか? 試験中ログが送信されないケース(サーバへの経路が切断されるような試験)を想定するのであれば、シリアルコンソールで直接確認するか内部バッファ等ローカルへのログ保存を行うことを検討する。
  • 基盤系SEを名乗るのなら tail -f くらい常識だよね!? 頼むぜマジで…
  • 意外と Syslog 受信できていることを確認しないで作業しちゃう人がいるので、あらかじめログ受信確認すること。

作業実施

  • ネットワーク試験の場合、特に動的なもののデバッグは難しい(STPとかOSPFとかああいうやつ)。タイミング重要。複数の機器が連携しながら動くので、操作コンソールを集中したとしても一人ですべてのイベントを見ることはできない。複数人で声を出しながら行う。イベント発生の際声を出しながら何が起こっているのかを確認すること。声出せ声。

*1:考えなくてもできることと言うポリシに従うと。修正が面倒というのはあるけど、いちいちスクロールバックしてコマンド打ったり変に覚えて手順実行する方が危険と考える。