Alertmanager 構築手順

Alertmanager 構築手順

概要

前回 Node Exporter 構築しました。

今回は監視実施サーバで Alertmanager 構築を実施します。

今回やること 3 行まとめ

  • Alertmanager インストール & 起動スクリプト作成
  • Prometheus 通知条件設定
  • Alertmanager で Slack 通知

Alertmanager の役割

アラートのレベルによって通知先をどの程度の頻度で送信するかを管理します。
あくまで、通知先の管理をします。

実際のアラート条件の設定は Prometheus Server でします。

環境

  • CentOS Linux release 7.3.1611 (Core)

Alertmanager インストール

  • パッケージインストール
1
2
3
4
5
$ cd /usr/local/src
$ sudo wget https://github.com/prometheus/alertmanager/releases/download/v0.5.1/alertmanager-0.5.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xvf alertmanager-0.5.1.linux-amd64.tar.gz
$ cd /usr/local
$ sudo mv alertmanager-0.5.1.linux-amd64 alertmanager
  • シンボリックリンク作成
1
2
3
4
5
6
7
8
$ sudo ln -s /usr/local/alertmanager/alertmanager /bin/alertmanager

$ alertmanager --version

alertmanager, version 0.5.1 (branch: master, revision: 0ea1cac51e6a620ec09d053f0484b97932b5c902)
build user: root@fb407787b8bf
build date: 20161125-08:14:40
go version: go1.7.3

Alert 通知先設定

以下 Slack へ通知設定です。

1
2
3
$ cd /usr/local/alertmanager
$ git clone https://gist.github.com/kenzo0107/71574c2d4d70ba7a9efaa88b4ff1be1b
$ mv 71574c2d4d70ba7a9efaa88b4ff1be1b/alertmanager.yml .
  • alertmanager.yml

slack 通知箇所を適宜変更して下さい。

Alertmanager 起動

とりあえず起動するならこれだけ

1
$ sudo alertmanager -config.file alertmanager.yml

http://alertmanager_server:9093/#/alerts にアクセスすると以下のような画面が表示されます。

Prometheus 同様、Alertmanager も起動スクリプトを作成しそこで起動管理をします。

起動スクリプト作成

  • オプションファイル作成
1
2
3
$ cat << 'EOF' > /usr/local/alertmanager/option
OPTIONS="-config.file /usr/local/alertmanager/alertmanager.yml"
EOF
  • Alertmanager 起動スクリプト
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sudo cat << 'EOF' | sudo tee /usr/lib/systemd/system/alertmanager.service
[Unit]
Description=Prometheus alertmanager Service
After=syslog.target prometheus.alertmanager.service

[Service]
Type=simple
EnvironmentFile=-/usr/local/alertmanager/option
ExecStart=/bin/alertmanager $OPTIONS
PrivateTmp=false

[Install]
WantedBy=multi-user.target
EOF
  • 起動設定
1
2
3
4
$ sudo systemctl daemon-reload
$ sudo systemctl enable alertmanager.service
$ sudo systemctl start alertmanager.service
$ sudo systemctl status alertmanager.service -l

アラート通知条件設定

アラート通知条件は Prometheus Server 側で設定します。

Prometheus Official - ALERTING RULES

サンプルとして以下設定します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cd /usr/local/prometheus-server
$ cat << 'EOF' > alerts.rules

# インスタンスに 5分以上(FOR) アクセスできない場合(IF up == 0)
# severity = "critical" とラベル付けし通知
ALERT InstanceDown
IF up == 0
FOR 5m
LABELS { severity = "critical" }
ANNOTATIONS {
summary = "Instance {{ $labels.instance }} down",
description = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes.",
}

// Prometheus 設定ファイルチェック
$ promtool check-config prometheus.yml

Checking prometheus.yml
SUCCESS: 1 rule files found

Checking alerts.rules
SUCCESS: 1 rules found

Prometheus Server で Alertmanager URL 設定

Prometheus の起動オプションで Alertmanager URL 設定します。

