達人が語る、インフラエンジニアの心得

第7回失敗を糧にしよう

今回は息抜きを兼ねて、お待ちかねの(?)失敗やトラブルについてのお話です。

まあインフラエンジニアを長いことやっていれば、誰しも失敗やトラブルには見舞われるものです。まずは、筆者が自身で体験したものや、目撃したことのある失敗やトラブルを挙げてみます。

誤操作アラカルト

ファイル削除

これはまず誰でもやったことはあるのではないでしょうか。

筆者も某ISPのDNSのゾーンファイルをまとめて消してしまったことがあります。そのときはRCS(当時はRCSもよく使われていました)から1週間前の状態まで復旧させて、残りはメールでのゾーン情報変更報告を拾い集めて復旧させました。

また、他にもやってしまったことのあるミスとして、

# rm *~

とするところを

# rm * ~

として、そのディレクトリ以下の全ファイルを消したことがあります。

防止方法として良くあるのは、rmをrm -iのaliasにするというものでしょう。ただ筆者はaliasが嫌いです。それにrm -iだと消すつもりで消すときに面倒でなりません。-fを付ければ面倒じゃないですが、それだといつも-f付けるようになって同じことですね。

もちろん、ファイルを消すのはrmとは限りません。mvで消したことがある人も多いのではないでしょうか。

完全な防止策というのはなかなかないですが、筆者の場合だと特にワイルドカードを使っているときは、最初にrmの部分をlsにしておいてどう展開されるかを出力させて、そのあとhistoryから呼び出してlsをrmに書き換えて実行、という癖はついています。ワイルドカードを展開するのはshellの役割(つまりコマンドに渡されるときは展開が既に終わっている)というのがポイントですね。

あと、以前Twitterで某宮川氏につっこまれたことがありますが、いまだにRCSを使っていたりします。rmやmvだとディレクトリは消えないので、RCSディレクトリ自体は守られるので、いざ消してしまってもco -lで復旧させることができます。

そういえば、消してしまったがEmacsのバッファから復旧させたということもありました。

電源断

これは筆者ではないのですが…。

ラックにはだいたい電源レールというのが付いています。そしてそのレールの最下部に、CVCFからのケーブルが接続されているのが普通です。この最下部を誤って蹴ったり何かをぶつけてしまってケーブルが脱落し、そのラックの電源レールが片側まるまるダウンという事故がありました。しかもその1週間後に同一人物が全く同じラックを同じ目に合わせていましたね…。

データセンター内を走るとあまりロクなことがありません。

間違いシャットダウン

これは筆者ですが…。

# init 6
とやるところを
# init 0

