kariaの日記 @ Alice::Diary

ノリツッコミの鳩子がはてなブログ書いちゃうよ

メンテナンス作業の手順書をつくるときの考え方

最近システムメンテナンスの手順書の作り方的な記事をちょこちょこ見かけるなーと思って、以前書きかけのものがあったので、ちょっと便乗してみようかなと。

papix.hatenablog.com

blog.tkuchiki.net

といっても自分流の「作り方」を書き出すと途方も無い長文記事になってしまうので、メンテナンス作業をやっていくぞ!手順書作るぞ!となったときに根底にある考え方を書き出してみます。

監視の通知を止めるか止めないか

大抵の商用のシステムには何らかの形で監視が入っているかと思います。メンテナンス作業の間はサービスが通常と異なる状態となるため(例えば通常はHTTPステータスコード200が返ってくるところ503が返ってくるとかね)、大抵はアラートが発生します。作業してもアラートなんて出ないよという場合は、その監視は見直した方が良いかと思います。

作業影響アラートをどう扱うかには2つの選択肢があります。

  • 抑止する:あらかじめアラートが出ない(もしくはアラートを検知しても通知しない)ように抑止しておく
  • 無視する:メンテナンスの間はアラートが出てもスルーする

どちらを採用するかはケースバイケース、システムや組織やアラート対応の枠組み*1により異なりますが、基本的には抑止する方向に倒すのではないかと思います。

わかりやすくMackerelを例に取って挙げると「ミュート」という機能がありますね。ミュートをONにしておけば、Mackerel上ではアラート発生扱いにはなるものの、Slackやメールなどの通知はされません。また、PagerDutyやTwillioもしくは人力でアラートが電話通知される枠組みになっている場合、メンテナンス期間中のアラートを抑止しておかないと業務に支障が出るレベルで電話が鳴ってしまう恐れもあります。

ただ、アラート抑止で最も恐ろしいのは「抑止の解除をし忘れる」ことです。メンテナンスが終わったあとに抑止の解除をし忘れると、本当に障害が発生したとき必要な通知が来なくなってしまいます。こんなに恐ろしいことはありませんね。ええ、恐ろしい……。

解除漏れを防ぐために考えられる方法は以下の3つ。一つ一つ見ていきましょう。

アラートの抑止をしない(静観する)

「そもそも抑止をしなければいいんだ!」という考え方。アラートの通知がメールやSlackで流れてくるだけなのであれば、メンテナンス期間中のアラートは無視すればよい、というのも一つの考え方でしょう。

これを「静観」という言い方をします。人力での監視が絡む場合は「●●時からメンテナンスのため、アラートの静観をお願いします」という依頼を出すこともあります。

抑止を時間指定にする

メンテナンス作業は通常は予定時間が決まっていますから、監視の抑止をする際にあらかじめ「●●時から××時まで抑止する」「今から90分間は抑止する」という時限設定を入れておけばアラート抑止の解除漏れがなくなります。Mackerelにも時間指定ミュート機能ありますよね(今年2月に実装されて超助かってます)。

mackerel.io

人間忘れっぽい生き物ですから、監視システムにできることは監視システムにやってもらいましょう。

手順書を上下対称で書く

どうしてもアラート通知を抑止したいけど、Mackerelは使ってないし時間指定ミュートを入れることは出来ない、でもメンテナンスはもう明日……そんなとき、初めて手順書の書き方が肝になってきます。

手順書を書く時は「上下対称になっているかどうか」を意識しながら書きます。上下対称とは?と思われるかと思いますが、例えば

  • 「メンテナンスモードにする」という手順があるなら、終了時に「メンテナンスモードを解除する」という手順が必要
  • 「監視を抑止する」という手順があるなら、終了時に「抑止を解除する」という手順が必要

といった風に上下対称にすることを意識して書くと、手順書の漏れを少なくすることが出来ます。