1
-alertmanager.url=http://localhost:9093
1
2
3
4
5
6
7
$ cd /usr/local/prometheus-server
$ cat << 'EOF' > option
OPTIONS="-config.file=/usr/local/prometheus-server/prometheus.yml -web.console.libraries=/usr/local/prometheus-server/console_libraries -web.console.templates=/usr/local/prometheus-server/consoles -alertmanager.url=http://localhost:9093"
EOF

// Prometheus 再起動
$ sudo systemctl restart prometheus.service

注意

今回 Alertmanager は Prometheus Server と同サーバ上に設定しているので

1
http://localhost:9093

となっていますが、ドメインが異なる場合は適宜設定してください。

Prometheus Alerts ページアクセス

設定した通知条件が表示されています。

通知試験

監視対象サーバの node_exporter を停止してみます。

1
$ sudo systemctl stop node_exporter

すると…

Slack に通知が届きました!

http://alertmanager_server:9093/#/alerts にアクセスすると通知内容一覧が表示されます。

以上で簡単ながら
Prometheus からリモートサーバを監視しアラート通知するところまでを
まとめました。

  1. Prometheus でサーバ監視
  2. Node Exporter 構築手順 + Prometheus から AWS オートスケール監視
  3. Alertmanager 構築手順

補足

フロントエンド

Grafana 3.x 以降でデフォルトプラグインで Prometheus をサポートしていたりと
Prometheus のフロントは Grafana が導入しやすく相性が良かったです。

メトリクスを自作したり、Prometheus 独自のクエリを駆使して
様々なメトリクス監視が実現できます。

My alerts.rules

Learning

改めて自身で構築してみて
Line Casual Talks #1, #2 を見直すと非常に理解が深まると思います。

一助になれば何よりです。

以上です。
ご静聴ありがとうございました。

Node Exporter 構築手順 + Prometheus からAWSオートスケール監視

Node Exporter 構築手順 + Prometheus からAWSオートスケール監視

概要

前回 Prometheus Server 構築しました。

今回は 監視対象サーバで Node Exporter 構築を実施します。

今回やること 3 行まとめ

  • Node Exporter インストール
  • Node Exporter 起動スクリプト作成
  • Node Exporter 起動し Prometheus Server からモニタリング

環境

  • CentOS Linux release 7.1.1503 (Core)

Node Exporter インストール

  • パッケージインストール
1
2
3
4
5
$ cd /usr/local/src
$ sudo wget https://github.com/prometheus/node_exporter/releases/download/v0.14.0-rc.1/node_exporter-0.14.0-rc.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xvf node_exporter-0.14.0-rc.1.linux-amd64.tar.gz
$ cd /usr/local
$ sudo mv node_exporter-0.14.0-rc.1.linux-amd64 node_exporter
  • シンボリックリンク作成
1
2
3
4
5
6
7
$ sudo ln -s /usr/local/node_exporter/node_exporter /bin/node_exporter

$ node_exporter --version
node_exporter, version 0.14.0-rc.1 (branch: master, revision: 5a07f4173d97fa0dd307db5bd3c2e6da26a4b16e)
build user: root@ed143c8f2fcd
build date: 20170116-16:00:03
go version: go1.7.4

Node Exporter 起動

とりあえず起動するならこれだけ

1
$ sudo node_exporter

http://node_exporter_server:9100/metrics にアクセスし
取得できる node_exporter で取得しているサーバのメトリクス情報が確認できます。

Prometheus 同様、Node Exporter も起動スクリプトを作成しそこで起動管理をします。

起動スクリプト作成

  • Node Exporter 起動スクリプト
1
2
3
4
5
6
7
8
9
10
11
12
$ sudo cat << 'EOF' | sudo tee /usr/lib/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter

[Service]
Type=simple
ExecStart=/bin/node_exporter
PrivateTmp=false

[Install]
WantedBy=multi-user.target
EOF
  • 起動設定
1
2
3
4
$ sudo systemctl daemon-reload
$ sudo systemctl enable node_exporter.service
$ sudo systemctl start node_exporter.service
$ sudo systemctl status node_exporter.service -l

