継続的Webサービス改善ガイド

第4章インフラ構成管理の改善~実サービスでの歴史から学ぶ、段階的な負債返済

インフラにおける改善の実際

本章では実在するサービスを題材に、インフラの改善で取り組んできたことを紹介します。

ヘテムル

執筆陣が関わっているpaperboy&co.(以下、ペパボ)のサービスはヘテムルです。ロリポップ! と並ぶレンタルサーバのラインナップで、大容量・高負荷に耐えうる上位のサービスとして提供しています。2005年リリース当初はサーバ数十台でしたが、それから規模や機能も増え、2013年5月現在は400台弱の規模にまで成長しました。執筆陣は4年前の2009年からヘテムルに携わっており、運用と機能改善を行っています。

インフラの技術的負債

インフラの技術的負債には次のものがあります。

  • a.集中管理されていない設定情報によるサーバごとでの微妙な仕様差
  • b.すばやい変更手段を持たないことによるサーバ全台展開の手間
  • c.移り変わるハードウェア性能とそれを扱う運用の柔軟さがないことによるスペックアップの困難さ
  • d.ルーチン化された作業が省力化されていないことによる運用のコスト
  • e.無秩序な監視システム運用によるサービスヘルスチェック品質の劣化

これらはインフラに必ず付随する問題です。小規模のサービスでは大きな問題とはならなくとも、成長につれて大きく顕在化するリスクでもあります。

負債の返済

前述の問題は対処を怠ると、時を経るごとに新たなリスクが積み重なっていきます。問題を分割し、リスクが高い事柄から、さらなる負債を積み重ねないように対策していくことが大切です。

ヘテムルでも、これらの問題を解決していくことが運用改善の歴史でもありました。具体的には次の改善を行ってきています。

  • a.提供しているサービスはすべてをバージョン管理下において管理する
  • b.デプロイやサーバに対する変更ツールを整備し、属人化や煩雑さを排除する
  • c.ベンチマークの指針と計測する手段を持ち、OSセットアップを省力化する
  • d.システム構成管理ツールを用いてサーバ構築の省力化・仕様化を行う
  • e.監視システム設定のレビューを行い、設定の一部は自動生成する

以降で時系列に沿って、それぞれどういう意図に基づきどのような施策を行ってきたかを紹介します。

すべてをバージョン管理下に

何をバージョン管理するのか

ソフトウェアと同様にインフラ(プラットフォームと言ったほうがよいかもしれません)のバージョン管理も、サービスの品質と運用精度向上には欠かせないものです。では、具体的に何をバージョン管理すればよいのでしょうか? 一口で言ってしまえば「すべて」です。プラットフォームを構成するミドルウェアやその設定、スクリプトなどはそれぞれが複雑に依存し協調し合うことで、あるべき機能を提供するよう動作しています。そのため、そのどれもが欠けることなく、任意のバージョン下で整合性がとられていることが理想です。

優先度

とはいえ、すべてをバージョン管理下に置くというのは一朝一夕にできることではありません。すでに長年動いているシステムでは、1つのファイルをバージョン管理システムにコミットするのにもそれなりの手間と時間がかかるものです。そのため、ある程度優先度を設けて、順にコミットせざるを得ません。

ヘテムルではおおよそ次の順番で行いました。

  • ① OSレイヤ、セキュリティ周り
  • ② ミドルウェア設定
  • ③ cron、運用スクリプト
  • ④ 監視ソフトウェア設定

③④は、その内容によっては、ほかと同時に進めることもありましたが、①②はこの順番で行う必要がありました。より下のレイヤから仕様をfixしないことには、その上で動くものの適切な設定を考えることはできません。

セキュリティ周りについてはどうでしょうか。iptablesやhosts.{allow,deny}の設定などは、ものによってはミドルウェア側でも同様のポリシーを設定できます。しかし、先により影響範囲の広いOSレベルで、どのレベルまでセキュリティポリシーやアクセス制限を担保するのかを決めてしまったほうが、ミドルウェアのセキュアな設定を決定することが容易になります。また、意味の重複が避けられるため、そのあとのメンテナンス性も高くなります。

オペレーションツールの見直し

