この記事は「ex-KAYAC Advent Calendar 2018」の11日目の記事です(遅れてすみません 🙇)。

カヤックでの私について

ソーシャルゲームのバックエンドエンジニアとして 3 ヵ月、クライアントワークのバックエンドエンジニアとして9 ヵ月の経験を積んだ後、Web のインフラエンジニア(以降、インフラエンジニア)として 4年半従事しました(2018年12月現在、中途採用ページを見るとインフラエンジニアになっていましたが、現在は SRE になっているはずです)。 主にソーシャルゲームの担当で、社内評価システムの実装・運用・保守や Redmine を定期的にアップグレードしたりもしていました。
もともとインフラエンジニア志望だったのですが、私が新卒入社したころはインフラの上で動くアプリケーションのこともわからないといけないということで、まずはバックエンドのエンジニアとして経験を積んでそれからインフラエンジニアになる、というキャリアパスでした。
現在は SRE として新卒入社した人もいますが、新卒研修後に SRE 以外の業務(主にバックエンド)の経験を積むために SRE 以外のチームに配属され数ヵ月間修行してくる、となっていたと思います。

メンテナンス作業手順の書き方

それでは本題です。私はソーシャルゲームが担当だったこともあり、定期的にメンテナンス作業を行っていました。メンテナンス作業を行う際は、作業手順を書いて実施していましたので、これまでの経験から、なぜ書くのか、どのように書くとよいかを記します。また、手順を書くにあたって必要となる作業を記します。

なぜ手順を書くのか

サービスをとめないメンテナンス作業もあると思いますが、メンテナンス作業といえばサービスを停止することが多いのではないかと思います。サービスを停止する理由はいくつか考えられますが、サービスをとめないと安全に作業を行えないなどがあると思います。緊急のメンテナンス以外は事前に停止時間を告知するのが一般的だと思いますが、告知している以上時間内に収めなくてはなりません。時間内に収めるためには、一つ一つの作業をミスと遅延なく行わなくてはならないため、手順を書く必要があるというのが私の考えです。 熟練の作業者であれば手順を書かなくても作業できる可能性はありますが、以下の効果があると思います。

  • 手順を事前に書いてそれをなぞるだけで良いので安心して作業ができる
    • メンテナンス作業は神経を使うので、心配事は少ないほど良い
    • 不測の事態が発生した際も、それの対応に注力できる
  • 事前にレビューすることで作業の抜け漏れを洗い出しやすい
    • 特に、経験の浅い作業者がメンテナンス作業を行う場合に効果が高い

手順の書き方

私は GitHub Issue に書いています。複数人で操作していると同期がうまくいかないこともありますが、チェックボックスにレ点を入れながら作業するとどこまで終わったかがわかりやすくて良いです。

日時、目的、対象を書く

まず、日時と目的を書きます。対象については GitHub Issue を使っていて repo = サービスとなっている場合は自明なため省略しても良いかもしれません。

# 日時

2018年12月14日 10:00 ~ 12:00

# 目的

- DB を MySQL から PostgreSQL に移行する

手順を書く

悪い例と良い例を示しながら手順の書き方を説明します。

%%% 悪い例 %%%

10:05 ~ 10:10

- [] Apache をとめる
- [] Apache が止まっていることを確認する

一見、止まっていることの確認もしているので良さそうに見えます。しかし、停止と確認のためのコマンドが書いてありません。作業は基本的にコピー&ペーストして実行するだけで進めていけるようにしておくと安心です。 また、「Apache をとめる」という書き方では誤解が生じる可能性があります。たとえば、作業者は Ubuntu での作業経験は豊富で、CentOS はまったく触ったことがない、また手順を書いた人と実際に作業する人が違うケースを考えます。そして、メンテナンス対象は CentOS だとします。Ubuntu と CentOS は同じ Apache HTTP Server でも init.d や systemd の service(Unit) 名が違います(CentOS は httpd、Ubuntu は apache2)。この場合、Ubuntu での作業経験しかない作業者は「Apache をとめる」= systemctl stop apache2 だと考えるでしょう。しかし、それでは「Apache をとめる」ことができないですし、メンテナンス作業中に不測の事態が発生したことで動揺してしまいそうです。もちろん、この例はかなり特殊なケースですし、そのサービスでのメンテナンス作業に慣れていれば間違うようなことはないと思いますが、明確になっているのが望ましいでしょう(開発環境も含めて一度も作業したことがない人がメンテナンス作業をすることはまれだと思いますが…)。 必ず手順作成者 = 作業者となる場合は細かいことは気にしなくても問題ないことが多いですが、手順作成者 = 作業者とならない可能性があるのであればあいまいな表現は避けたほうが良いと思います(手順作成者 = 作業者とならない場合はメンテナンスを延期する、という判断をするのも良いでしょう)。

