Ansible+Dockerでシンプルにサークルのサーバを管理しはじめた話

どうも千葉大電子計算機研究会(以下CCS)、老害㌠いかろちゃんです。 CCS Advent Calendar 2016 の6日目の記事として 老害なので現役生を差し置いてサーバ管理をしちゃってる話を今日は書こうと思います。

サークルでサーバ管理をする上での問題点

大学サークルの特徴(少なくともCCSは)として下記があります。

  1. 人間の流動が激しい(役職は一年交代)
  2. 様々なWebアプリケーションがデプロイされる可能性がある
  3. 予算がその年のサークルの人数によって決まる
  4. 仕事でしているわけではないのでかけられる時間が限られる

したがって

  1. サーバを構築した人が連絡がつかず誰も構成を把握・対応できなくなる
  2. 環境がコンフリクトしてしまい最悪各種サービスが提供できなくなる
  3. いつIDCの変更を余儀なくされるかわからない
  4. 時間的制約で後回しにされがち

といった問題があります。

これらの問題を解決するために構成をシンプルにしてAnsible+Dockerでコード化をすすめてみたよというのが今日のお話。 今後CCSのWeb管になる人、他のサークル等で同様の悩みを抱えている人の参考になれば幸いです。

技術選択

クラウド

会室にサーバ機を置くのはネット回線を引く手間、盗難・火事等が怖いのでまず最初に却下としました。 クラウドとかVPSの候補としてはAWSGCP,IDCFクラウド、さくらVPS、ServersMan@VPSが候補に。 料金・拡張性を考えてIDCFクラウドとしました。 IDCFクラウドなら最低ワンコイン(オブジェクトストレージつかうともっとさげられますが...)からはじめられます。 (ServersMan@VPSは安いけど前使った感じあんまり印象が良くなくてお遊び以上には使えないなーっていう感じがあったので却下)

お金があるんだったらAWSとかGCPのPaaSをがんがんつかっていくというのがよい選択な気がします。

OS

現在はCentOS7を使っています。 これは最近のものがまぁまぁ動いてかつ枯れていて、サポート期間も長いため選択しました。 過去にCoreOSやFeodraつかってみましたが、CoreOSは小規模環境ではただただつらい、 Fedoraはサーバ機でする選択ではなかったですね...

構成管理

構成管理ツールのひとつであるAnsibleで構成管理を行っています。 Ansibleを使い構成をコード化することで(Ansibleがわかる人なら)誰でもサーバの構成を把握しやすくなりました。 また、将来のクラウド移転を行うことになった際もだいぶ楽なはずです。

Ansible特徴としてはエージェントレスであることYAMLで記述するため比較的設定がシンプルであることが挙げられます。 Chef-soloなんかでもいい気も一瞬しましたが、シンプルにできることはシンプルに済ませるというのが引き継ぎや作業のコスパを考えるといい気がしたのでAnsibleを選択しました。

Webアプリケーション

ここでコンテナ型仮想化技術のDockerです。 これでAnsibleを導入したのと同様の環境のコード化を手に入れ、 また環境がホスト・他のDockerコンテナと分離されるのでコンフリクトを気にする必要がなくなります。

Webサーバ

軽量・高速なWebサーバであるNginxを採用しました。 Nginxで静的サイトの配信及びWebアプリケーションへの振り分けを行っています。 各種環境に依存するサービス、特にWebアプリケーション(というか今はWebアプリケーションしかコンテナ化してない...)をコンテナ化しました。

監視

外形監視にはUptimeRobotを利用しています。 また,内部のリソース管理にはNagiosを利用しています。 Mackerelを使い始めました(詳細はこちらMackerelとUptimeRobotでサークルのサーバを監視している話 - まどろみの思考空間)

Nagiosを利用しているのはわたしが慣れているからという理由だけなのでZabbixでもMackerelでもなんでもいいと思います。

コードの管理

Ansibleのplaybook, DockerのDockerfile, そしてコンテンツ系ソースコードの管理はGitHubで行っています。 gitによるバージョン管理を行うことで構築でミスって障害を引き起こしても最悪直前の状態までもどせるという安心をえることができます。 学生ならアカデミックライセンスがつかえますのでプライベートリポジトリもつかえていい感じです。

実装

仮想マシンの立ち上げ・基本設定

IDCFはCloudStack APIに対応していますのでAnsibleのCloudStackモジュールを利用することで上位のファイアウォールの設定はもちろん、VMインスタンスを自動的にたてて基本的な設定をするといったことまで可能です。 これは下記を参考に実装しました。