バージョン管理システムで厳密な管理をする以前にも、⁠構築手順書」という名の秘伝のタレや、更新日付サフィックスを付けた設定ファイルの固まりなどでゆるいバージョン管理は行われていました。しかし構築時の職人による暗黙手順や、々の運用でのアドホックな対応の繰り返しなどによって、サーバ間で設定の差異が生じていました。そのため、まずはその差異を把握し、既存環境に悪影響を与えない形で改めて内容をfixする必要がありました。

sshループ期

100台を超すサーバ群にコマンドを一括して実行するために当初採られていた方法は、シェルのワンライナーでのssh forループでした。ファイルを配布する場合はsshをscpに変えます。

for host in web{1..100}.heteml.lan;   do echo $host; ssh $host 'cat /path/to/config'; done

古典的な方法であり、プログラミングスキルに乏しいインフラ系エンジニアでも、この程度は書けます。しかし、毎回これをタイプするのは骨が折れますし、与えたホストリストに対して1つずつシーケンシャルに実行するため、時間もかかり過ぎます。再利用性が低いのも難点でした。

Archer期

ベタのワンライナーには早々に見切りをつけ、最初に導入したツールはArcherでした。ArcherはPerl製のプラガブルなデプロイツールです。YAMLYAML Ain't Markup Languageで定義された設定に基づき、単純なシェルコマンドから複雑なデプロイ処理までをコマンドラインからお手軽に並列実行できます。

似た機能を持つツールにRuby製のCapistranoをはじめほかにもいくつかありましたが、Archerを採用した理由としては、すでに社内で多くの利用実績があったことと、筆者(黒田)自身もPerlが好きで、実装の隅々まで理解可能であり、プラグインの開発にも抵抗がなかったためです。

Archerは対象ホストを設定ファイルに静的に記述する仕様だったため、RoleLoaderという小さなプラグインを開発し、バージョン管理された次のような外部ファイル(以後、roles.yamlと表記)に定義したロールとそれに属するホストのリストを実行時に読み込めるようにしました。

---

web:
  - web1.heteml.lan
  - web2.heteml.lan
mail:
  - mail1.hetmel.lan
  - mail2.heteml.lan
  - mail3.hetmel.lan

これによって、処理内容と処理対象を別々に管理できるようになり、さらに利便性が向上しました。

Archerの限界

Archerの導入によって定形作業の効率は大幅に改善され、設定内容のレビューをチームで行うことで、作業内容の管理品質も向上させることができました。しかしArcherを使った運用でも、次のような不満がすぐに生まれてきました。

  • 大量の対象ホストでの実行出力や結果の確認がしにくい
  • 処理内容は基本的に設定ファイルに依存するため、細かな動的作業には向いていない

これらはArcherの機能に不足があったわけではなく、そもそも用途に合っていなかったと言えます。Archerはアプリケーションをデプロイをするために使うものであり、サーバの細かな設定ファイルの配布や内容の確認に使うことは想定されていません。使っていて不満が出るのは当たり前だったのです。

自作ツールheteloy期

より用途に合ったツールを求め、今度は一からツールを自作することにしました。既存ツールの使いこなしで頑張るよりは、実行環境と用途に特化したものを自分たちで作ってしまったほうが、長い目で見れば得策であろうと判断したためです。そしてその思惑は当たり、現在でも日々の運用に欠かせないものとして利用されています。自作ツールは「へテムル」「デプロイ」からheteloyと名付けました。

heteloyは環境依存を許容し汎用性を捨てたため、コンパクトな実装になっています。そのため、仕様変更や機能拡張が容易で、構成管理と運用の変化に対してすばやく対応できました。また、後述するPuppetと親和性の高い作りにしたため、バージョン管理を進めながらシステム構成管理ツールを導入していく取り組みを加速させることもできました。

heteloyの仕様と特徴は次のとおりです。

  • 対象ホストはArcherのRoleLoaderプラグインで使っていたroles.yamlからロード可能
  • 実行するコマンドや対象ロールの指定などはコマンドラインオプションで指定
  • 配布したいファイルを絶対パスで指定すると、対象ロール名と合わせて、自動的にPuppet管理下にある該当ロール向けファイルパスとマッピング
  • 結果は色付きで出力し、実行ユーザ、ホストごとにログファイルにも保存
  • オプションで指定した内容はダンプ可能で、再利用が可能
  • 実際に実行される前に、対象ホストと処理内容、確認のためのプロンプトを表示

