はじめに
Kubernetesで監視を行う際の代表的なツールのひとつとしてPrometheusがあります。PrometheusではExporterを介してメトリクスを受け取り、グラフ等で表示することができます。Exporterは様々な種類が公開されていますが、今回はその中からSNMP Exporterを使ってメトリクスを出力し、Prometheusの画面上で確認できるまでをやってみました。
SNMP Exporterとは
SNMP Exporterは、SNMP(Simple Network Management Protocol)によって集められた情報を、Prometheusで見れるようにしてくれるツールです。公式ページでは2つのツールを紹介しており、ひとつはSNMP Exporter自身、もうひとつはExporterで使用するsnmp.yml
を、ユーザの指定する情報に基づいて出力してくれるSNMP Exporter Config Generatorです。Generatorを使用する理由として、デフォルトのsnmp.yml
は行数も多く内容も複雑なため、手書きでの修正を推奨されていないからです。
今回はお試しということで非常に単純な設定しか入れないため、generatorは使用せず、手で修正したsnmp.yml
を使用しました。generatorの利用方法についてはまた後日紹介します。
環境
今回検証を行うのは、以下のような環境にあります。こちらの記事で環境構築について紹介しているので、詳細はそちらをご覧ください。
- OS: Centos 7
- Kubernetes version: 1.13.1
- User: 以下の作業は全てrootユーザで実行しています。
今回は<k8s-node-1>ノードにNet-SNMPを導入し、SNMP-Exporterを介してメトリクスを受け取り、それをPrometheusで表示することを目指します。
Net-SNMPの設定
デフォルトの状態ではSNMPを利用できなかったため、Net-SNMPをインストールしてSNMPが利用できるようにします。
Net-SNMPの導入自体はとてもシンプルです。まずはyumコマンドを用いてインストールします。
yum install -y net-snmp net-snmp-utils
次にコンフィグファイルに当たる/etc/snmp/snmpd.conf
を編集します。こちらは行数が多いですが、関連するのは以下の箇所になります。
# 行数を確認する [root@k8s-node-1 ~]# wc -l /etc/snmp/snmpd.conf 462 /etc/snmp/snmpd.conf # コメントアウトされていない箇所を抜き出す [root@k8s-node-1 ~]# egrep -v "^#|^$" /etc/snmp/snmpd.conf com2sec notConfigUser default public group notConfigGroup v1 notConfigUser group notConfigGroup v2c notConfigUser view systemview included .1.3.6.1.2.1.1 view systemview included .1.3.6.1.2.1.25.1.1 access notConfigGroup "" any noauth exact systemview none none syslocation Unknown (edit /etc/snmp/snmpd.conf) syscontact Root <root@localhost> (configure /etc/snmp/snmp.local.conf) dontLogTCPWrappersConnects yes [root@k8s-node-1 ~]# # 説明文と行番号も含めて出力する (説明文を追記しています) [root@k8s-node-1 ~]# less -N /etc/snmp/snmpd.conf ~ 省略 ~ 37 #### 38 # First, map the community name "public" into a "security name" 39 40 # sec.name source community 41 com2sec notConfigUser default public # com2sec: セキュリティを定義 ## sec.name: セキュリティ名 ## source: 送信元IPアドレス ## community: コミュニティ名 43 #### 44 # Second, map the security name into a group name: 45 46 # groupName securityModel securityName 47 group notConfigGroup v1 notConfigUser 48 group notConfigGroup v2c notConfigUser # group: com2secで定義したセキュリティ名と紐づくグループ名を定義 ## groupName: グループ名 ## securityModel: セキュリティモデル。{v1|v2c|usm}のいずれかを選択 ## securityName: セキュリティ名。com2secで定義したものを入力 50 #### 51 # Third, create a view for us to let the group have rights to: 52 53 # Make at least snmpwalk -v 1 localhost -c public system fast again. 54 # name incl/excl subtree mask(optional) 55 view systemview included .1.3.6.1.2.1.1 56 view systemview included .1.3.6.1.2.1.25.1.1 # view: SNMPで参照するMIBツリーの参照許可範囲を指定 ## name: ビュー名 ## incl/excl: {include|exclude}から選択 ## subtree: MIBツリーの参照範囲 58 #### 59 # Finally, grant the group read-only access to the systemview view. 60 61 # group context sec.model sec.level prefix read write notif 62 access notConfigGroup "" any noauth exact systemview none none # access: SNMPへのアクセス許可対象を指定 ## group: 上のgroupで定義したグループ名 ## context: {any|v1|v2c|usm|tsm|ksm}から選択 ## sec.model: {any|v1|v2c|usm}から選択 ## sec.level: {noauth|auth|priv}から選択 ## prefix: {exact|prefix}から選択 ## read: 読み取り権限を与えるビュー名を入力 ## write: 書き込み権限を与えるビュー名を入力 (なければnone) ## notif: 通知するビュー名を入力 (なければnone) ### context、sec.model、sec.level、prefixはSNMPv3で使用するパラメータ ~ 中略 ~ 155 ############################################################################### 156 # System contact information 157 # 158 159 # It is also possible to set the sysContact and sysLocation system 160 # variables through the snmpd.conf file: 161 162 syslocation Unknown (edit /etc/snmp/snmpd.conf) 163 syscontact Root <root@localhost> (configure /etc/snmp/snmp.local.conf) # syslocation: システムの存在する場所を入力 ## 自由記述 # syscontact: システムの連絡先を入力 ## 上の例では「Root」というユーザの連絡先が「root@localhost」であることを示す ~ 中略 ~ 176 ############################################################################### 177 # Logging 178 # 179 180 # We do not want annoying "Connection from UDP: " messages in syslog. 181 # If the following option is commented out, snmpd will print each incoming 182 # connection, which can be useful for debugging. 183 184 dontLogTCPWrappersConnects yes # dontLogTCPWrappersConnects: この行をコメントアウトすると、snmpdがアクセスするたびに、その情報がログに出力されます。デバッグ等に有用です。 [root@k8s-node-1 ~]#
なお、{v1|v2c|usm}は、それぞれ{SNMPv1|SNMPv2|SNMPv3}に対応しています。
今回はデフォルトの設定から以下のように変更しました。
# 変更後のsnmpd.confからコメントアウトの箇所以外を出力 [root@k8s-node-1 ~]# egrep -v "^#|^$" /etc/snmp/snmpd.conf com2sec local localhost public com2sec mynet 10.0.0.0/24 public group MyGroup v1 local group MyGroup v1 mynet view all included .1 80 access MyGroup "" any noauth exact all all none syslocation Centos 7, Linux Server syscontact root <root@localhost> dontLogTCPWrappersConnects yes [root@k8s-node-1 ~]# # 差分を確認 [root@k8s-node-1 ~]# diff /etc/snmp/snmpd.conf.bk /etc/snmp/snmpd.conf 41c41,43 < com2sec notConfigUser default public --- > #com2sec notConfigUser default public > com2sec local localhost public > com2sec mynet 10.0.0.0/24 public 47,48c49,52 < group notConfigGroup v1 notConfigUser < group notConfigGroup v2c notConfigUser --- > #group notConfigGroup v1 notConfigUser > #group notConfigGroup v2c notConfigUser > group MyGroup v1 local > group MyGroup v1 mynet 55,56c59,61 < view systemview included .1.3.6.1.2.1.1 < view systemview included .1.3.6.1.2.1.25.1.1 --- > #view systemview included .1.3.6.1.2.1.1 > #view systemview included .1.3.6.1.2.1.25.1.1 > view all included .1 80 62c67,68 < access notConfigGroup "" any noauth exact systemview none none --- > #access notConfigGroup "" any noauth exact systemview none none > access MyGroup "" any noauth exact all all none 162,163c168,172 < syslocation Unknown (edit /etc/snmp/snmpd.conf) < syscontact Root <root@localhost> (configure /etc/snmp/snmp.local.conf) --- > #syslocation Unknown (edit /etc/snmp/snmpd.conf) > #syscontact Root <root@localhost> (configure /etc/snmp/snmp.local.conf) > > syslocation Centos 7, Linux Server > syscontact root <root@localhost> [root@k8s-node-1 ~]#
- com2secではKubernetesクラスターのプライベートIPアドレスレンジ (10.0.0.0/24)を指定しています。
- viewではすべてのMIBツリー情報を見せるように設定しています。
- 今回はSNMPv1のみ使用しました。
コンフィグファイルを編集した後、サービスの起動を行います。
[root@k8s-node-1 ~]# systemctl start snmpd [root@k8s-node-1 ~]# systemctl status snmpd ● snmpd.service - Simple Network Management Protocol (SNMP) Daemon. Loaded: loaded (/usr/lib/systemd/system/snmpd.service; disabled; vendor preset: disabled) Active: active (running) since Sat 2019-01-12 04:20:57 UTC; 6s ago Main PID: 12810 (snmpd) Tasks: 1 Memory: 4.2M CGroup: /system.slice/snmpd.service └─12810 /usr/sbin/snmpd -LS0-6d -f Jan 12 04:20:57 k8s-node-1 systemd[1]: Starting Simple Network Management Protocol (SNMP) Daemon.... Jan 12 04:20:57 k8s-node-1 snmpd[12810]: Duplicate IPv4 address detected, some interfaces may not be visible in IP-MIB Jan 12 04:20:57 k8s-node-1 snmpd[12810]: NET-SNMP version 5.7.2 Jan 12 04:20:57 k8s-node-1 systemd[1]: Started Simple Network Management Protocol (SNMP) Daemon.. [root@k8s-node-1 ~]#
ここでDuplicate IPv4 address detected, some interfaces may not be visible in IP-MIB
というメッセージが表示されていますが、原因がわかりませんでした。こちらを参照すると、特に気にする必要もなさそうです。
ひとまずこれで、監視対象サーバがSNMPを動かせるようになったので、今度は監視サーバ側 (k8s-master)からSNMPを見れるかを確認します。ここではsnmpwalkコマンドを用いて、MIB値を取得できるかを確認します。
[root@k8s-master ~]# yum install -y net-snmp net-snmp-utils [root@k8s-master ~]# snmpwalk -v 1 -c public 10.0.0.235 | wc -l 4451 [root@k8s-master ~]# snmpwalk -v 1 -c public 10.0.0.235 | head SNMPv2-MIB::sysDescr.0 = STRING: Linux k8s-node-1 3.10.0-957.1.3.el7.x86_64 #1 SMP Thu Nov 29 14:49:43 UTC 2018 x86_64 SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (1350) 0:00:13.50 SNMPv2-MIB::sysContact.0 = STRING: root <root@localhost> SNMPv2-MIB::sysName.0 = STRING: k8s-node-1 SNMPv2-MIB::sysLocation.0 = STRING: Centos 7, Linux Server SNMPv2-MIB::sysORLastChange.0 = Timeticks: (3) 0:00:00.03 SNMPv2-MIB::sysORID.1 = OID: SNMP-MPD-MIB::snmpMPDCompliance SNMPv2-MIB::sysORID.2 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance SNMPv2-MIB::sysORID.3 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance [root@k8s-master ~]#
確かにk8s-node-1
から取得できているようです。
SNMP-Exporterの設定
続いてSNMP Exporterの設定を行います。SNMP Exporterの公式ページではBinaryファイルの起動方法が記載されているので、今回はそれに従います。まずは公式githubのreleaseページから圧縮ファイルをダウンロードします。
wget https://github.com/prometheus/snmp_exporter/releases/download/v0.14.0/snmp_exporter-0.14.0.linux-amd64.tar.gz tar xvzf snmp_exporter-0.14.0.linux-amd64.tar.gz cd snmp_exporter-0.14.0.linux-amd64
デフォルト設定でよければ、あとは./snmp_exporter
と入力すれば起動し、http://<k8s-masterのグローバルIPアドレス>:9116
にアクセスすると以下のような画面が表示されます。
さらにhttp://<k8s-masterのグローバルIPアドレス>:9116/metrics
にアクセスすると、取得するメトリクスが表示されます。
これでSNMP Exporter自体は起動できましたが、監視対象サーバのSNMPを受け取るための設定を行います。
SNMP Exporterのコンフィグファイルに当たるsnmp.yml
の中身を一部だけ見てみます (各ポイントの説明を追記しています)。
# モジュール名 cisco_wlc: # walk: snmpwalkするOID walk: - 1.3.6.1.2.1.2 - 1.3.6.1.2.1.31.1.1 ~ 中略 ~ # metrics: メトリクスの名前とOIDとの紐付けを定義 metrics: - name: ifNumber oid: 1.3.6.1.2.1.2.1 type: gauge ~ 中略 ~
上記のように、モジュール名、walk、metricsなどの値を定義します。
[20190113追記]
snmp.yml
のフォーマットに関して公式ページのこちらとこちらに説明されていました。こちらに簡単に抜粋しておきます。
- auth: {community|user|security_level}などなど、様々なauth/versionに関するオプションがあります。
- walk: walkするOIDサブツリーのリスト
- get: 直接getするOIDのリスト
- metrics: 抽出するメトリクスのリスト
今回snmp.yml
に追加した設定は以下になります。
[root@k8s-master snmp_exporter-0.14.0.linux-amd64]# diff snmp.yml snmp.yml.org 2,17d1 < linux: < version: 2 < auth: < community: public < walk: < - 1.3.6.1.2.1.1.5.0 < - 1.3.6.1.2.1.2.1.0 < metrics: < - name: sysName < oid: 1.3.6.1.2.1.1.5.0 < type: gauge < < - name: ifNumber < oid: 1.3.6.1.2.1.2.1.0 < type: gauge < [root@k8s-master snmp_exporter-0.14.0.linux-amd64]#
これでSNMP Exporterの設定は完了したので、SNMP Exporterを起動します。
[root@k8s-master snmp_exporter-0.14.0.linux-amd64]# ./snmp_exporter & [1] 11915 [root@k8s-master snmp_exporter-0.14.0.linux-amd64]# INFO[0000] Starting snmp exporter (version=0.14.0, branch=HEAD, revision=da73490e051012714ee36cbf69d74dd41e21d4fb) source="main.go:139" INFO[0000] Build context (go=go1.11.2, user=root@86242397dc77, date=20181204-15:41:19) source="main.go:140" INFO[0000] Listening on :9116 source="main.go:226" [root@k8s-master snmp_exporter-0.14.0.linux-amd64]#
Prometheusの設定
最後にPrometheusの設定を行います。Prometheusの起動方法等はこちらの記事で紹介しています。ここではprometheus.yml
ファイルの変更箇所を紹介します。
[root@k8s-master prometheus-2.6.0.linux-amd64]# prometheus.yml # my global config global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). # Alertmanager configuration alerting: alertmanagers: - static_configs: - targets: # - alertmanager:9093 # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. rule_files: # - "first_rules.yml" # - "second_rules.yml" # A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: 'prometheus' # metrics_path defaults to '/metrics' # scheme defaults to 'http'. static_configs: - targets: ['localhost:9090'] # ここからが追加箇所 - job_name: snmp static_configs: - targets: ['localhost:9116'] [root@k8s-master prometheus-2.6.0.linux-amd64]#
追加したものは単純にSNMP Exporterの接続先を指定しただけです。
上記を追加したのち、Prometheusを起動します。
[root@k8s-master prometheus-2.6.0.linux-amd64]# ./prometheus --config.file=prometheus.yml & [2] 13936 [root@k8s-master prometheus-2.6.0.linux-amd64]# level=info ts=2019-01-12T04:42:42.359459537Z caller=main.go:243 msg="Starting Prometheus" version="(version=2.6.0, branch=HEAD, revision=dbd1d58c894775c0788470944b818cc724f550fb)" level=info ts=2019-01-12T04:42:42.359544708Z caller=main.go:244 build_context="(go=go1.11.3, user=root@bf5760470f13, date=20181217-15:14:46)" level=info ts=2019-01-12T04:42:42.359569444Z caller=main.go:245 host_details="(Linux 3.10.0-957.1.3.el7.x86_64 #1 SMP Thu Nov 29 14:49:43 UTC 2018 x86_64 k8s-master (none))" level=info ts=2019-01-12T04:42:42.359612736Z caller=main.go:246 fd_limits="(soft=1024, hard=4096)" level=info ts=2019-01-12T04:42:42.359632891Z caller=main.go:247 vm_limits="(soft=unlimited, hard=unlimited)" level=info ts=2019-01-12T04:42:42.361882876Z caller=main.go:561 msg="Starting TSDB ..." level=info ts=2019-01-12T04:42:42.362027192Z caller=web.go:429 component=web msg="Start listening for connections" address=0.0.0.0:9090
これでPrometheusが見れる状態になりましたので、http://<k8s-masterのグローバルIPアドレス>:9090
にアクセスします。アクセスした画面からStatus
→Targets
にアクセスすると、prometheus.yml
で設定したjob_name: snmp
が確認できます。
さらに最初の画面に戻り、Expression
から「snmp」と入力すると、SNMPの幾つかのメトリクスが表示され、取得できていることが確認できます。
snmp.yml
で設定したMIB値のものが取れていないように見えますので、設定に誤りがあるかもしれません。。。引き続き調べてまいります。
参考リンク
snmpd.conf - ファイルのフォーマットと規約の説明 - Linux コマンド集 一覧表