AnsibleでCloudStackを操作する(基礎編:仮想マシン作成とプロビジョニング) - Qiita

ユーザはセオリー通りsudo権限を持つ管理者ユーザ、webコンテンツの管理者ユーザ(sudoは不可)を用意しました。 webコンテンツの管理者ユーザはDockerの各種コマンドが実行できるようにdockerグループに入れてあります。

SSL証明書の取得

世の中の常時SSL化の流れにしたがってCCSでもすべてのページを原則https化しています。

SSL証明書の取得にはLet's Encryptを利用しました。 Let's Encryptを使うと無料でSSL証明書を取得できます。 また,コマンドラインで取得,更新が可能ですので非常に自動化向きです。 certbotyumでいれて定期的に更新するようなcronを仕込めば完了です。 Ansible化するための注意点としてSSL証明書の取得のコマンドをそのまま叩いてしまうと冪等性が保証されないので --keep-until-expiringオプションを付ける必要がありました。

Nginx

これもAnsibleで管理です。 特に細かいチューニング等はしていません。 また,一時期動的にdockerコンテナにproxyする実装にしようかと思いましたが, 実装コストを考えて手動で設定ファイルを書き換えて各種コンテナにproxyさせるようにしています。 必要になったら実装すればよいでしょう。

監視

例のごとく監視設定,監視エージェント(NRPE)もAnsibleで管理しています。 監視項目で特にかわっている点としてはサーバにSWAPがないのでメモリ使用量監視にしているということでしょうか。 これには下記のプラグインを利用しています。

GitHub - koemu/nagios_plugin_check_memfreetotal: Checking overall memory free space (RAM + Swap) plugin for Nagios.

また,コンテナの起動監視もしたいと思っていて,現在こちらのプラグインを作成中です。

監視サーバは暫定的にわたしの個人契約しているのを利用しているのでそのうち移行したいと考えています。しました。 Mackerelに移行した記事はこちら(詳細はこちらMackerelとUptimeRobotでサークルのサーバを監視している話 - まどろみの思考空間)

コンテンツ系

先程説明したとおり,WebアプリケーションはDockerで管理しています。 基本的に揮発しても良いものはDockerfileにかいて、 データはVolumeでマウントするようにしています。 gitで管理はしているものの,基本的に手動でデプロイです。 ポート番号とかも手動管理... これはいけてないのでそのうち直したい...

実際に運用してみて

メリットとしては作った本人も構築当時の設定等をわすれてしまうもので, 何かあったときとりあえずGitHubをみて設定を確認できるってのは便利だなって思ってます。 今までは構築担当者が死んだらサーバの構成は闇の中でしたがそういったこともなくなりました。 また,教える時に余計コストが増えるかと思いきやAnsibleやDockerの概念さえ教えてしまえば、 細かいところに気をとられることなくざっくりと教えられる、ダブルチェックの手間が減る等 で時間的コストを大幅に減らすことに成功しました。 具体的には昔は構築は教えながらだと2,3日fullでしても終わらないとかでしたが 今は最短数秒,教えながらしても合計12時間程度の時間になりました。

今回サーバ構成で意識したこととしては、要求を満たしかつ凝りすぎないということです。 再利用性や柔軟性をかんがえたり、もっとストイックに全部Dockerで管理したり... ともっとやろうと思えば色々できたと思います。 ただそういうことをしてしまうとメリットをデメリットが上回ってしまいます。 また、シンプルなシステムのほうが壊れにくいし何かあっても対処しやすい。 そういったことを考えて妥協点を探るというのが特にサークルのサーバような 必要経費ではあるものの全力でそれに時間をかけているものではないといった場合に 必要なのではないかと思います(もちろんお金があるんだったら専門の会社とかにアウトソーシングとかもありなんでしょうけど...) 実は明らかな技術的負債も作り込んでしまっていますが、これはきっと後輩たちが解決してくれるでしょう(他人任せ

ただ,緊急で対応したいとかテストしたいとかのときになかなか面倒だなーっていうところはあるので そういったのに対応しやすいPlaybookとかかきたい(テスト環境をいい感じに整備することもふくめ)なあといった感じです。

まとめ

サークルのような低予算かつ人の流動が激しい環境ではAnsible+Docker等で出来る限り環境のコード化する, 構成をシンプルに保つことで幸せになれるかもというお話でした。

次は @littlebird514 君の予定です。よろしくおねがいいたします