heteloyの実行例は次のようになります。

$ sudo heteloy --role web \
    --dist /etc/httpd/httpd.conf \
    --mode 644 \
    --exec 'service httpd configtest' \
    --exec 'service httpd condrestart'

これで、ローカルの/var/lib/puppet/data/modules/web/files/etc/httpd/httpd.confがwebロールに属するホスト群に対してパーミッション644で並列配布されます。また、配布に成功した場合のみ、続けてconfigtestが実行され、それも成功したらhttpdの再起動が実行されます。もしconfigtestが失敗してしまった場合は、自動的に作成されたバックアップファイルを使い、迅速にロールバック処理を行うことができます。

また、このような作業は頻繁に発生するため、次のようにして設定をチームで再利用します。

// オプション内容を保存し
$ sudo heteloy ... --configdump > httpd.yaml
// 設定が変わったら保存していた内容をロードして再実行
$ sudo heteloy --configload httpd.yaml

こういったオーケストレーション[1]と言われる処理は、本来は後述するPuppetなどのシステム構成管理ツールで一括管理するのが理想です。しかし、それらのツールにはまだまだスケーラビリティや速度の面で不足感もあります。そのため、日々の運用の中で行う粒度は小さいがスピードを求められる作業については、このような別のツールで補うという柔軟な姿勢が必要と考えます。

新サーバの導入とOSセットアップの自動化

ハードウェア入れ替えの必要性

昨今、個人が扱うデータは画像や動画、そのほかのファイルフォーマットもリッチになり容量も増え続けており、レンタルサーバサービスに対する容量の要件も上がっていきます。ヘテムルは当初2GBで「大容量」とうたいリリースされましたが、そのあと段階的に、

  • ① 10GB
  • ② 42.196GB(マラソン距離のようなタフさ)
  • ③ 118.6GB(いいハム、ちょっとおいしいし覚えやすい)
  • ④ 150GB

と容量アップを図っています。

ここでは容量を例としましたが、CPUやメモリなども徐々にアップしていきました。快適な環境を提供し続けるためにも、ハードウェアスペックは見直しを続けていく項目となります。

ハードウェア選定の基準

ヘテムルはリリース当初から2010年まで、同じベンダーのサーバを利用してサービスを提供してきました。定期的なハードウェアのスペックアップはありつつも、長く運用を行っていたことになります。しかし、2010年の118.6GBへの容量アップの際に、当時のベンダーではこちらの要件に見合うHDD容量を搭載できないという問題が持ち上がりました。また、近くサーバ自体の提供終了の案内もあり、ハードウェア故障に対する予備部材の確保などにも懸念が出てきました。

サーバベンダーは時期やトレンドにより提供されるサーバのラインナップも変わっていきます。ペパボも含めインターネットサービス提供事業者は、その中から適切な要件でハードウェアを選定していく必要があります。一口に選定と言ってもさまざまな判断軸がありますが、このタイミングで次のような流れでハードウェアを検討しました。

ハードウェアスペック

ハードウェアスペックは、単純に言うとCPU、メモリ、ディスク容量上限などのカタログスペックです。最初の段階での判断材料は提供されるカタログでしか得られないため、ここで必要なスペックを見極めます。加えて台数が多くなるサービスでは物理的なラック専有率についてもコストにつながるため、サイズや消費電力も考慮します。

価格

サーバやそれに付随するハードウェアの価格は、サービスの収益予想を鑑みて、必要としている要件を満たすものを選びます。スペックが良くパフォーマンスの高いものでも、価格が高過ぎてはサービス運営を圧迫し、利用されるお客様に対しても長くサービスを提供していくことが困難になってしまいます。サービスのクオリティと出資できるコストのバランスが重要です。

ベンチマーク