アクセスしてみる

http://node_exporter_server:9100/metrics にアクセスします。

以下のように表示されていれば Node Exporter 起動成功です。

Prometheus から監視

今回は AWS EC2 インスタンスで起動中の node_exporter によるメトリクス取得設定です。

※ 監視実施サーバに AmazonEC2ReadOnlyAccess をアタッチしたロール設定をする必要があります。
※ 監視対象サーバに 監視対象サーバから 9100 ポート へアクセスできるようにセキュリティグループ設定します。

  • /usr/local/prometheus-server/prometheus.yml 編集

以下設定は region 指定しアクセス権のある Instance のメトリクスを取得します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# my global config
global:
scrape_interval: 15s
evaluation_interval: 15s

external_labels:
monitor: 'codelab-monitor'

rule_files:
# - "first.rules"
# - "second.rules"

scrape_configs:
- job_name: 'prometheus'

static_configs:
- targets: ['localhost:9090']

- job_name: 'node'
ec2_sd_configs:
- region: ap-northeast-1
access_key: ********************
secret_key: ****************************************
port: 9100

タグで監視対象を絞る

全インスタンスを監視であれば上記で問題ありません。

ですが、監視対象をある程度条件で絞りたいケースがあります。
そんな時、Prometheus では relabel_configs でインスタンスの設定タグで絞る方法があります。

  • インスタンスのタグ設定
  • prometheus.yml 設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# my global config
global:
scrape_interval: 15s
evaluation_interval: 15s

external_labels:
monitor: 'codelab-monitor'

rule_files:
# - "first.rules"
# - "second.rules"

scrape_configs:
- job_name: 'prometheus'

static_configs:
- targets: ['localhost:9090']

- job_name: 'node'
ec2_sd_configs:
- region: ap-northeast-1
access_key: ********************
secret_key: ****************************************
port: 9100
relabel_configs:
- source_labels: [__meta_ec2_tag_Stage]
regex: production
action: keep
- source_labels: [__meta_ec2_tag_Role]
regex: web
action: keep
  • prometheus.yml 編集後、再起動
1
$ sudo systemctl restart prometheus.service

Prometheus から node_exporter 起動したサーバを監視できているか確認

http://prometheus_server:9090/consoles/node.html

Up : Yes となっている Node のリンクをクリックすると CPU, Disck のグラフが確認できます。

次回は 監視対象で Alertmanager 構築します。

参照

Prometheus でサーバ監視

Prometheus でサーバ監視

概要

以前 Ansible + Vagrant で Prometheus モニタリング環境構築について書きました。

今回は具体的によくある設定ユースケースを順追って設定していきます。

  1. Prometheus Server 構築
  2. 監視対象で Node Exporter 構築
  3. Alertmanager 構築

今回やること 3 行まとめ

  • Prometheus Server モジュールインストール
  • Prometheus Server 起動スクリプト作成
  • Prometheus Server 起動し自身のサーバモニタリング

Prometheus の設定ファイルについては
全体像を理解した後が良いと思いますので
Node Exporter の設定の後に実施したいと思います。

環境

  • CentOS Linux release 7.3.1611 (Core)

Prometheus インストール

1
2
3
4
5
$ cd /usr/local/src
$ sudo wget https://github.com/prometheus/prometheus/releases/download/v1.4.1/prometheus-1.4.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xvf prometheus-1.4.1.linux-amd64.tar.gz
$ cd /usr/local
$ sudo mv prometheus-1.4.1.linux-amd64 prometheus-server
  • シンボリックリンク作成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sudo ln -s /usr/local/prometheus-server/prometheus /bin/prometheus
$ sudo ln -s /usr/local/prometheus-server/promtool /bin/promtool

$ prometheus --version
prometheus, version 1.4.1 (branch: master, revision: 2a89e8733f240d3cd57a6520b52c36ac4744ce12)
build user: root@e685d23d8809
build date: 20161128-09:59:22
go version: go1.7.3

