SRE視点で見るマイクロサービス

FiNC SRE担当の鈴木です。

今回は、以前社内のマイクロサービス勉強会で話した「SREの視点からみたマイクロサービスの運用」に関して紹介していきたいと思います。 いつもは、マイクロサービス万歳みたいな記事を書いていますが、今回は、こんなところが困った、こんなところが面倒くさい、みたいな事にフォーカスを当ててみました。

FiNCにおけるマイクロサービスの成長速度

FiNCにおけるマイクロサービスの取り組みは、こちらの連載こちらのスライド に紹介されていますが、FiNCの成長に伴い、サーバー構成も日々成長しています。

具体的には、私がサーバーの面倒を見出した2015年の2月時点では5つのマイクロサービスの結合により出来上がっていたシステムが、2016年の1月時点で小さいものも含めると16個にまで増えていて、この数はさらに増えていく予定となっています。 

増加する要因としては、新サービスのリリースの他にも、既存のサービスの機能の切り出しや、フロント部分の切り出し、などがあります。 もちろん、コンポーネントが増えるわけですからインフラの管理コストや費用も上がっていきます。

立ちはだかる問題たち

image

そんな成長するサービスの中で、とくにマイクロサービスだからこそ立ちはだかって来る問題点について紹介していきたいと思います。

  • 構築の日々
  • ソフトウェアのバージョンアップ
  • 共通部分の設定変更
  • 少しずつ異なる環境
  • 実は大きなものシリック疑惑
  • 開発環境構築における問題
  • 諦めるところは諦める
  • サーバーにsshしない、chatops中心
  • コストの増加
  • Too Many Slack Channels

構築の日々

構築に関しては、自動化するのみです。

FiNCでは、構成管理ツールとしてAnsibleを使用しているので基本的には、AnsibleのPlaybookを新しいサービス用に書くだけで構築が出来るようになっています。 また、細かい部分で言うと、監視回りや、分析用のログの設定なども自動化しておく必要があります。 

例えば、サーバーを構築して立ち上げたタイミングで監視対象に追加される仕組みや、サーバーが吐き出すログを自動でfluentdがストレージに送る仕組みなど、基本的には自動でセットアップされるようにすることで、工数の削減だけでなく抜けもれやミスなどを防ぐ事が出来ます。 

コンポーネントの増加により少しずつ設定が異なる事もあるのでそういった部分は人の手を介さないようにする事が重要です。

ソフトウェアのバージョンアップ

ソフトウェアのバージョンアップは気を使う作業ですが、マイクロサービスでは、サービスの数だけそれを行わないといけないので大変ですし、時間もかかります。仮にモノリシックなサービスの場合には1回やれば良いですが、FiNCの場合は16回やらないといけません。 

ただ、逆の側面として、バージョン上げの影響の局所化という事が挙げられますので一長一短であるとも言えます。この特徴により、一つ一つのバージョンアップ作業の重さは軽減されるので、常にバージョンを最新に保つ事に関するハードルは下がっているとも感じています。

共通部分の設定変更

FiNCではunicornを利用してプロセスを立ち上げていますが、unicornの設定ファイルに修正を入れたい場合に、全てのサービスに漏れなくミス無く設定を入れる必要が出ます。 また、デプロイに関しても、Capistranoを利用していますが、各サービスにcapistranoのgemがインストールされ、設定ファイルが書かれている状況で、修正を全てに適用する作業が徐々に大きくなっていきました。 

この問題に関しては、共通コンポーネントを切り出してインフラツールとしての一つのマイクロサービスとしてしまう方針を取っています。 たとえば、capistranoに関しては、全てのサービスをデプロイ出来る様な新しいサービスを独立して作成し、デプロイの方法などを変更したい場合にはそこだけを修正すれば良い、という構成に変更しました。

少しずつ異なる環境

長らくサービスを運用しているとつきものかと思いますが、"歴史的経緯"といった理由で、少しずつ構成が異なるものが存在(口伝)すると思います。 実はこの辺りが結構事故るポイントで、新しくジョインした人に構築をお願いして漏れてましたー、というのは結構あります。 

口伝を見つけたら、即Ansibleに反映、を徹底しています。

実は大きなモノリシック疑惑