いざサーバが決まったあとは、テスト機を借りるなどして実際にカタログスペックと求めるスペックがマッチしているかのベンチマークが必要となります。特に大容量のレンタルサーバではファイルの出し入れなども定常的に発生するため、ディスクI/Oのパフォーマンスは無視できません。切り替えの際には以前のサーバよりも良い数値が出るかを、RAIDRedundant Arrays of Inexpensive Disksなどの構成によっても変動があるため、いろいろな組み合わせでベンチマークを取りました。

具体的にはBonnie++hdparmなどのツールを使い、何度か取得した結果をまとめました。まとめた数値はサーバの型番やHDDの種類・組んだ構成を含めメンバーで共有できるWikiに残していきます。ペパボでは十数個のサービスを有しており、各サービスで利用しているハードウェアが異なることも多いため、これらは比較のためにも有益な情報となります。

そのほかのツールとして、ネットワークはIperf総合的な値についてはUnixBenchなどを利用し、同じくWikiにまとめました。

運用コスト

当時のもう一つの状況として、サーバ購入から設置・OSインストールまでの一連の業務をデータセンター側に委託していたということがあったため、サーバの選定を自社で行うにあたり、この線引きをどうするかも検討を行う必要がありました。長く運用をしていくうえでメンバー1人当たりで見る台数が増える場合、データセンターに赴くコストも無視できません。しかしある程度の部分はこちらでコントロールできるようになっていないと、実運用に影響があります。

このときは、

  • 購入、搬入の手続きは自社で
  • 物理的な配置はデータセンターで
  • OSインストールなどについてはまた自社で

という切り分けを行いました。従来とフローが変わるため、ハードウェアベンダー、データセンター、自社での責任範囲の分解と取り決めを行うことが重要でした[2]⁠。

また、ハードウェアは経年による劣化が避けられませんし、それにより発生するハードウェア障害も必ずつきまとう問題です。そこで搬入以外のフローについても、たとえば交換対応時のベンダー立ち会い手続きなどについても時間をとって調整を進めました。

OSインストール以降については自社となるため、IPMIIntelligent Platform Management Interfaceなどによる遠隔地からのオペレーション、特にBIOS設定や電源オン/オフなどが可能かどうかもポイントでした。この点を含め、以降で説明するOSインストールの自動化へと続いていきます。

OSインストールの自動化

今までデータセンターに依頼していたOSインストール部分を自社で行うようにした理由として、

  • 依頼から作業までの待ち時間を短縮したかった
  • OSインストール作業費用が別途かかった

ということが挙げられます。前者にはたとえば夜間などに急遽行いたい際に自社側で作業を完結できるというメリットがあります。後者は単純にコストの削減となり、台数が増えると地味に効いてきます。

そしてこれらを実現・自動化する手段として、すでに全社的に導入が進んでいたCobblerを採用しました。

Cobbler

Cobblerは次の特徴を持ったツールです。

  • ネットワークブートでOSをインストールする際に必要なコンポーネントがそろっている
  • 個別のホストごとの設定を中央でまとめて集中管理できる
  • PXEPreboot Execution Environmentブートに必要なKickstartファイルのテンプレート化ができる
  • 諸々の処理をまとめたスニペットが利用できる

Cobbler の導入方法は割愛しますが、今までdhcpd、pxe、tftpd、httpdなど個別にセットアップを行っていた煩雑さもcobbler checkコマンドでチェックできるため、ある程度の台数以上のOSインストールをする際にはお勧めです。なお、CobblerはRed Hat Enterprise Linuxまたはそのクローンディストリビューションに特化したツールです。

Cobblerの負うべき責務と、Puppetとの切り分け住み分け

Cobblerの強力なテンプレート機能やスニペットを利用してKickstartファイルをゴリゴリと編集すれば、複数ロールあるサーバのそれぞれを、ネットワークインストールが完了した時点で「必要なミドルウェアのセットアップまで終わっている」状態を作り出すことも可能は可能です。

しかし、OSインストールは時間がかかる作業であり、Kickstartファイルはお世辞にも可読性が高いフォーマットではないため、Kickstartファイルの細かな編集や、それに伴うやりなおしや確認にはたいへんな労力がいります。加えて、OSのインストールさえしてしまえば、以降の設定は次節で述べるシステム構成管理ツールPuppetですべて行えます。

