Ubuntu20.04でPrometheusを用いてリソースモニタリング（環境構築編）

# はじめに
## 対象読者
* リソースモニタリングをするために Ubuntu に [Prometheus](https://prometheus.io/) を入れたい

### Prometheus とは
* Go で実装された OSS のリソースモニタリングツール
* PromQL という独自のクエリで CPU や メモリ 使用量等の各種値 ( メトリクス ) を抽出し、グラフにより可視化することができる

## 言い訳
* 2020/04 中旬くらいに下書きしていたのだけれど、そうこうしているうちに Ubuntu 20.04 がリリースされてしまって、やや時代遅れ感が出てしまった……
* 手元の Prometheus サーバの環境を Ubuntu 20.04 にしたらタイトルもそれに合わせて書き直したい
* 【追記 2020/07/08】Ubuntu 20.04 に更新しました。特に問題なく稼働しています！

## 前提
* サブドメインを用意しておく


# サーバ環境の用意
## ConoHa VPS
- Ubuntu 20.0.4
- CPU : 2 core
- メモリ :  2 GB

## パッケージ更新
```sh
apt update
apt upgrade
```

## Let’sEncrypt + nginx
* パッケージインストール

```sh
apt install certbot python-certbot-nginx
```

* インストール
    * 用意しておいたサブドメインを入力する
    * 設定時に SSL force redirect とする

```sh
certbot --nginx
```


## nginx
### 基本チューニング
* 参考
    * [そこそこなスペックのサーバにおけるnginxチューニングの一例](https://qiita.com/Hi_Noguchi/items/9e099420cc3934c43f00)

```nginx:/etc/nginx/nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 20000;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
    
events {
  worker_connections 2048;
  use epoll;
}

# 後略
```

### IP 制限
* 管理画面へのアクセスを許可する ip address を xxx.xxx.xxx.xxx のところに入力

```nginx:/etc/nginx/sites-available/default
# 前略

  location / {
    allow xxx.xxx.xxx.xxx;
    deny all;

# 後略
```


## MySQL
* パッケージインストール

```sh
apt install mysql-server mysql-client
```

* 初期設定

```sh
mysql_secure_installation
```

* [mysqld] 末尾に追記

```conf:/etc/mysql/mysql.conf.d/mysqld.cnf
character-set-server=utf8

[client]
default-character-set=utf8
```

* 設定完了後に再起動

```sh
service mysql restart
```

* charaset の反映確認

```sh
mysql> show variables like "chara%";
```


## ファイアウォール
### UFW
* 設定

```sh
ufw allow 'Nginx Full'
ufw allow from xxx.xxx.xxx.xxx
ufw allow 3306
ufw allow 9090

ufw enable
```


# Prometheus インストール
## 前準備
### Prometheus 動作のためのユーザ/グループ作成
```sh
groupadd prometheus
useradd -d /var/lib/prometheus -g prometheus -s /bin/false -m prometheus
```

## パッケージインストール
### パッケージの取得
* なるべく最新の ver. を取得するようにしてください

```sh
cd /usr/local/src/
wget https://github.com/prometheus/prometheus/releases/download/v2.17.1/prometheus-2.17.1.linux-amd64.tar.gz
tar xf prometheus-2.17.1.linux-amd64.tar.gz
rm prometheus-2.17.1.linux-amd64.tar.gz
```

### path を通す
```sh
cd prometheus-2.17.1.linux-amd64
cp prometheus promtool /sbin/
chown root:root /sbin/prometheus /sbin/promtool
```

### 設定ファイル／データディレクトリの作成
```sh
mkdir /etc/prometheus
mkdir /var/lib/prometheus/data
```

### 設定／サンプルファイル移設
```sh
cp -r prometheus.yml consoles console_libraries /etc/prometheus/
chown -R root:prometheus /etc/prometheus
```

### system ファイル設置
```sh:/etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network-online.target

[Service]
User=prometheus
ExecStart=/sbin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/data --web.console.templates=/etc/prometheus/consoles  --web.console.libraries=/etc/prometheus/console_libraries
ExecStop=/bin/kill -TERM ${MAINPID}
ExecReload=/bin/kill -HUP ${MAINPID}

[Install]
WantedBy=multi-user.target
```

### デーモンのリロード
```sh
systemctl daemon-reload
```

### サービス起動
```sh
systemctl start prometheus.service
```

### ステータス確認
```sh
systemctl status prometheus.service
```

## 参考
* [Ubuntu Weekly Recipe - 第562回　モニタリングツールPrometheusを使う](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0562)


## nginx 設定
* 最終的に以下のようになります
* サブドメイン指定のところは xxxxxx.xxx としていますが、自身のものに置き換えてください

```nginx:/etc/nginx/sites-available/default
upstream prometheus {
  server localhost:9090;
}

server {
  if ($host = xxxxxx.xxx) {
   return 301 https://$host$request_uri;
  } # managed by Certbot
    
  listen 80 ;
  listen [::]:80 ;
  server_name xxxxxx.xxx;
  return 404; # managed by Certbot
}
    
server {
  server_name xxxxxx.xxx; # managed by Certbot
    
  location / {
    allow xxx.xxx.xxx.xxx;
    deny all;

    proxy_redirect          off;
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://prometheus$request_uri;
  }
    
  listen [::]:443 ssl ipv6only=on; # managed by Certbot
  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/xxxxxx.xxx/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/xxxxxx.xxx/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
```

### 設定読み込み
```sh
nginx -s reload
```

### 管理画面の表示確認
* ブラウザで xxxxxx.xxx へアクセスして管理画面が表示されるかどうか確認してください
* 無事に表示されていれば、いったん監視する側は完了です



# 監視される側への設定
## ファイアウォール設定
### ufw
```sh
ufw allow 9100 # node_exporter
```

## 各 exporter 置き場
* https://prometheus.io/download/


## node_exporter
### what
* サーバ内部の各種値（メトリクス）取得
    * メモリ利用
    * ネットワーク利用
    * CPU 利用
    * その他諸々……

### 設置
```sh
cd /usr/local/src/
wget https://github.com/prometheus/node_exporter/releases/download/v1.0.0-rc.0/node_exporter-1.0.0-rc.0.linux-amd64.tar.gz
tar xzf node_exporter-1.0.0-rc.0.linux-amd64.tar.gz
rm node_exporter-1.0.0-rc.0.linux-amd64.tar.gz
```

### リネーム
* init.d 登録したいので ver. 情報は消しておきたい

```sh
mv node_exporter-1.0.0-rc.0.linux-amd64/ node_exporter/
```

### 実行確認
* 動作確認したら ctrl + c で停止させる

```sh
cd node_exporter
./node_exporter
```

### init.d 登録
* /etc/init.d/node_exporter 作成

```sh
cd /etc/init.d
vi node_exporter
```

```sh:/etc/init.d/node_exporter
RETVAL=0
ARGS=""
PROG="node_exporter"
DAEMON=/usr/local/src/node_exporter/${PROG}
PID_FILE=/var/run/${PROG}.pid
LOG_FILE=/var/log/node_exporter.log
LOCK_FILE=/var/lock/subsys/${PROG}
GOMAXPROCS=$(grep -c ^processor /proc/cpuinfo)

start() {
  if check_status > /dev/null; then
    echo "node_exporter is already running"
    exit 0
  fi

  echo -n $"Starting node_exporter: "
  ${DAEMON} ${ARGS} 1>>${LOG_FILE} 2>&1 &
  echo $! > ${PID_FILE}
  RETVAL=$?
  [ $RETVAL -eq 0 ] && touch ${LOCK_FILE}
  echo ""
  return $RETVAL
}

stop() {
  if check_status > /dev/null; then
    echo -n $"Stopping node_exporter: "
    kill -9 "$(cat ${PID_FILE})"
    RETVAL=$?
    [ $RETVAL -eq 0 ] && rm -f ${LOCK_FILE} ${PID_FILE}
    echo ""
    return $RETVAL
  else
    echo "node_exporter is not running"
    rm -f ${LOCK_FILE} ${PID_FILE}
    return 0
  fi
}  

check_status() {
  status -p ${PID_FILE} ${DAEMON}
  RETVAL=$?
  return $RETVAL
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    stop
    start
    ;;
  *)
    N=/etc/init.d/${NAME}
    echo "Usage: $N {start|stop|restart}" >&2
    RETVAL=2
    ;;
esac

exit ${RETVAL}
```

* permission 設定

```sh
chmod 755 node_exporter
```

* init.d 登録

```sh
update-rc.d node_exporter defaults
```

* デーモン起動

```sh
/etc/init.d/node_exporter start
```

* port 9100 で起動確認
    * http://yyyyyy.yyy:9100


* サーバ起動時に実行されるよう、以下に追記

```sh
vi /etc/rc.local
```

```sh:/etc/rc.local
/etc/init.d/node_exporter start
```

### 参考
* [Prometheusで超速監視設定](https://qiita.com/supertaihei02/items/38abb7ff7c1e04db6a6e)
- [Prometheus の基本的な使い方【Node exporter】](https://christina04.hatenablog.com/entry/prometheus-node-exporter)
- [Prometheusのnode_exporterをdaemon化するスクリプト](https://blog.kaznishi.com/post/180529_node_exporter_daemon/)



## mysqld_exporter
### what
* MySQL の各種値（メトリクス）取得
    * コネクション数
    * スレッド数
    * クエリレート
    * などなど

### MySQL ユーザー作成／権限付与
```sh
mysql -u root -p
```

```sh
mysql> CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'password' WITH MAX_USER_CONNECTIONS 3;
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
```

### cnf ファイル作成
```sh
cd /etc
vi .exporter.cnf
```

```conf:.exporter.cnf
[client]
user=exporter
password=password
```

### 設置
```sh
cd /usr/local/src/
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.12.1/mysqld_exporter-0.12.1.linux-amd64.tar.gz
tar xvzf mysqld_exporter-0.12.1.linux-amd64.tar.gz
rm mysqld_exporter-0.12.1.linux-amd64.tar.gz
```

### リネーム
* systemd 登録したいので ver. 情報は消しておきたい

```sh
mv mysqld_exporter-0.12.1.linux-amd64/ mysqld_exporter/
```

### 実行 user 作成
```sh
useradd -rs /bin/false prometheus
```

### systemd ファイル作成
```sh
vi /lib/systemd/system/mysql_exporter.service
```

```sh:mysql_exporter.service
[Unit]
Description=MySQL Exporter

[Service]
User=prometheus
Type=simple
Restart=always
ExecStart=/usr/local/src/mysqld_exporter/mysqld_exporter \
--config.my-cnf /etc/.exporter.cnf \
--collect.auto_increment.columns \
--collect.binlog_size \
--collect.engine_innodb_status \
--collect.engine_tokudb_status \
--collect.global_status \
--web.listen-address=0.0.0.0:9104

[Install]
WantedBy=multi-user.target
```

### systemd reload
```sh
systemctl daemon-reload
```

### status 確認
```sh
systemctl status mysql_exporter
```

### もし必要ならサービス再起動
```sh
systemctl restart mysql_exporter
```

### 参考
* [Complete MySQL dashboard with Grafana & Prometheus](https://devconnected.com/complete-mysql-dashboard-with-grafana-prometheus/)


## blackbox_exporter
### what
* 外形監視


## consul_exporter
### what
* ？　コメントで教えていただけると助かります……


## graphite_exporter
### what
* Graphite を Prometheus 上で使うのに用いられる


## haproxy_exporter
### what
* HAProxy を Prometheus 上で使うのに用いられる


## memcached_exporter
### what
* memcached を Prometheus 上で使うのに用いられる


## pushgateway
### what
* バッチジョブ向けの監視
* Prometheus からのスクレイピングを pushgateway が代わりに受けることになる
* 限定的な利用に留めるべき

### 参考
* [PrometheusのPushgatewayを試す](https://kazuhira-r.hatenablog.com/entry/2019/06/02/235307)


## statsd_exporter
### what
* StatsD を Prometheus で使うために用いられる



# ふたたび監視する側の設定
## prometheus.yaml
### 監視対象の設定
* 監視対象が増えたら targets: のところへ追記していく
* 編集したらリロードすることで設定反映される

```yaml:/etc/prometheus/prometheus.yaml
scrape_configs:
  - job_name: 'node_exporter'
    static_configs:
      - targets: [yyyyyy.yyy:9100]
      - targets: [zzzzzz.zzz:9100]
      # - targets: others ...
  - job_name: 'mysqld_exporter'
    static_configs:
      - targets: [yyyyyy.yyy:9104]
      # - targets: others ...
```

### 記述チェック
* 長いので alias 化しておくと便利そう

```sh
/sbin/promtool check config /etc/prometheus/prometheus.yml
```

### リロード
* こちらも alias 化しておくと便利そう

```sh
killall -HUP prometheus
```

### 参考
- [Prometheusで超速監視設定](https://qiita.com/supertaihei02/items/38abb7ff7c1e04db6a6e)
- [prometheus.ymlの検証方法 - Prometheusドキュメント](http://it-engineer.hateblo.jp/entry/2019/02/17/084933)


# おわりに
## 感想
* 環境構築するにあたって結構やらないといけないことが多いので大変ですが、とはいえそれでも他のリソースモニタツールと比べれば、楽な方かな……？
* 管理画面、軽くてサクサク動くのが嬉しいですね

## 次に
* 以下の記事を書いていく予定です
* Ubuntu20.04でPrometheusを用いてリソースモニタリング（よく使うクエリまとめ編）
* Ubuntu20.04でPrometheusを用いてリソースモニタリング（Alertmanagerで通知編）