マイクロサービスを運用していると、ふと思う事だとおもいます。 例えば、良く聞くメリットとして「マイクロサービスにすると障害が局所化する」と言う事が挙げられますが、それは本当か?と。

 一部はそうでないところはあるはずで、例えば認証系のサービスがあればそれは確実に他のサービスから依存されているはずですし、たとえは、FiNCにおいても、パーソナルサーベイと呼ばれるアンケートシステムがダウンした場合には、アプリをそれ以上先に進める事は出来なくなります。

 こういった事情があるので、サービスの粗結合化や影響範囲の局所化は出来る限り進めつつも、「マイクロサービスだから気軽にデプロイ出来る」とか、「マイクロサービスだから他に影響はあたえない」という認識を安易に持つのではなく、他に影響を与える可能性がある、という認識をもって運用していく必要があると思っています。

開発環境構築における問題

「実は大きなモノリシック疑惑」に関連して、各ディベロッパーの個人PCにおける開発環境にも問題が生じます。各人の担当するコンポーネントだけを立ち上げても開発が出来ない状態に出くわしてしまいます。 

当初、この問題をローカルサーバーにdocker環境を構築して各ディベロッパーがそれぞれ自分のPC内に、FiNCの主要なコンポーネントを立ち上げられるように構想していたのですが、コンポーネント数が増えるに従って利用するメモリの量が増加し、個人のPCには全てが入らない状況になってきました。 

そのため、現在のプランとしては共通で利用出来る開発環境サーバーを構築し、自分の開発対象サービスだけをローカルで立ち上げ、その他はクラウド上の開発環境サーバーに接続する、という構成を考えています。 これは現在鋭意設計中ですので、完成したらまたブログに投稿したいと思います。

諦めるところは諦める

FiNCのサービスはほとんどがAWSで運用されていますが、小さなコンポーネントやほとんど更新がないようなコンポーネントに関しては、HerokuやElasticBeanstalkといったフルマネージドなサービスを頼る事も重要だと考えています。 そうする事によって、負荷が高くなる様なコンポーネントや、AI技術などを使っている特殊な環境に対してより大きな工数をさく事が出来るようになります。

サーバーにsshしない、ChatOpsやログの集約と可視化

マイクロサービスにおいては、sshしなくても良い運用の重要性が高いと考えています。 マイクロサービスが増えて、開発者が把握していないコンポーネントが増える事によりオペミスも増加します。そのため、開発者は出来るだけsshしない様な運用をするべきです。 具体的には以下の様な構成を整備中です。

  • ログの集約と可視化
    サーバーにログインせずにあらゆるログを調査出来る事が重要です。また、サーバーにそのままログを出しっぱなしにしていると、サービス毎にログの所在がバラバラになってしまうので、一カ所に集約する事も大切です。 現在、fluentdによって、アプリケーションのログをS3やredshift、ElasticSearchなどに送る事によりログを集約し、sshせずにログを可視化しています。
  • ChatOpsでのオペレーション
    デプロイなどのコマンドをチャットから打てるようにしています。今後はより複雑な操作に関してもチャット経由で出来るようにしていく予定です。ChatOpsでオペレーションする事によりあらかじめ決められた操作を決められたサーバーに対してしか行えないため、オペミスを減らせる事が期待出来ます。

コストの増加

マイクロサービスで冗長構成を取ろうとすると、各サービスにおいて、必要台数+1台とする必要があるためモノリシックに比べるとサーバー台数が増加します。 これは仕方が無い事なのですが、Dockerを利用すればそこの余剰を効率良く使える可能性があります。
(運用負荷やコストの増大を、Dockerで解決)

Too Many Slack Channels

これはおまけですが、Slackのチャンネルが増えまくります。

まとめ

以上、マイクロサービスにおいて困った点を紹介してみました。 ただ、それ以上にメリットも感じていて、例えば

  • 異なる言語を小さなコンポーネントから導入出来る
  • コンポーネントが多いのでリードエンジニアの育成機会が多い
  • (上でも紹介していますが)ソフトウェアのバージョンアップが小さいコンポーネントで実行出来る
  • テストの単位が小さくなる

などなど色々とあります。 今回挙げた問題点のうち、まだまだ設計途中や解決途中のものもあるので、更新点がありしだい随時ブログで紹介していきたいと思います。