そこでヘテムルではあえてCobblerの責務を絞り、OSインストール以外では以下だけを行っています。

  • ホスト名設定
  • ネットワーク設定
  • 最小限のパッケージインストール

その結果、ハードウェアが設置されてからメンバーが行う作業は次の項目だけで済むようになりました。

$ cobbler system add \
    --name (ホスト識別名) \
    --hostname (OS 上のホスト名) \
    --profile CentOS6.3-x86_64 \
    --kopts "ksdevice=XX:XX:XX:XX:XX:XX syslog=192.168.X.X" \
    --kickstart /var/lib/cobbler/kickstarts/CentOS6-base.ks

$ cobbler system edit --name (ホスト識別名) \
    --interface eth1 \
    --ip (IP アドレス) \
    --subnet (サブネットマスク) \
    --mac (MAC アドレス) \
    --static 1

完了後にハードウェアをPXEブートすることで、最小構成のOSがインストールされたサーバを、指定されたホスト名、ネットワーク情報が設定された状態で起動させることが可能となりました。

このように各ツールがカバーする機能と受け持つ範囲を吟味し、必要な部分のみを利用することで、導入にかかる時間を短縮できました。

システム構成管理ツールの導入

新しいハードウェアの導入は済みましたが、それに伴い新たな問題が顕在化してきました。いわゆるサーバ構築(ミドルウェアのインストールや設定ファイルの配置)はサーバ構築手順書をもとに担当メンバーが手動で行っていたのですが、サーバ準備や追加のスピードが上がったうえにリプレースの機会も増えてきたタイミングだったので、構築時間の長さが全体のボトルネックとなってきたのです。

そこでこの問題を解決すべく、かねてから視野に入れていたシステム構成管理ツールPuppetを使ったサーバ構築の自動化に着手しました。

なお、システム構成管理ツールの機能と必要性については、各所で語り尽くされた感があるため、ここでは詳細を述べません。2章で紹介した宮下によるPuppetの記事オープンソースなシステム自動管理ツール Puppetや、第1章第3章の執筆を担当した栗林による書籍入門Puppet ─⁠─ Automate Your Infrastructureをぜひご一読ください。

Puppet導入の前に

手順書を読み解く

Puppetで定義すべきものとは、現時点で動いているシステム構成そのものです。そのため、まずはそのシステムのもととなった構築手順書を読み解く必要があります。

しかし、⁠すべてをバージョン管理下に」でも触れたとおり、長年に渡って熟成されてきた手順書は次のような問題をはらんでいました。

  • 矛盾がある(一度インストールしたものを、あとでアンインストールする!)
  • 意味のある単位で構造化されていない(後ろに付け足し付け足し)
  • 職人による暗黙の手順が反映されていない

これらは「すべてをバージョン管理下に」への取り組みの中でも改善を進めてはいましたが、Puppet導入のタイミングで改めて大きくリファクタリングと修正を行いました。

マニフェストへの落とし込み

構築手順書がある程度きれいになったら、次はいよいよシステムのあるべき状態を独自言語で記述するマニフェストファイルへの落とし込み作業です。この時点でいまだバージョン管理されていなかったものはPuppetの管理領域にコミットし、ファイル以外のサービスや必要なパッケージといったリソースについても、それぞれの依存関係や処理順と共に、一つ一つを手順書と見比べながら記述していきました。

なお、Puppetはテンプレート言語ERBによるファイルの動的な内容生成が可能ですが、ヘテムルでは極力それを利用していません。先述したheteloyは単純なファイル配布に特化しておりERBの解釈まではできないため、ツール間での連携が取りにくかったからです。ネガティブな理由に聞こえるかもしれませんが、実は設定ファイルなどのほとんどは静的な内容で済みますし、ミドルウェア側に備わっている設定include機能などで工夫すれば、動的な内容生成は実はほとんど必要なくなるものです。加えて言えば、動的生成が不要な構成や設定にすることによる運用の効率化という側面も、ある程度の規模のシステムでは無視できません。

マニフェストの検証