とやってしまい、戻ってこなくなったことが数回あります。ちなみにinit 6は再起動(rebootやshutdown -rとだいたい同じ⁠⁠、init 0は停止(haltやshutdown -hとだいたい同じ)です。今のLinuxだと、だいたいshutdownはinitのwrapperだったりするんではないでしょうか。

昔はhaltやrebootやshutdownよりinitのほうが行儀が良いと言われていたので今でもそうしているのですが、行儀の良さ(ファイルシステムの整合性のチェックやinit.d以下のscriptのstop処理の実施など)が同じであればhaltやrebootのほうが間違いは起こしにくいのかもしれません。とはいえ、init 0やinit 6は間違いなく行儀がいいので、これからもinitで停止や再起動をすると思います。

OSフォーマット

これも筆者ではないのですが、あるラックにマウントされているマシンのOSを全部入れ直すはずが、1本隣のラックに対して行ってしまい、かなりのサーバのデータが失われたということがありました。なんと恐ろしい……。

OSを入れ直す前には必ずhostnameやifconfigを叩いたり、/homeの下を見るなりしないと駄目ですね。これが今まで見たことのある中で一番キツイ失敗だったかもしれません。10台以上のサーバのデータが復旧不可能でしたから。

プロセス落とし

sshdや(最近はないですが)telnetdをkillしてしまって接続できなくなる、という経験がある人もいるのではないでしょうか。ただこの場合は、今つながっているセッションは活きているはずなので、⁠あ、間違えた!」と思っても冷静に対処すれば復旧できると思います。なにげに、sshd.confを書き換えてSIGHUPを送るときはちょっとドキドキしますね。

そういえば余談ですが、最近はもうリモート接続といえばsshのみだと思いますが、15年ほど遡ればtelnetdやin.rlogindが普通に動いていました。データセンターにいるときに、普段あまりデータセンターに来ない人が来たので「どうしたんですか?」と聞いたら「いや間違ってtelnetdを落としてしまって」と言ったので、⁠じゃあrloginしたらいいじゃないですか」と言ったら嫌な顔をされたことがあります。せっかくデータセンターまで来てからそんなことを言うな、って感じだったんですね。

ネットワーク断

たとえばルータ(やL3スイッチ)でルーティングを間違えたり、フィルタの設定を間違えたり、サーバでもiptablesの設定を間違えて、瞬時に何もできなくなるという経験をした人も多いと思います。筆者も一度フィルタの設定を間違えて、あわててデータセンターに駆けつけたことがありました。

ネットワーク機器やiptablesの場合、その瞬間からなにもできなくなるのが辛いところです。お金に余裕があれば、全マシンにKVMスイッチやシリアルコンソールを付けておきたいところですね。もちろんミスをしないのが一番ですが…。

特権モードで緊張感をもつ癖をつけよう

もちろん他にもたくさんのケースがあると思います。ミスに起因するトラブルというのは、だいたいが操作ミス、設定ミス、予防措置をしないミスです。操作ミスについていえば、特権モードで作業をしているときは普段と違うテンションが求められます。

たとえばLinux(とかサーバ系)に関していえば、sudoという便利で素晴らしいものができてだいぶマシになったところはありますが、それでも一度rootになると、そのまま作業するという人も結構いるんではないでしょうか。sudoしているとき、もしくはrootプロンプトになっているときは、指先に普段とは違う緊張感が求められます。これは訓練で身に付く癖なので、ぜひそうなるようにしてください。もちろん、特権モードでいるのが最小限であることに越したことはありません。サーバ管理について言えば、rootでいるかそうでないかだけで、ミスの影響範囲に相当違いがあります。

もちろんこれはサーバに限った話ではなくて、ルータやスイッチでも同じことです。CiscoのIOSでenableしているのはなるべく最小限にとどめ、enableでいる間は緊張感を持ちましょう。

そういう意味では、プロンプトというのは非常に重要です。多くの環境で、特権モードでいる間というのは「#」で終わるプロンプトがよく使われます。これは、プロンプトの最後が「#」だったら緊張感を持て、というパブロフの犬のような条件反射を身につければ、だいたいどんな環境でもそれが活かせるということになります。 逆に言うと、rootやenableの際のプロンプト(の最後)「#」以外にするのは絶対やめたほうがいいでしょう。

予防措置を取ろう

また、操作ミスではなく設定のミスでトラブルを招くのもよくある話です。

つい最近、あるサイトに接続したら全く別のサイトの内容が見えていた、という話がちょっとTwitterで広がっていましたが、これなんかは(おそらく)Apacheのhttpd-vhosts.confの書き間違いか、そもそもhttpd-vhosts.confをIncludeし忘れたかとかでしょう。前述したように、sshd.confの設定を間違えたり、iptablesの設定を間違えたときなどは、そもそもリモートから復旧できなくなってしまうので悲惨です。

設定ファイルはだいたいrootで編集する、もしくはそのサービス用のアカウントで編集するものなので、いずれにしても普段の自分のアカウントでない時には緊張感を持つことが必要です。もちろん、特権モードや自分以外の(サービス用などの)アカウントでいる間だけ気をつければいいという話ではなくて、自分のアカウントで作業しているときもそれは同じなのですが。

# cat id_rsa.pub >> ~/.ssh/authorized_keys2

とするかわりに

# cat id_rsa.pub > ~/.ssh/authorized_keys2

とするだけで悲しい思いをすることもあるでしょう。

そういう意味では、LinuxとかUNIX系は実に多くのファイルを消す手段がありますね。rmはもちろんですが、mvやcp、リダイレクト(>file⁠⁠、tarで消してしまうこともあります。

設定ミスの場合には、操作ミスとは違って一発で即座にトラブルになるというよりは、設定してそれを反映して初めてトラブルになるケースのほうが多いので、操作ミスの場合には「やっちまった!」という感じがほとんどですが、設定ミスは「あー、やっぱりこうなるか」というケースもままあるような気がします。

操作ミスにしても設定ミスにしても、予防措置があるかどうかによって、その影響範囲がかなり変わってきます。この予防措置には「そもそもトラブルが起きないようにする予防措置」「トラブルが起きても復旧できるようにしておく予防措置」があります。

わかりやすいところで言えば、冗長化しておく、バックアップを取っておくなどが超定番ではありますが、それ以外でも前述したように、シリアルコンソールをつないで接続できるようにしておく、権限委譲を適切に行って不要に強い権限を与えないようにしておく、ワークフローで確認作業を必ず入れるようにしておく、作業時には二人同時に確認するようにする、なども効果的です。場合によっては、ファイルシステムをread-onlyでmountしておくなども効果的でしょう。

もちろん、こういったシステム構成としての予防措置も重要ですが、エンジニア一人一人が自分でできる予防措置というのもとても重要です。たとえば先ほどのようなRCSを使うとか、人によってはプロンプトの最後を「###」と重ねてより一層の視覚的注意を喚起してみたりとか、再起動する前にはps auwwxの出力を保存しておくとか、いろいろ考えられると思います。

また、こういう予防措置をしておこうという気持ちが、そもそもミスの発生を抑えたりもします。rootでいるときにミスるとダメージが大きそうなコマンドをたたく際、リターンキーを叩く前に一瞬止まる人もいると思いますが、そういう人のほうがそもそもミスをしないものです。余談ですが、そういう人のほうがリターンキーを強く叩く気がします。

今回は息抜きということで、ミスとトラブルについて書いてみました。

次回ももう1回息抜きで、筆者の修羅場の経験について書いてみたいと思います。

おすすめ記事

記事・ニュース一覧