every Tech Blog

株式会社エブリーのTech Blogです。

はじめてのシステムメンテナンスをする君へ

はじめてのシステムメンテナンスをする君へ

はじめに

主にインフラ周りや時折バックエンドでGoを書いているyoshikenです。

この記事はevery Tech Blog Advent Calendar 2023の2日目の記事となります。
昨日の記事は「Next.js + Go + AWS API Gateway で WebSocket API を使って API サーバーからフロントエンドに通知を送る」となります。

tech.every.tv

tech.every.tv

対象読者層

  • インフラレイヤー(バックエンドも含)の知識/経験が少ないエンジニア
  • エンジニアがどういう手順でメンテナンスをするのか知りたいPdM/PjM/PM

本記事の目的

システムメンテナンスについて

  • どのような流れで行うことがあるのか例を示す
  • 気をつけるべき事柄を示す
  • ドキュメンテーションに必要な項目の例を示す

以上を持って、初めてメンテナンスを行うエンジニアが1例を参考にメンテナンスに関するノウハウを得て、0ベースではなく1べースでメンテナンスの"準備"を行えるようにすることを目的とします。

本記事の対象外

  • システムメンテナンスの具体的な手順やコマンド
  • 使用ツールの説明や使い方

準備の準備

DBのストレージ増設、サーバーOSのアップデート、キャッシュ増設など、システムメンテンスと一概に言っても、その目的や範囲は様々です。
そのため、予めその目的を明確にしておくことで、影響範囲の把握や停止時間の正当性などが明確になります。

また、メンテナンスを一つのプロジェクトとして責任者を立てましょう。
ここでいう責任者は"メンテナンスについて網羅的に把握し、進捗の管理や渉外に立つ人"という意味です。
実際にメンテナンスを行うオペレーターは一人かもしれませんが、事前準備では複数人が関わるため責任の所在が曖昧になることもあります。特に大規模であればあるほど、関わる人間が多く、全体を把握するには複数の人にヒアリングをしないとわからないということが起こりやすいので注意が必要です。

目的・影響範囲・責任者が決まったら、メンテナンスを実施する旨を関係各所へ連絡しましょう。
サービス/アプリケーションに影響があるメンテナンスの場合は、この時点でのおおよその目安で良いので影響する範囲と時間を関係部署に伝えておきましょう。

例. 20xx/xx/xx ~ 20xx/yy/yyの間で 大体3時間前後。 Android/iOS 両OSのモバイルアプリケーションがメンテナンス状態で使用不可になる。ただしwebはアクセス可能。

そうすることで、厳密な日時は決まらなくても影響範囲からメンテナンス実施可能な日時の割り出し、エンジニアが想定する影響範囲から"関係部署としての影響範囲"(連絡する企業やユーザーへ通知手順)などを割り出すことができます。
後述する手順書の作成中に精度がある程度しぼれた影響時間が算出できたら、再度関係部署に連絡し、具体日時を確定させましょう。
こういった"準備の準備"は直接的なメンテナンスの成功に貢献する割合は少ないですが、円滑なメンテンスの実施やその後のメンテナンスを行う際の他部署との連携には大きく貢献するので、メンテナンスの前には必ず行いましょう。

メンテナンス手順書

具体的な準備に取り掛かって行きましょう。
兎にも角にもメンテナンス手順書を作成します。
といってもいきなりはかけないと思いますので目安として以下の項目を書き出していきましょう。

  • 目的と範囲
  • 対象のシステムの構成(図)
  • 手順に必要なツール一覧/インストール方法
  • 実施手順
  • ロールバック手順
  • メンテナンスの後に必要な作業
  • トラブルシューティング
  • 参考資料

それぞれの項目ごとに上から"ロールバック手順"まで、どのような情報があると望ましいか触れていきます

目的と範囲

前章でも触れましたが、メンテナンスの目的と範囲を明確にすることで、メンテナンスの成功基準(ゴール)や影響範囲を明確にすることができます。
この部分が明確ではないと、この後に書いていく情報や手順が正しいのかどうなのかが不明瞭になります。

例えば、「データベースをアップデートする」という情報では "なんのデータベースが" "どのバージョンまで" が不明瞭なので、「(データベース名)をv1.2.3からv4.5.6にアップデートする」というのが目的としては好ましいです。
また、メンテナンスの範囲も明確にしておきましょう。

とはいえ、いきなり最初から範囲がわかるわけでもないので、後述するシステムの構成図などを書きながら範囲を絞っていきましょう。
ではなぜ最初の節に紹介したかというと、 "ドキュメンテーションとして多くの人が必要とする情報ほど前に書く" というのはドキュメンテーションの基本中の基本です。これはメンテナンスに限った話ではないです。
今回の場合は多くの人は手順そのものではなく影響する範囲が、関係するエンジニアや後世にドキュメンテーションを読むであろうエンジニアが一番に見たいのはメンテナンスの前後の状態と予想されるので一番最初の節にに記載しています。

対象のシステムの構成(図)

システムの構成(図)を書く目的・必要性ですが、よほど簡素で単純なシステムでない限りインフラレイヤーはごちゃごちゃしています。

「AWSのEC2でサービス立ててます!」といっても、subnetやsecurity group・route table・AZなどなど、実際はさらにRDSやELB、Route53など複雑に絡み合っています。