作成したマニフェストや設定ファイルの内容検証は、社内の開発VMで行いました。VMは2章で触れたKVMKernel-based Virtual Machine管理ツールMaglica[3]を利用して手軽に作成できるようになっています。

作成したVM上で実際にPuppetを適用して、

  • マニフェストのシンタックスエラーはないか?
  • 仕様どおりにサービスは稼働しているか?
  • Nagiosの監視が通るか?

といったあたりをチェックしたあとにmasterブランチにマージしました。

Puppetの導入

新規構築分から順次導入

検証後は本番環境への導入ですが、既存のサーバでいきなり適用するのはリスクが高いため、まずは新規投入するサーバ構築から使用することにしまし

た。この時点で既存環境の仕様管理もある程度進んでいたとはいえ、いまだ把握しきれていない特殊な設定やそれに依存した機能が存在する可能性もあり得たためです。新規投入サーバでの稼働確認を時間をかけて行い、発見された問題はPuppetへ反映させるという作業を重ねることで内容をブラッシュアップしました。

新規投入サーバでの安定稼働が確信できたため、現在は既存サーバで一台一台noop実行(dry-run)で差分を確認し、場合によっては手作業での環境修正をしつつ、順次導入を進めているところです。

Puppet導入後

機能追加はマニフェストの追加

サーバへの機能追加は、今までは

  • ① サーバ構築手順書への追記
  • ② 既存サーバへの追加作業の手順書を作成し、全台へ適用

という手順で行っていましたが、すべてがPuppet管理下に置かれたことで、マニフェストへの追記作業のみに変更されました。サーバの状態はPuppetが担保する冪等性(べきとうせい)注4により、1つのマニフェストで既存・新規両方のサーバをカバーできるという恩恵を感じることができます。

リファクタリング

導入後のマニフェストは、⁠まず既存仕様と同じ振る舞いをする」ものとして書き進めたため、内容としてはけっして読みやすい・理解しやすいものではありませんでした。そのためある程度時間が経ったものや、機能追加の際には随時リファクタリングを行っています。例としては、

  • 1ファイルに肥大化した内容を意味のある粒度のファイル・クラスに分割する
  • 各ロールに重複している内容はモジュールに切り出してコード量を減らす

などです。このあたりの考え方は通常のソフトウェア開発と何ら変わりません。特にマニフェストはサーバ仕様の要なので、メンテナンス性が高い状態に保つことが重要です。

また、マニフェストだけでなく、バージョン管理されている各設定ファイルやスクリプト類についても見直しをかけています。スクリプト類には、

  • ファイル名が同じなのに複数ヵ所に配置されている
  • どこから使われているかわからない

など、疑問を呈したくなるものまで存在します。これらを放置せず見直し、不要な場合は思い切って項目を削除するなどの作業も平行で進めています。地味ですが気を遣う作業で、項目を足すよりも引くほうが勇気がいることを実感します。

また、ファイル追加時や削除時には、経緯や目的などをコミットメッセージに書いてトレースしやすくしておくことも、のちの自分やチームのためになります。ファイル追加時に「○○を追加」というメッセージはNGで、必要なのはその理由を書くことです。

レビュー

前述のとおり、機能追加やサーバ仕様のバグの修正はすべてマニフェスト上で行われているため、導入後はメンバーが触る機会が極端に増えます。作業を進めやすくするためにも、機能追加やトピックごとにブランチを切り、各々の作業が完了した段階でGitHubのpull requestを行い、チームメンバーでレビューをするように心がけています図1⁠。この取り組みは、

  • メンバー間での仕様の共有
  • 冗長な記載の簡素化・バグの発見
  • メンバーのスキルの底上げ

などに寄与しています。

図1 GitHubを利用したマニフェストのレビュー
図1 GitHubを利用したマニフェストのレビュー

監視システムの運用改善

問題

サービス監視システムの運用にも問題があったため、改善の対象となりました。

監視ソフトウェアはNagiosを使っていましたが、設定(各種オブジェクト定義ファイル)のバージョン管理が行われていなかったため履歴や経緯がわからず、適切なレビューを受ける機会もなかったため、次のような無秩序で運用コストが著しく高い状態でした。

  • 記述スタイルが人によってバラバラ
  • 設定の重複
  • 各種オブジェクトの関連付けが無茶苦茶