$ promtool version
promtool, version 1.4.1 (branch: master, revision: 2a89e8733f240d3cd57a6520b52c36ac4744ce12)
build user: root@e685d23d8809
build date: 20161128-09:59:22
go version: go1.7.3

Prometheus 起動

とりあえず起動するならこれだけ

1
$ sudo prometheus -config.file=/usr/local/prometheus-server/prometheus.yml

ただ ↑ これを毎回実行するのは辛いので起動スクリプトを作成して
サーバ再起動時に自動起動したり
systemctl start ... と実行したい。

起動スクリプト作成

  • Prometheus オプションファイル作成
1
2
3
$ cat << 'EOF' > /usr/local/prometheus-server/option
OPTIONS="-config.file=/usr/local/prometheus-server/prometheus.yml -web.console.libraries=/usr/local/prometheus-server/console_libraries -web.console.templates=/usr/local/prometheus-server/consoles"
EOF
  • Prometheus 起動スクリプト
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sudo cat << 'EOF' | sudo tee /usr/lib/systemd/system/prometheus.service
[Unit]
Description=Prometheus Service
After=syslog.target prometheus.service

[Service]
Type=simple
EnvironmentFile=-/usr/local/prometheus-server/option
ExecStart=/bin/prometheus $OPTIONS
PrivateTmp=false

[Install]
WantedBy=multi-user.target
EOF
  • 起動設定
1
2
3
4
$ sudo systemctl daemon-reload
$ sudo systemctl enable prometheus.service
$ sudo systemctl start prometheus.service
$ sudo systemctl status prometheus.service -l

アクセスしてみる

<IP Address>:9090 にアクセスします。
以下のように表示されていれば Prometheus 起動成功です。

Imgur

オプション設定でも設定した、 /usr/local/prometheus-server/consoles の各 html にもアクセスしてみてください。

<IP Address>:9090/consoles/prometheus-overview.html?instance=localhost%3a9090

次回は 監視対象で Node Exporter 構築 します。

リモートサーバとローカルサーバとの差分のあるファイル情報を取得するツール作ってみた

リモートサーバとローカルサーバとの差分のあるファイル情報を取得するツール作ってみた

概要

リモートサーバとローカルサーバとの差分のあるファイル情報を取得するツールを Golang で作成しました。

どんなツールか 3 行まとめ

  1. ローカルワークスペースを元にリモートサーバからディレクトリと拡張子指定し実行ディレクトリ上にファイルをダウンロード
  2. ローカルのワークスペースから実行ディレクトリ上にファイルをコピー
  3. 1,2 で取得したファイルから差分をチェック

利用想定ケース

  • リモートファイルサーバとローカルワークスペースの同期状況が不明瞭である場合

この 1 点のみです。
整備されたデプロイ環境では発生しにくいケースです。

ですが意外と多いです。

それはこんなケース

  • 担当者が退職して引き継がれていない (>_<)
  • ちょっとしたツールだし Git 管理してなかった (>_<)
  • 別の業者さんがサーバにアクセスでき、勝手に編集することがある (>_<)

上記のケースに当たる案件にたまたま担当してしまって
デグレった、バグったとならない為に個人的に作ってました。

補足

デフォルトの対象拡張子は php,tpl,js,css,html を対象としています。
会社で PHP プロジェクトを扱うことが多いので m(_ _)m

あとがき

元々 Python で書いてましたが Go にしたところ
4~5 倍程度パフォーマンスアップしました!

並行処理についても
Python も multiprocessing がありますが
書き易さは Go かなと思いました。

ちなみに

実装に当たってこちら拝読させていただきました。
基礎的な Go 言語の構文や環境構築、
Semaphore を意識した設計はとても参考になりました。

Jenkins が起動しない - Unable to read /var/lib/jenkins/config.xml -

Jenkins が起動しない - Unable to read /var/lib/jenkins/config.xml -

とある午後、Jenkins を再起動したときに出たエラー

