読者です 読者をやめる 読者になる 読者になる

リクルート住まいカンパニー Tech Blog

ITのちからで暮らしをよくしたい、エンジニア・デザイナーが発信するTech情報メディア

オーケストレーションツールConsulの紹介(2)

f:id:recruit-sumai:20170310130104p:plain

前回は現代のサービス運用の課題とConsulの基本構造について説明しました。

下の図はWebアプリケーションサーバ 、RDBサーバ、memcachedサーバ、バッチサーバ、デプロイサーバから構成される小規模なWebサービスのインフラ構成例です。

f:id:recruit-sumai:20170124111704p:plain

今回は以下の様なインフラ課題に対してConsulを使った対策を見ていきましょう。

  • 稼働中に負荷に合わせたオートスケール機能を使ってアプリケーションサーバの台数を増減させている
  • キャッシュサーバはピークタイムの負荷を考慮して二台に負荷分散している。また、メンテナンスや障害の発生時にはアプリケーションサーバから停止しているキャッシュサーバにアクセスしないよう切り離す必要がある。
  • Webアプリケーションやソフトウェアのアップデート等は全アプリケーションサーバに漏れなく実施する必要がある(ただし、作業の瞬間に何台アプリケーションサーバが存在するかは不明)

 

メンバー検出機能

前回の記事でConsulの中核機能は分散KVSであることをお伝えしました。このKVSにはmemcachedやredisのように手動でkey-value形式のデータを登録することが可能ですが、 手動で登録しなくとも各ノード上でエージェントを稼働させておくだけでクラスタに所属するノードに関するさまざまなデータが自動的にKVSに登録されるため、このデータを活用することで基盤運用を簡単にすることができます。

まず紹介するのは、Consulクラスタに所属するノードリストから該当するホストに紐付いているIPアドレスを取得する機能です。では実際に取得してみましょう。取得のためにはDNS、RESTインタフェースが使用可能です。

$ curl ‒s http://CONSUL-SERVER:8500/v1/catalog/nodes/pro-sp-web1
  [
    {
      "Address": "a.b.c.1”
    }
  ]
$ dig @CONSUL-SERVER pro-sp-web1.node.consul a
;; ANSWER SECTION:
pro-sp-web1.node.consul. 0 IN A a.b.c.1

地味に便利なのはDNSインタフェースがあるのがいいところです。このメンバー検出機能を使うことでサーバの追加削除時の内部DNSもしくはhostsファイルへの登録を省くことができます。もちろん個別のサーバの検出だけではあまり実用的ではありませんので次にサービス検出機能を使ってみましょう。

サービス検出機能

各サービス毎の連携に必要なエンドポイント情報は地味に扱いが厄介な情報です。 身近な例としてWebアプリケーションから見たRDBMS、キャッシュサーバのホスト名などがあります。こういった情報は何らかの形でアプリケーションからアクセス可能な形で保持する必要があるのですが、 production/staging/developmentなどの環境ごとに違うためソースコードに埋め込むとアプリケーションの移植が難しくなってしまいます。 そのため、通常はアプリケーションのソースコード内には記述せず、環境変数や設定ファイルなどに外出しすることがほとんどです。

ところが、ホスト情報はオートスケールの発動や障害時に運用中に変化することが想定されますので、最新の情報を常に収集して 、関係するサーバの設定ファイルを全て更新するという複雑な仕組みが必要になってきます。

ではConsulのサービス検出機能を使って、関連するサービスを連携してみましょう。

準備 サービスが稼働するサーバにサービス定義ファイルを設置します。 サービス定義ファイルにはサービス名、タグ、監視スクリプトを記載します。 同一サービスかつ同一のタグを複数のノードで定義することも可能です。

例:ランキング情報キャッシュ用memcachedサービスの定義

{"service":
    {
        "name":”memached”,
        "port": 11211,
        “tag”:”ranking”,
        "check":
            {"script": ” memcached-tool localhost stats″, "interval": "60s"}
    }
}

サービス定義ファイルを設置するとKVS上にサービスの状況が常に記録されるようになります。