また、対象ホストの追加や削除もすべて手作業で行っていたため、設定の更新漏れなどが発生してしまい、それに気づくことなく長期にわたって放置されてしまうこともありました。

リファクタリング

問題の解決のために、まずは大規模な設定のリファクタリングに着手しました。また、使っていたNagiosのバージョンが古く(1系⁠⁠、設定書式の自由度が低かったこともメンテナンス性の低い設定を産む一因となっていたため、同時にソフトウェアのバージョンアップ(3系)も行いました。

作業は既存のNagiosを稼働させたまま、新しいNagiosも並行して稼働させた状態で行い、入念な動作確認をしたあとに新旧の切り替えを行いました。

方針としては、リレーショナルデータベースの正規化に似ています。各オブジェクトタイプの意味に合わせた適切な関連付けを行い、冗長性を排除することで、メンテナンス性の高い設計にできます。

みなさんの管理するNagiosで、対象ホスト1つ追加するのに複数ヵ所の設定を更新する必要があるとしたら、それは危険信号です。大きな負債になる前に早めの見直しをお勧めします。

設定の自動生成

次に、最も更新頻度の高い設定ファイルであるhosts.cfg(監視対象となるhostオブジェクト定義ファイル)は自動生成するように変更しました。設定のメンテナンス性が上がったとしても、人の手による作業をできる限り排除しないことには、更新漏れのリスクは残ったままになってしまうからです。

設定は先述したroles.yamlをデータソースとして、Perlスクリプトでテンプレートを当てて生成しています。運用手順の中でroles.yamlの更新とスクリプトの実行は不可分になっているため、設定の更新漏れはほぼ起こり得ない形となっています。

roles.yamlはほかにも、バックアップシステムや、リソースモニタリングに使用しているMuninの設定自動更新のしくみでも使われています。こうした各種システムのデータソースを一元化することは、作業の省力化と運用の確実性を上げるために必要不可欠です。

設定ファイルの運用と自動生成については、筆者(黒田)が以前に勉強会用に作成したスライドNagios運用例(on AWS⁠⁠─⁠─ sqaleの場合がありますので、そちらを見ていただくと、より具体的にイメージできると思います。なお、内容はペパボの別サービスを例に書いたものですが、ヘテムルでもだいたい似たようなしくみとなっています。

今後の改善

もちろん現状がベストというわけではなく、実際に運用する中から、ブラッシュアップできる部分が新たに見えてきます。以下は今後さらに改善しようとしている点です。

ホストやロール情報をTriglavに集約する

roles.yamlでロールの一元管理はできるようになりましたが、サーバに付随する情報はロールだけではなくIPアドレスやハードウェア構成などもあるため情報が不足しています。また、よりプログラマブルに情報を操作できる状態を目指しています。そこで現在、第1章第3章を執筆した栗林が中心となり開発しているTriglavに情報を集約し、API経由で必要な情報の取得や更新ができるように改善していこうと考えています。

serverspecによるPuppetマニフェストと適用結果のテスト

Puppetで構成したサーバが意図どおりに構成されているかの確認方法の改善として、前述の宮下が開発しているserverspecの導入を行い、サーバの確認やテストの自動化と、属人性の排除を進めていこうと考えています。

Triglavもserverspecもオープンソースとして開発されています。ペパボのみでなく広くインフラの運用改善につながると思いますので、興味がある人はぜひ利用して、フィードバックをいただければ幸いです。

本章のまとめ

今回紹介した取り組みによって現在のヘテムルのインフラは、少なくともサービスの成長の足かせになるような大きな負債は返済し終え、新たな負債も生みにくい状態に大きく改善されました。

かつて、負債の返済や煩雑な運用業務のために多く割かれていた人的リソースを、今では新規機能の技術検証や、導入のために使えるようになりました。今現在もインフラチームが主軸となる複数のプロジェクトを進行中です。今後もサービスをご利用いただいてるみなさんに安定した、また価値のある機能を提供できるよう運用を進めていきたいと考えています。

おすすめ記事

記事・ニュース一覧