またインフラレイヤーに限らずアプリケーションレイヤーでも、昨今のマイクロサービス化やモノリシックなアプリケーションでも、複数のサービスが絡み合っていることが多く、暗黙知であったりロストテクノロジーとなっていることが多いです。 そういった状況でレビューをしたりリストアップをすると漏れが生じてしまうので、漏れの可能性を最小限にするためシステムの構成(図)を書くことが望ましいです。

システム構成(図)と表現しているのは、"可能であれば図で表現するのは望ましいが、それに時間をあまりにも割くのが難しいのであれば他でも代用可能"という意味合いで記述しています。
大事なのはメンテンスの対象と関係あるネットワークや通信がどのように絡み合っているかを把握することです。

手順に必要なツール一覧/インストール方法

「メンテナンス手順に含まれているライブラリやコマンドがインストールされていなかったので当日慌ててインストールした」というのはあるあるなお笑い話なんですが、そういったイレギュラーはない事に越したことはないので事前に手を打っておきましょう。

インストールする際は極力バージョンによる挙動の違いをなくすためにバージョンは指定したインストール方法を記載しましょう。

実施手順

ここが一番のボリュームかつ大事な部分になると思います。

手順についてはオペレーティングする人が当日やりやすいを前提に、レビューする人が見やすい形も意識しましょう。

一例として以下のフォーマットを参考にしてみてください


  1. 具体作業をわかりやすく一言で

事前確認

作業を行う前にステータスを確認できるCLIコマンドと結果

[ ] 目視の場合はチェック欄があると尚良し

作業

実際の作業を行うCLIコマンド

[ ] GUIをポチポチする場合はチェック欄が(ry

事後確認

作業を行ったあとのステータスを(ry

[ ] 目視の場合はチェック(ry


具体的な例を出すと、


  1. route53のprivate hosted zoneのレコードを新しいエンドポイントに切り替え

事前確認

dig hoge.local

作業

cloudmapに登録されているインスタンスのCNAME設定を6の手順で作った新クラスターのエンドポイントに変更
https://github.com/org/repo/blob/master/path/to/terraform/service-discovery.tf

git checkout feat/update_nanntara__uwaaaa

cd path/to/terraform

// 差分確認
terraform plan

// 反映
terraform apply

事後確認

// login to bastion
ssh user@humidaihost -i ~/.ssh/koukaikagi.pem
// 向き先確認(手順6のエンドポイントを参照
dig hoge.local
// ログイン
redis-cli -h hoge.local -c
// バージョン確認
> INFO

[ ] コンソール上のroute53で向き先が変わっている

[ ] privateDNSが新しいエンドポイントの向き先に変わっている


このようになります。

これらを作業工程ごとに記載します。
非常にボリューミーになるので必要な情報を簡潔に記載しましょう。

ロールバック手順

「いちばん大事なのは手順だ」と一個前の節で書いたかもしれませんが、この節が一番大事かもしれません。

メンテナンスには失敗がつきものです。こんだけ偉そうに書いてますが打率は7・8割です。
ですが、取り返しの付かない失敗は…まだ片手で数えられるぐらいしかしていません。たぶん。

その失敗に備えるためにいかなる状況でもメンテナンス前に戻せるような手順をいくつか事前にリストアップしておくことが非常に大事です。
ロールバックを行うということは、何かしら失敗をしてしまった後です。精神的に不安定になり、簡単な作業もオペレーションミスしてしまう可能性がぐっと上昇します。ですので粒度は細かく、コマンドをコピペして終わるぐらい詳細に書きましょう。

どうしても都合上非可逆的な作業でロールバックが不可能な場合は"上位の判断者が判断を下し、復旧作業が開始されるまで被害が最小限に済む方法"を記載しておくのが良いです。例えば破壊的変更を含むバッチの停止やデータ書き込みの停止などです。

手順を開発環境で試そう

手順書を作成してく上でわからないことや実際にどういった反応が返ってくるかわからない場合も多々あると思います。そういったときはぜひ開発環境で試してみましょう。

上記以外にも本番環境と限りなく近い状態の環境を用意し手順を再現することで当日にかかる時間の見積もりの精度も向上します

手順書のレビュー

手順が一通り出来上がったら知見がありそうな人にレビューをもらいましょう。

コードレビューと一緒で何回か往復をしてブラッシュアップしていきましょう。

まとめ

メンテナンスの手順書を作っていくことで自ずとメンテナンスに必要な準備ができてくると思います。

メンテナンスは事前に共有し、ドキュメンテーションもしっかり書けば、当日はあとは手順書を見ながらコマンドを打つだけです。
よく「メンテナンスやったことないから怖い」という話も聞きますが、それは不明瞭なものに対して抱く恐怖心であり、"メンテナンス"にたいしてではありません。手順書をしっかり書き、リハーサルを重ねることで恐怖心が和らいでいきます。正しく恐れていきましょう。

ここまで書いてあれですが、当日はきっと手順書に書いてない想定外のトラブルが起こることが多々あるでしょう。
そういった場合に備えて日常で発生するシステムのアラートに対して積極的に対応して行きましょう。そういった場で得た経験はきっとメンテンス中のトラブル対応として生きていきます。

それでは皆さんよきメンテナンスライフを!