1
2
3
4
5
6
7
8
9
10
hudson.util.HudsonFailedToLoad: org.jvnet.hudson.reactor.ReactorException: java.io.IOException: Unable to read /var/lib/jenkins/config.xml
at hudson.WebAppMain$3.run(WebAppMain.java:234)
Caused by: org.jvnet.hudson.reactor.ReactorException: java.io.IOException: Unable to read /var/lib/jenkins/config.xml
at org.jvnet.hudson.reactor.Reactor.execute(Reactor.java:269)
at jenkins.InitReactorRunner.run(InitReactorRunner.java:44)
at jenkins.model.Jenkins.executeReactor(Jenkins.java:912)
at jenkins.model.Jenkins.<init>(Jenkins.java:811)
at hudson.model.Hudson.<init>(Hudson.java:82)
at hudson.model.Hudson.<init>(Hudson.java:78)
at hudson.WebAppMain$3.run(WebAppMain.java:222)

/var/lib/jenkins/config.xml が読み込めない というエラー

/var/lib/jenkins/config.xml の所有者は jenkins:jenkins だけど、なぜ?

と権限周りを諸々試験して直していくと
plugins をディレクトリごと所有者変更すると直りました汗

1
$ sudo chown -R jenkins:jenkins /var/lib/jenkins/plugins

plugin の挙動で何か所有者変更され得るものがあったのか解明せず。

同様の事象の記事を見つけたので参照

「会員登録完了メールが迷惑メールに入っちゃいます」対策

「会員登録完了メールが迷惑メールに入っちゃいます」対策

概要

サイト作りにありがちな設定忘れ
「会員登録完了メールが迷惑メールに入っちゃいます」

SPF レコード設定と DNS の逆引き設定が必要です。

まず DNS 正引きとは

ドメイン — 問合せ —> IP アドレス

以下のようなメールアドレスがあるとします。

info@hogehoge.jp

この hogehoge.jp から IP アドレス を問い合わせるのが 正引き

DNS 逆引きとは

IP アドレス — 問合せ —> ドメイン

IP アドレス から hogehoge.jp を問い合わせるのが 逆引き

SPF レコード

SPF = Sender Policy Framework

メールを送る側のポリシーを設定したフレームワークです。

何故こんなフレームワークがあるの?

送信元偽装なんて簡単にできるから!

1
$ echo "TEST" | sendmail -f aiueo@xxxx.jp -t kenzo.xxxxxx.0107@gmail.com

SPF レコードを設定することの意味

SPF レコード設定する、ということは
送信元の IP アドレス, ドメイン を指定することで
受信先が 送信元メールアドレスと SPF レコード情報に設定している IP, ドメイン情報と一致しているか
わかるようになります。

逆引き設定することの意味

送信元の IP アドレスから割り出したドメインと
逆引き設定された IP に紐づくドメインとを照合し
異なる場合は偽装と判断することができる為です。

Gmail などではこのフィルターが設定されていて
逆引き設定されていないと迷惑メール BOX に入っちゃいます。

SPF レコード設定確認

1
$ dig -t TXT <メールドメイン>
  • 例) gmail.com
1
2
3
$ dig -t TXT gmail.com

gmail.com. 300 IN TXT "v=spf1 redirect=_spf.google.com"
  • 例) yahoo.co.jp
1
2
3
$ dig -t TXT yahoo.co.jp

yahoo.co.jp. 6 IN TXT "v=spf1 include:spf.yahoo.co.jp ~all"

Gmail で SPF レコード設定確認

  • SPF: NEUTRAL の場合、SPF レコードが正しく設定されていません。
  • SPF: PASS の場合、SPF レコードが正しく設定されています。

以上です。

Python ローカルとリモートサーバ上のファイル差分抽出ツール

概要

これまで数社経験してきましたが
必ずといっていいほど存在する、
現状のステータスがわからないサーバ。。

Git 上の master とも差分が激しく生じている状態。。

そんなサーバとローカルの workspace との差分を確認すべく
ツールを作成しました。

今後

今の所、
リモートからファイルをダウンロードする度に SSH のコネクションを張ってしまいパフォーマンス悪い(>_<)

