8
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SensuAdvent Calendar 2014

Day 19

SensuのhandlerとしてAnsibleを使う

Last updated at Posted at 2014-12-19

うどん大学 情報系 院1年の堀内です.
勢いで Sensu Advent Calendar を立てましたが,無事埋まっていてホッとしています.

SensuはAnsibleと同時期に使い始めました.
現在は,研究室のサーバ監視に使っています.

もくじ

  1. Sensuとの出会い
  2. 研究室のサーバ監視で
  3. handlerとしてのAnsible

Sensuとの出会い

研究室でAnsible使ってる話」でも書きましたが,8月末にヤフーのインターンシップに参加しました.
そこでSensuが使われているのを見せて頂き,興味を持ったのがキッカケです.
ホテルに戻ってから,試してみようと作業していたのを覚えています.
(Ansibleを使ってsensu-clientを流し込もうと四苦八苦.)

ヤフーでの取組みはAdvent Calendarに書かれています.

研究室のサーバ監視で

研究室にはVMを含めて20台以上のサーバがあります.
そこにAnsibleを使ってsensu-cluentを流し込み,監視しています.

監視項目はCPUやメモリ,HTTPなど,基本的なものだけです.
community-plugins もしくは,その機能を削って使っています.

sensu_metrics.png

metricsはElasticsearchに投げて,Kibanaで可視化しています.
(fluentdなどを介さず,handlerから直接投げています.)
また,研究室で Typetalk を使っているので,Hubotを使ってアラートを投げたりもしています.

handlerとしてのAnsible

ここからが本題です.

例えば,SensuのHTTPチェックでCRITICALが発生したとします.
そこで,handlerからWebサーバを再起動するためにAnsibleを使ってみます.
(ついでに,Typetalkに再起動の通知も出します.)

発生したアラートはこんな感じ.

{
  "client":{
    "name": "web-server-01",
    "address": "192.168.11.10",
    "subscriptions": ["webservers"],
    "timestamp": 1326390159
  },
  "check":{
    "name": "check-http",
    "issued": 1326390169,
    "output": "HTTP CRITICAL: HTTP/1.1 503 Service Temporarily Unavailable",
    "status": 2,
    "command": "etc/sensu/community-plugins/plugins/http/check-http.rb -r -u http://localhost/",
    "subscribers":["webservers"],
    "interval": 60,
    "handler": "ansible",
    "history": [],
    "flapping": false
  },
  "occurrences": 1,
  "action": "create"
}

まず,このアラートを受ける/etc/sensu/plugins/ansible_handler.rbを作ります.

#!/usr/bin/env ruby
# Sensu Ansible Handler

require 'sensu-handler'

class AnsibleHandler < Sensu::Handler
  def playbooks
    settings['ansible']['playbooks'] || '/etc/sensu/playbooks'
  end

  def typetalk_vars
    {
      client_id: settings['ansible']['typetalk_client_id'],
      client_secret: settings['ansible']['typetalk_client_secret'],
      topic: settings['ansible']['typetalk_topic']
    }
  end

  def generate_hostfile(event)
    client = event['client']['name']
    address = event['client']['address']
    check = event['check']['name']

    hostfile = "/tmp/#{Time.now.strftime '%y%m%d%H%M%S'}.hosts"
    typetalk = typetalk_vars

    File.open(hostfile, 'w') do |f|
      f.puts "[#{check}]"
      f.puts "#{client} ansible_ssh_host=#{address}"
      f.puts "[#{check}:vars]"
      f.puts "typetalk_client_id=#{typetalk[:client_id]}"
      f.puts "typetalk_client_secret=#{typetalk[:client_secret]}"
      f.puts "typetalk_topic=#{typetalk[:topic]}"
    end

    hostfile
  end

  def handle
    status = @event['check']['status']
    occurrences = @event['occurrences']
    return if status < 2 || occurrences > 1

    hostfile = generate_hostfile @event
    check = @event['check']['name']
    result = `ansible-playbook -i #{hostfile} #{playbooks}/#{check}.yml`
    unless $?.to_i == 0
      puts result
    end

    File.delete hostfile
  end
end

handlerの設定ファイル/etc/sensu/conf.d/handler_ansible.jsonは下記の通り.

{
  "ansible": {
    "playbooks": "/etc/sensu/playbooks",
    "typetalk_client_id": "abcdefghijklmnopqrstuvwxyz123456",
    "typetalk_client_secret": "abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz123",
    "typetalk_topic": 1234
  },
  "handlers": {
    "ansible": {
      "type": "pipe",
      "command": "/etc/sensu/handlers/ansible_handler.rb"
    }
  }
}

ansibleで実行する/etc/sensu/playbooks/check-http.yml
Nginxの再起動と,Typetalkの通知のみでシンプルにします.

---
- hosts: check-http
  sudo: yes
  tasks:
    - name: restart nginx
      service:
        name=nginx
        enabled=yes
        state=restarted

    - name: notify to typetalk
      typetalk:
        client_id={{ typetalk_client_id }}
        client_secret={{ typetalk_client_secret }}
        topic={{ typetalk_topic }}
        msg='[sensu] restart nginx on {{ ansible_hostname }}'

後は,実際に対象サーバのNginxを止めると,Ansibleが実行されるはずです.
こんな感じで Huboco ちゃんが通知してくれます.

huboco.png

まとめ

今ハマっているSensuとAnsibleを組合せる方法を紹介しました.
今回はNginxでしたが,AnsibleでRailsをデプロイ しているので,こちらも対応させたいなと思います.

また,この記事のhandlerはGitHubで公開しています.
コメント・プルリクお願いします!

8
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?