%%% 良い例 %%%

10:05 ~ 10:10

- [] Apache をとめる
    - `systemctl stop httpd`
- [] Apache が止まっていることを確認する
    - 1. `systemctl status httpd`
    - 2. 1 の実行結果が Active: inactive (dead) になっていることを確認する(systemctl status httpd の実行結果を例として貼っておくとよりわかりやすいです)

作業手順に GUI 操作がある場合は、スクリーンショットを貼って手順を書くとわかりやすいと思います。慣れている人が作業する場合にスクリーンショットを貼らない場合でも、確認方法は明示しておくのが良いでしょう。 例の手順の上に時間を書いていますが、この作業がいつまでに終わっていなくてはならない、という基準があると、時間がかかりすぎてしまった場合の対応策が取りやすくなります。たとえば、今まで少しゆっくり目に作業していたけど少し急ぎ目にやろうとか、このままではとても終わりそうにないので切り戻し作業をしよう、などです。

手順を書く上で必要となる作業

手順を書く上でやっておくと安心して作業ができることについてです。

時間の計測

コマンドを実行してすぐに結果が反映されるのであれば、確認も含めて時間が読みやすいと思います。しかし、中には1つの手順に時間がかかるものがあります。そういうものは検証用の環境を用意して実際に実行して時間を計測しましょう。
たとえば、MySQL のバックアップに mysqldump を使おうと考えたら、本番環境の DB のコピーを用意して、実際に mysqldump の実行時間を計測する、などです。

追記: mysqldump の例で注意しないといけないことがありました。たとえば、1日のデータ増加量が 10GB ある環境があったとして、計測した日から10日後にメンテナンスをする場合 100GB 増加している計算になるので、実際のメンテナンス時には時間の乖離が予想されます。必ずしも線形に実行時間が伸びるとは限りませんが、複数回計測しておくことで、データ増加量と実行時間の関係を予測できるのではないかと思います。

切り戻し方法の検証

すべてのメンテナンス作業で必要となるわけではありませんが、場合によっては失敗したときに作業前の状態に戻さなくてはならない場合があります。たとえば、DB の構造を変更したらアプリケーションが正常に動作しなくなったので、DB の構造を元に戻す、といったケースです。 メンテナンス作業中にぶっつけ本番で切り戻し作業を冷静に行うのは難しい人が多いと思います。これは、切り戻し作業を行うことがあまりないこと、時間が読みにくいこと、時間が読みにくいのでメンテナンス作業時間内に切り戻せるか不明瞭なこと、などが理由として挙げられます。そのため、検証用の環境を用意してあらかじめ手順を確認しておくと安心して作業ができます。ただし、メンテナンス作業の度に切り戻し手順を確認している余裕がない場合もありますので、その場合はいつまでに作業が終わらなかったら切り戻す、という時間を決めておくのが良いと思います。

まとめ

メンテナンス作業手順の書き方を記しました。 この記事を書きながらこういうこともやったほうが良さそうだなと思ったことも書いていますので、筆者が実践していないことも書いてあります。 ほかにも思いついたら追記することがあるかもしれません。 かっちりした作業手順書の作り方ではないので、そういった用途では参考にならないかもしれませんが、何かの参考になれば幸いです。

追記

はてブのコメントで、とめる前に動いているか確認しないのか、というコメントをいただきました。たしかに、手順としてはそれが正しいのではないかと思いました。なぜ書かなかったのかは、動いていることは常に監視しているので動いていないという前提で考えていなかったためです。正常に監視できている前提であれば省略しても良いかなと思いますが、そうでなければ書くと良さそうです。