新米エンジニア(アプリ・インフラエンジニア問わず)に知っておいてほしいトラブルシューティング入門 はじめの一歩編

実践編はこちらです。
>* [新米エンジニア(アプリ・インフラエンジニア問わず)に知っておいてほしいトラブルシューティング入門 実践編](http://qiita.com/keigodasu/items/1aeb32310e3feac231fa)

6/24追記：本記事中にも記載した操作ログの取得方法について、入門記事を作成しました。
>* [Linuxサーバでカジュアルに作業ログを取得する](http://qiita.com/keigodasu/items/3eebbc079274ad8dd2c2)

はじめに
-------

今の時期、多くの企業では新卒入社向けの新人研修真っ最中であるところが多いかと思います。
弊社も新人研修の真っただ中でして、私も新人向けに主にインフラ周りの講義や研修サポートを実施しています。
その中で最も質問の多い内容が　
>* 「～に接続できないのですが、、」
* 「○○を見ながら設定したのですが起動しません、、」　　
* 「自分のノートPCだと動いていたのですがサーバ上だと動かなくて、、、」

といった**「○○できないのですが、どうしたらよいでしょうか」**といったものでした。

入社当初は自分もこんな感じだったなーと思いながらも、質問を受ける側としてはなかなか骨が折れるものです笑　
「接続できない」という事象ひとつとっても、それがサーバ上で稼働するWebアプリケーションへhttpで接続できないのか、そもそもサーバへすら疎通ができない状態なのかなど、そのレベル感も様々です。
そこで、問題が起きた際の最低限確認しておきたい・実際しておきたいトラブルシューティングについてまとめてみました。　
が、基礎的な内容とはいえ記載量が多くなってしまいそうだったので、以下のように二部構成として記事を分けることしました。

* はじめの一歩編(本エントリ)
* 実践編([新米エンジニア(アプリ・インフラエンジニア問わず)に知っておいてほしいトラブルシューティング入門 実践編](http://qiita.com/keigodasu/items/1aeb32310e3feac231fa))

はじめの一歩編(本エントリ)では、まず実際にトラブルシューティングや確認事項、取り掛かる際に意識・注意しておきたいことについて経験も交えてまとめてみました。
[実践編](http://qiita.com/keigodasu/items/1aeb32310e3feac231fa)では実際に問題にぶつかった際の簡易的な切り分け方法について、コマンド例も交えてまとめます。

本記事の対象と扱う範囲
---------
初めてインフラエンジニアとして働くことになった方々向けです。(考え方についてはインフラエンジニアの方以外にも共通するものなのかなあと思います。)
本記事のゴールが「○○できないですのですが、、」といった事象に対して自ら順を追って基本事項を確認し、効率的に質問ができるようになること(先輩社員の負荷を減らすこと笑)を目的としています。
そのため必ずしも自ら解決できるようになることをゴールとはしていません。
ですので、調査時に使えるツールやコマンドの詳細な紹介、パフォーマンス劣化の原因調査やパケット解析といったより詳細なトラブルシューティングについては触れませんのであらかじめご了承ください。

トラブルシューティング前にやっておきたいこと
------
まずは実際にトラブルシューティングに取り掛かる前に意識しておきたいこと、やっておきたいことについてまとめてみます。

####現在困っている事や状態をハッキリさせる
---
「そんな事言われなくてもわかってるよ」という内容ですが、作業にとりかかる前に整理することをぜひおすすめします。　
新人から質問を受け際にどういった問題が起きているのかを聞いてみると、意外とうまく説明できない方が多いように感じました。
作業している本人は分かっているとは思うのですが、いざそれを言葉で説明しようとするとややちぐはぐになりがちです。
例えばあるコマンドが実行できないという問い合わせを受けた際に、その詳細を聞いてみると以下のような回答がありました。

>「自分たちのサーバへ接続して操作するとコマンドが実行できないのですが、直接サーバを操作するとコマンドが実行できるんですが、なぜでしょうか。」

これだけを聞くと以下のような疑問を抱きます。

* 接続して操作するのと、直接サーバを操作するとは何がどう違うのか
* どこから何を使って(何のプロトコルを使って)接続しているのだろうか
* 実行できる・できないとは何をもって判断しているのだろうか

よくよく話を聞くと、自分のノートPCからSSH接続してコマンド操作するとコマンドがないよと怒られて、サーバに直接モニターをつないでデスクトップから操作するとコマンドが実行できるということだったらしく、案の定環境変数のパス設定が原因でした。

これはちょっと極端な例かもしれませんが、「○○できません」の一言で終わらせるのではなく、このようにまずは現在直面している問題を主語と述語をちゃんと補って説明できるようになることが初めの一歩かと思います。
このような説明ができるようなると、どういった登場人物がいて、それらはどのようにつながっているのかを整理することもできるので、問題の原因調査をどこを対象に着手すればよいのかの指針にもなります。

####実機上で試行錯誤せずに、まずは仮説を持ってみる
------
一言でいえば問題が起きた際に手当たり次第に実機をいじらない方がいいよ、ということです。
例えば、今発生している問題のせいで他の人が作業できなくて困っているといった場面を想像してください。
こういった場合に特に注意してほしいのですが、焦って手当たり次第に実機を操作するあまり、操作ミスなどで今起きている問題よりもさらに大きな問題を引き起こす恐れもあります。

かくいう私も、現場へ出た直後に自分の操作ミスが原因で障害を引き起こしてしまったことがあります。焦った私は急いでサーバに入って、原因を手当たり次第に調査していたところ、誤って正常に動いていたアプリケーションまで停止させてしまったことがあります。(当時は本当にごめんなさい。。。)

焦れば焦るほど人はうっかりミスをしがちです。(振り返るとなんであんな事をしてしまったのだろうという事もしばしば。。。)

ですので、まずはPCの前で一息ついて、現状起きている事象からどういったことが原因として考えられるかを自分なりに推測してみてください。
そしてその仮説を確認するために、どこから調査すればよいのかをちゃんと整理してから、実機での調査へ取り掛かりましょう。

最初のうちは何から考えていいかも分からないよ、といった状態かもしれませんが、今後学習や経験を積むにつれてどういった内容から確認した方がよいかある程度選択肢を持てるようになります。(もちろん必ずその選択肢が正しいということはありません)
いきなり実機を触らず自分の中で仮説を立てるクセを今のうちからつけておくことをぜひおすすめします。

####時系列を整理してみる
------
これもとっても大事な作業です。

例えば「サーバにSSHで接続できません」といった質問について、よくよく事情を聞いてみると、どうやらある時点までは接続できていたのに、ある時を境につながらなくなったとのことでした。

こういった時は、問題が発生した前後の作業について振り返ることはとても大事です。
何か設定変更をしていないかなど、問題発生時までの作業やイベントを時系列で整理してみることをおすすめします。
今回の場合だと、チームメンバの一人がsshdの設定を誤って変更してしまったらしく、それが原因で一部のユーザでSSH接続ができなくなってしまったようでした。

トラブルシューティング中にやっておきたいこと
-----
一息つけたところで、いざトラブルシューティングを始めす。今度はトラブルシューティングに意識してほしいこと、実施してほしいことをまとめてみます。

####操作履歴は追えるようにしておく
-------
後から作業を振り返る際や、質問をする際にぜひ実施しておきたい作業です。
例えばLinuxであればhistoryコマンドでコマンドの実行履歴を残しておけますし、出力結果も含めて取得したい場合はscriptコマンドが便利です。
またはWindows端末からSSHクライアント(Teratermなど)で接続する場合は、SSHクライアントツールの設定でログを出力することもできます。

質問する際にもこういった作業ログがあれば、質問を受ける側も事象を把握しやすくてとても助かります。

#### (参考)Linuxサーバで作業ログを取得する
>* [Linuxサーバでカジュアルに作業ログを取得する](http://qiita.com/keigodasu/items/3eebbc079274ad8dd2c2)

#### (参考)Windwosでよく使われるSSHクライアントツールでのログ設定
>* [Tera Termログ取得－自動でログの取得を開始する設定](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CB4QFjAA&url=http%3A%2F%2Fwww.j-oosk.com%2Fteraterm%2Flogging%2F114%2F&ei=z_mJVc_bKuPVmgWRy4OgDw&usg=AFQjCNGun_sNpSGWaLltFLD2mxKw2ujEqg)
* [ターミナルソフト Poderosa](http://changineer.info/network/ccie_tools/windows_terminal_poderosa)


####失敗しても戻せる状態にしておく
------
いざ実機に対してトラブルシューティングを始めた際に、設定ファイルを変更するような場面もあるかと思います。
これも当たり前なのですが、設定ファイルを編集する際は編集前の状態をバックアップしておきましょう。cpコマンドで別名でファイルを保存しておくだけでも十分です。
たとえ一つのパラメータをいじるだけであっても必ずとるクセをつけておくことをおすすめします。
障害時などで緊張感ある中で作業すると、こういった些細な変更も忘れてしまう可能性があります。
それに、万が一設定を誤ってしまった際にも前の状態へ戻すことができます。

こういった万が一失敗してしまった際の保険があるのとないのでは、作業のしやすさも各段に違ってくるのでぜひ考慮してみてください。(もちろんバックアップをいかにとるかだけでなく、バックアップからいかに戻すのかも一緒に検討する必要があります)

番外編
-------

####(できれば)素振りできる環境をつくっておく
------
何か設定変更が必要になった際に、いきなり実機投入するのもなかなか勇気がいります。
最近だとVagrant+VirtualBoxといったホスト型の仮想化技術や,Dockerなどのコンテナ技術が気軽に使えるようになったので、ぜひこういった技術を使って素振り環境を作っておくことをお勧めします。

Vagrant+VirtualBoxやDockerでの環境構築方法はここでは解説しませんが、最近は情報量も多いため練習がてらぜひチャレンジしてみてください。

####コードでインフラを管理している場合
-----
最近だとChefやAnsible、AWSだとCloudeFormationやOpsWorksのように、インフラの構成管理をコードで実施することも増えてきているかと思います。
こういった場合だと直接実機に入って変更作業を行うこと事態NGとして運用しているケースも多いかと思います。
またサーバ自体もクラウドサービスを利用していたり、Dockerのようなコンテナ技術をインフラとして利用して、よりも気軽にサーバへ変更を加えられるような仕組みで運用しているようなことが多いかと思います。
こうしたインフラ環境であっても、上で書いたような意識しておきたい内容は基本変わらないと考えています。

コードで状態を管理して、作って壊してを気軽にできるようなインフラ環境が整っているとしても、がむしゃらに試行錯誤するのも非効率ですし、どういった変更を行ったのかはGitなどでバージョン管理しておく必要はあります。

クラウドサービスなど自分たち以外の第三者が管理しているような仕組みを使う場合、
特に上の
> 何に対して何をしようとしているのか(したいのか)を明確にする　

を意識することは大事だと思います。
そもそも今どんな事象が起きているのかをちゃんと考えてみると、クラウドサービス側へ問い合わせる必要がある内容かもしれませし、効率的に原因追及を進めるためにも一度立ち止まって考えてみることはとっても大事です。

まとめ
-------
言われてみれば当たり前のことばかりですが、意識できているかどうかで対応の質に差がでてきます。
質問する際もきっと体系だって説明できるようになれるはずです。
次回の実践編では、じゃあどのように問題を切り分けていくのかについてまとめてみようかと思います。