これって、監視の話に限らず手順書に書かれるであろう作業全てに言えることだと思うんです。たとえば、データベースのダンプを取るのであればリストアできるかどうかを考える*2ロードバランサーから切り離すのであれば、元通りに組み込めるのかどうかを考える。対称にならない作業って無いはずなんですよね。対称に作業するかどうかは別として、対称に出来る作業なのかどうかを考えるのが、漏れや事故を無くす一つのコツなのではないかと思います。

予定時間と実績時間を書く

個人的にはあんまりGitHub Issueに手順書作るのって馴染みなくて、スプレッドシートに書くことが多いです。何故かというと、作業項目ごとに時間を入れる欄が欲しいんですよね。それも「開始」「終了」と「予定」「実績」で合わせて4つ。

何故かというと、現在の進捗が知りたいわけです。オンスケで進んでるのかどうかが知りたい。たとえば、

開始時刻(予定) 終了時刻(予定) 開始時刻(実績) 終了時刻(実績)
00:00 00:30 00:00 00:20
00:30 01:00 00:20

となっていたら、30分で見積もっていた作業が20分で終わったことがわかります。素晴らしいですね。

開始時刻(予定) 終了時刻(予定) 開始時刻(実績) 終了時刻(実績)
00:00 00:30 00:00 00:50
00:30 01:00 00:50

となっていたら、20分遅れで進んでいることがわかります。何があったんでしょうね。

このように、実績を入れる欄を作ることで単純に作業の進み具合がわかるわけです。予定よりも早く進む分には、後半の作業のバッファが生まれるし、メンテナンスを予定より早く終わらせられるかもしれない。予定より遅れているなら、後半のバッファで吸収できるのかどうか、作業を中止するかどうかも検討しなくてはらない。時間を意識せずにメンテナンス作業を進めること無いですよね?ってことです。

実績を書くことによるもう一つの利点は、次回の作業に活用できることです。次回また同じ作業をするかどうかわからない時こそ実績を書いておくのは大事で、実際のところ同じメンテナンス作業をするのは数ヶ月単位だったり年単位だったりすることはあるわけです。繰り返しますが人間は忘れっぽい生き物なので、数ヶ月前のことなんて覚えてません。そんなときに、過去の作業で記録しておいた実績値を見れば「この作業だったら●●時間程度で終わる」とパッと分かるわけです。

でも別にスプレッドシートにコダワリがあるわけではないのでMarkdownでその辺うまく表現できるならそれでもいいかなー。

本当にこのメンテナンス必要?

ここまで長ったらしく書いてきましたが、全部ひっくり返す事を言うと「メンテナンスによるサービス停止なんて無い方がいい」に決まってるわけです。皆さんも、一般の利用者として使っているサービスがメンテナンスしているところに遭遇したら困りますよね。なので、手順書を作りながらも「本当にこの作業必要?」「もっと停止時間短くできない?」という自分との対話が続くことになります。

たとえば2つの作業を同時に進めることで、合計3時間かかる作業が1.5時間になるとか、単純に並列化するだけで時間を短縮できませんか?「プロセスを停止する」という作業のところにkillコマンドそのものを載せておけば、文字通り秒殺できるのではないですか?メンテナンスモードに入る前に済ませておける作業はありませんか?いろんな時間短縮の工夫を考えましょう。

もっとも、その短縮の工夫が裏目に出てしまうことがないとも限りません。確実に予定したメンテナンス枠内で終わらせられるように工夫した方が、何度もメンテナンスをやり直さずに済む結果につながるケースもあるでしょうね。

結局長くなってしまった。とりとめもなくおしまい。

入門 監視 ―モダンなモニタリングのためのデザインパターン

入門 監視 ―モダンなモニタリングのためのデザインパターン

*1:例えばアラート毎に自動でチケットが起票されるような場合は、アラートが大量に出るとチケットも大量に作られて業務に支障が出るので、作業影響アラートが大量チケット起票につながらないようにうまく調整する必要がありますよね。

*2:単にバックアップとしてダンプを取る場合、その作業内ではそのダンプをリストアする事は無いかもしれません。でも、バックアップということは万一の事態が起きたらリストアしますよね、作業する前にちゃんとそのやり方抑えてますか?というお話です。