はじめに
SynologyのNASは常時稼動しているので、この上のDockerにPrometheus、AlertmanagerにGrafanaを導入しています。K8sクラスター側では、node-exporterやnginx-prometheus-exporterを導入してWebサーバーの状況も監視するようにしています。
今回は別の環境で構築したk8sクラスターをモニターするために、Ubuntu 18.04上のDocker上にPrometheus+Alertmanager+Grafanaを導入したので、その際のメモを残しておきます。
【2023/07/06追記】
現在はほとんどのクラスターでkube-prometheusを利用してk8sクラスター上でPrometheus等を稼動させています。この記事を書いてからの現在までの経験からは、k8sクラスターの外でWebサーバー等の稼動状況をモニターしてクラスターダウンだけ監視しておけば、細かいデータの収集はk8sクラスター上でPrometheusを稼動させた方が良いと考えています。
References
環境
PrometheusをK8sのPodとして稼動させる例も多いですが、Alertmanagerとの連携を考えるとPodにするわけにはいかないかなと思ったので、適当に独立したDocker上に導入しています。最初は冒頭に書いたようにSynology NAS(DS916+)のDockerサービス上に導入しました。
今回は次のような構成のUbuntu 18.04をターゲットにしてみます。
- Docker on Ubuntu 18.04 (HP ProLiant MicroServer Gen8)
- Prometheus
- Alertmanager
- Grafana
- K8sクラスター内のPodとして稼動しているもの
- node-exporter
- kube-state-metrics
Prometheus+Alertmanager+Grafanaの導入 (Dockerコンテナ)
次のようなMakefileを準備しています。192.168.1.5はUbuntuホストのIPアドレスです。
NAME = prometheus
IMAGE = prom/prometheus:v2.15.0
ALERT_NAME = alertmanager
ALERT_IMAGE = prom/alertmanager:v0.20.0
GRAFANA_NAME = grafana
GRAFANA_IMAGE = grafana/grafana:6.5.2
HOST_IP = 192.168.1.5
.PHONY: run stop start alertmanager-run alertmanager-stop alertmanager-start grafana-run grafana-stop grafana-start
run:
sudo docker run -it -d --name $(NAME) --restart=always \
-p $(HOST_IP):9090:9090 \
-v `pwd`/prometheus.yml:/etc/prometheus/prometheus.yml \
-v `pwd`/alert_rules.yml:/etc/prometheus/alert_rules.yml \
-v `pwd`/prometheus.root.prometheus:/prometheus \
$(IMAGE)
stop:
sudo docker stop $(NAME)
start:
sudo docker start $(NAME)
alertmanager-run:
sudo docker run -it -d --name $(ALERT_NAME) --restart=always \
-p $(HOST_IP):9093:9093 \
-v `pwd`/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
$(ALERT_IMAGE)
alertmanager-stop:
sudo docker stop $(ALERT_NAME)
alertmanager-start:
sudo docker start $(ALERT_NAME)
grafana-run:
sudo docker run -it -d --name $(GRAFANA_NAME) --restart=always \
-p $(HOST_IP):3000:3000 \
-v `pwd`/grafana.var.lib.grafana:/var/lib/grafana \
$(GRAFANA_IMAGE)
grafana-stop:
sudo docker stop $(GRAFANA_NAME)
grafana-start:
sudo docker start $(GRAFANA_NAME)
カレントディレクトリにある prometheus.root.prometheus/ディレクトリ には UID=65534(nobody)、 grafana.var.lib.grafana/ディレクトリ には UID=472 (grafana) のユーザーで書き込めるよう権限を付与する必要があります。
SynologyではGUIからでは存在しないIDに権限を変更することはできなかったので、とりあえずNobodyに書き込み権限を付与しましたが、UbuntuであればUID、GIDを指定して権限が変更できるので、$ sudo chown 472:472 grafana.var.lib.grafana
のように変更しています。
設定ファイルの内容
各Dockerコンテナに-vオプションで渡している設定ファイルの内容は次のとおりです。マウント先がディレクトリの場合には空ディレクトリを指定しています。
global:
scrape_interval: 15s
scrape_timeout: 10s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ["192.168.1.5:9093"]
scheme: http
timeout: 10s
api_version: v1
scrape_configs:
- job_name: prometheus
honor_timestamps: true
scrape_interval: 15s
scrape_timeout: 10s
metrics_path: /metrics
scheme: http
static_configs:
- targets:
- 192.168.1.5:9090
- job_name: kubernetes
scheme: http
metrics_path: /metrics
static_configs:
- targets:
- 192.168.1.51:9100
- 192.168.1.52:9100
- 192.168.1.53:9100
- 192.168.1.54:9100
labels:
group: 'k8s'
- job_name: k8s-system-metrics
scheme: http
metrics_path: /metrics
static_configs:
- targets:
- 192.168.1.47:8080
labels:
group: 'k8s-system'
rule_files:
- "alert_rules.yml"
.scrape_configs.job_nameに指定している/metricsは、自分自身とnode-exporterとkube-state-metricsのサービスを指しています。このサービスの導入に利用したdeployment等のYAMLファイルは次に掲載しています。192.168.1.5[1-4]のIPアドレスは4台のk8sノードを指していて、192.168.1.199:8080はkube-state-metricsのサービスで公開したIP:ポートを指しています。
groups:
- name: fs_alert
rules:
- alert: FilesystemAlert
expr: node_filesystem_avail_bytes{mountpoint="/"} < 8589934592
for: 10m
labels:
severity: critical
type: MiscAlert
annotations:
summary: fs_alert
alert_rules.ymlには複数の定義が書けるので、実際には複数の定義が記述されています。
global:
resolve_timeout: 5m
smtp_from: "user01@example.com"
smtp_smarthost: "example.com:25"
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'web.hook'
routes:
- receiver: "email"
match:
type: MiscAlert
receivers:
- name: "email"
email_configs:
- to: "user01@example.com"
require_tls: false
- name: 'web.hook'
webhook_configs:
- url: 'http://127.0.0.1:5001/'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
.global.smtp_from, .global.smtp_smarthost, .receivers.email_configs.to の各変数には実際のメールアドレス、SMTPホストを指しています。SMTP-AUTHなしで送信できるようになっているので最低限の設定になっています。メールサーバーの管理は、その組織毎のポリシーで様々なので、適切に設定してください。
各プロセスの起動
あとは適切な監視スクリプトを/usr/local/sbinの下に置いて、適宜、このMakefileを呼び出してプロセスを起動しています。
$ make run
$ make alertmanager-run
$ make grafana-run
再起動時に再起動する設定は、--restart=alwaysを追加しました。これによって、docker runの引数にあった*-rm*は削除しています。
$ make stop
などで停止した後は、runではなく、startを使用してください。通常は自動的に再起動するので明示的に*stopタスクを実行しない限り、使用することはないと思います。
監視対象へのnode-exporterの導入
ここからは、K8sクラスターの中から、kubectlコマンドを利用して導入していきます。
あらかじめ $ kubectl create ns monitoring
で、namespaceを作成しています。変更する場合には、YAMLファイル中の、.metadata.namespaceを編集してください。
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
spec:
template:
metadata:
labels:
app: node-exporter
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '9100'
prometheus.io/path: '/metrics'
spec:
containers:
- name: node-exporter
image: quay.io/prometheus/node-exporter:v0.18.1
ports:
- containerPort: 9100
hostNetwork: true
hostPID: true
ファイルが準備できたら、kubectlコマンドで各ノードでnode-exporterを実行させます。
$ sudo kubectl apply -f 01.daemonset.yaml
kube-state-metricsの導入
動かしているのは4ノード構成のK8sクラスターなので、kube-state-metricsはK8sクラスター内で1つだけ稼動すれば十分です。規模の大きな環境でShadingを考慮しなければいけない場合は、実験的機能があるのでドキュメントを参照してください。
導入に必要なYAMLファイルの準備
まずGithubのプロジェクトをcloneして、この中にあるexamples/standard/ディレクトリの中のファイルを利用します。
$ git clone https://github.com/kubernetes/kube-state-metrics.git
$ cd kube-state-metrics/examples/standard/
このディレクトリの中にある設定で通常は問題ないと思いますが、今回はPrometheusはk8sクラスターの外にあるので、外部のPrometheusからアクセスできるようにサービスを公開しています。
$ git diff
diff --git a/examples/standard/service.yaml b/examples/standard/service.yaml
index fcd83797..acf96c31 100644
--- a/examples/standard/service.yaml
+++ b/examples/standard/service.yaml
@@ -7,7 +7,8 @@ metadata:
name: kube-state-metrics
namespace: kube-system
spec:
- clusterIP: None
+ type: LoadBalancer
+ loadBalancerIP: 192.168.1.47
ports:
- name: http-metrics
port: 8080
ディレクトリ全体のYAMLファイルを適用する場合には、-f .
が利用できます。
$ sudo kubectl apply -f .
Prometheus+Grafanaで観察した印象
各Podの状況も把握することができるのでリトライ回数の増加などを検出することができるようになります。https://github.com/kubernetes/kube-state-metrics/tree/master/docs を確認して、deprecatedな項目は利用せずに、stableな項目を利用するようにしたいところです。
ただ項目の種類も多いですし、Podの数に応じて項目数も増えるので、適切に項目と閾値を指定するには少し実験が必要そうです。
node-exporterは通常のUbuntuサーバーの状態を確認するにも便利ですし、nginx-prometheus-exporterを稼動して、nginx上の/stub_statusを/metricsに変換したりさせて、k8sに限らずいろいろなシステム・サービスがモニターできるようになりました。