ではこのサービスの状況を取り出してみましょう。特に便利なのがDNSインタフェースです。DNSインタフェース経由で問い合わせすると、 同一のタグのサービスが複数のノードで稼働している場合ロードバランシングされ、 サービスがダウンするとそのノードはレスポンスから除かれますので、クライアントは常に正常に動作しているサービスにアクセスすることができます。

service=memcached tag=ranking のサービスが登録されたノードが二台とも稼働している場合

$ dig @CONSUL-SERVER ranking.memcached.service.consul
;; ANSWER SECTION
ranking.memcached.service.consul 0 IN b.c.d.1
ranking.memcached.service.consul 0 IN b.c.d.2

一台障害が発生した場合

$ dig @CONSUL-SERVER ranking.memcached.service.consul
;; ANSWER SECTION
ranking.memcached.service.consul 0 IN b.c.d.1

アプリケーション側の設定ファイルにはホスト名として「タグ名.サービス名.service.consul」を登録しておくだけで常に稼働中のいずれかのノードへアクセスすることができます。

 

一斉コマンド実行

サービスを運用していると、アプリケーションのデプロイやチューニングに伴う設定変更などで複数のサーバへ何らかのコマンドを送信したい場合がよくあります。 ところが危険なのはサーバ一覧表を元に一サーバずつ手動でポチポチやってたら「実施漏れ」が起きることです。 「アプリケーションをデプロイしたら動作がおかしい」「あ、昨日追加したサーバ、一覧表に追加するの忘れてた」。。はい、言葉になりません。

このようなケースでは、Consulの一斉コマンド実行機能を使うことで指定した条件にマッチするノード群に一斉にコマンドを実行することができます。

例:

$ consul exec –service=httpd –tag=auth “cd /docroot ; git pull ”

この例ではタグがauth、サービスがhttpdのサーバのみWebアプリケーションをデプロイするコマンドを実行します。今この瞬間条件に該当するノードが何台あるかどうか、人間が認識していなくとももれなく実施することが可能です。

イベントハンドラ

サーバ増設をオートスケールで自動化するなど、頻繁に行う場合に発生する問題として、ノード増設時に必要な細かいオペレーションの実施漏れなどがあります。 例えば、ロードバランサ、サーバ監視システム、設定情報のバックアップシステムなどへの登録があります。

「同じサービスが稼働するサーバを増設する場合でも、開発環境ではなく本番環境への設置の時だけ監視やバックアップサーバへの登録が必要です」なんて作業漏れろって言ってるようなものです。Consulを使用することで、こういった環境固有の退屈な処理を自動化することが可能です。

では、追加されたノードを自動的にzabbix(サーバ監視システム)へ登録する処理をイベントハンドラを利用して設定してみましょう。クラスタのいずれかのノード上で以下のようなコマンドラインを実行してイベントにハンドラを紐付けておくことで、ノード追加イベントの発生時にzabbixへ登録を実行することが可能です。

$ consul watch –type node –name add “register_zabbix.sh”

(イベントの発生したノード情報はregister_zabbix.shの標準入力に渡されます)

まとめ

IaaS等クラウドサービスの普及により、スケールアウト構成はコストを抑えて高い性能が得られるため広く用いられるようになりました。ところが運用手法自体はあまり大きな進歩がなく、オンプレミス時代を引きずった暗黙知山盛りの職人的手運用になっているケースが多く見られます。

そのため、リードタイムが極小であったり、API等で人手に頼らずインフラ構成が変更できるなど、サービスプロバイダからいくら良いサービスが提供されていても、ユーザ側の運用体制が追いついていないため十分に使いこなせていないケースがよくあります。また、サーバに比べて運用担当者自体を増設するのは難しく、職人的運用に終始していてはスケールアウト/アップも難しいという側面もあり、将来的にサービス拡大していく上で支障をきたす可能性が高いと考えています。

IaaS、PaaS、SaaSがほぼ普及し最早クラウドネイティブという言葉が一般的になった時代、Consul等を使って運用方法を見なおす良い機会なのではないでしょうか