はじめ pysftp で ssh コネクション張ってた方がパフォーマンスよかった気がする。
でも、手軽さを考えたら hostname 指定の方が良かったので
hostname 指定の方向でパフォーマンスを上げていくことを考えます。

ところが
pysftp で実装してみましたが 多段 ssh アクセスの場合がうまくいかず。。
随時解消させていきます。

golang で並行処理を試してパフォーマンスを上げるのも検討します。

CentOS 5系 Neobundle 対応 vim をインストール

概要

CentOS 5 に vim をソースからビルドしようとした所
.configure 実行時にエラー発生

1
2
3
4
no terminal library found
checking for tgetent()... configure: error: NOT FOUND!
You need to install a terminal library; for example ncurses.
Or specify the name of the library with --with-tlib.

terminal library がないと怒られている。

ちなみにこんな流れで vim をソースからダウンロードしビルドしようとしました。

1
2
3
4
5
6
$ wget ftp://ftp.vim.org/pub/vim/unix/vim-7.4.tar.bz2
$ tar xvf vim-7.4.tar.bz2
$ cd vim74
$ ./configure --enable-multibyte --with-features=huge --disable-selinux --prefix='/usr/local/vim-7.4'
$ sudo make install
$ sudo ln -s /usr/local/vim-7.4/bin/vim /usr/bin/vim
  • ncurses-devel インストールし再度実行
1
$ sudo yum install -y ncurses-devel

通りました (;_)

yum でインストールする vim だと Neobundle が利用不可バージョンだった為
ソースからビルドする選択にしました。

程よい rpm があれば教えてください!

zsh vcs_info が使えない問題解決

zsh vcs_info が使えない問題解決

概要

CentOS5 系で yum でインストールした zsh で以下エラー発生

1
precmd: vcs_info: function definition file not found

Version 4.3.6 以上でないと vcs_info は利用できないそう

1
vcs_info is available since zsh-beta, version 4.3.6-dev-0+20080929-1 or later
  • バージョン確認
1
2
3
$ /bin/zsh --version

zsh 4.2.6 (x86_64-redhat-linux-gnu)

なので zsh バージョンアップデートする必要があります。

zsh 5.2 ダウンロード ビルド

1
2
3
4
5
$ cd /usr/local/src
$ wget https://sourceforge.net/projects/zsh/files/zsh/5.2/zsh-5.2.tar.gz/download
$ tar xvjf zsh-5.2.tar.gz
$ cd zsh-5.2
$ ./configure && make && sudo make install

インストールされた zsh バージョン確認

1
2
3
$ /usr/local/bin/zsh --version

zsh 5.2 (x86_64-unknown-linux-gnu)

新たにダウンロードした zsh にシェル変更

1
2
$ echo "/usr/local/bin/zsh" | sudo tee -a /etc/shells
$ chsh -s /usr/local/bin/zsh

それでも、まだ出てくるこのエラー。。

1
precmd: vcs_info: function definition file not found

.zcompdump を削除し zsh を実行し直す

1
2
$ rm ~/.zcompdump
$ exec zsh

.zscompdump はコマンドやその補間関数の定義一覧が記載されているファイルです。

無事エラーが消えました。

Golang 簡易パフォーマンス測定

概要

簡易的なパフォーマンス測定覚書です。
よく使うので備忘録的に保存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import (
"fmt"
"runtime"
"time"
)

func main() {
// CPU数
cpus := runtime.NumCPU()

// 開始時メモリ
var startMemory runtime.MemStats
runtime.ReadMemStats(&startMemory)

// 開始時間
start := time.Now()


// do something


// 経過時間
elapsed := time.Since(start)

// 終了時メモリ
var endMemory runtime.MemStats
runtime.ReadMemStats(&endMemory)

fmt.Printf("実行時間: %f 秒 \n", elapsed.Seconds())
fmt.Printf("CPU: %d \n", cpus)
fmt.Printf("Memory All: %f MB \n", float64(endMemory.Alloc-startMemory.Alloc)/float64(1024*1024))
}