Grafana Lokiを使ったKubelet Logging入門

### 結論

Grafanaを使って以下のように`kubelet`の`log`を見れるようになります。
<img width="1250" alt="Alerting__Alert_Rules_-_Grafana.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/27894916-289a-d714-a81d-86ad3abcab12.png">


### KubernetesのLogの概要

- Kubernetesの全体像は以下になります。
![Kubernetes_Logging入門_-_Google_Slides.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/dda6d1df-f7bf-1d3f-ce6f-30d258a17fa8.png)

- Kubernetesを`Log`の観点でまとめてみると以下のようになります。
![Kubernetes_Logging入門_-_Google_Slides.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/1120d7e5-8dab-a998-2323-e3b1d59be7ab.png)

なので、`Log`の観点で見るとPodの`log`と"kubelet"の`log`を抑えるとKubernetes全体のlogを把握することができることがわかります。  


### Grafana Loki とは

- `Loki`は以下のようなアーキテクチャをもつログの収集基盤です。
![Kubernetes_Logging入門_-_Google_Slides.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/844efe88-b844-ca75-0c12-e5897ff6b753.png)

- 特徴としては以下があります。
    - `promtail`というエージェントが各ノードのlogを収集してくれる
    - Grafanaを用いて、各ノードのlogを見ることができる

Lokiの[helm][1]を用いるとPodのlogについては簡単にGrafanaから見れるようになりますが、そのままでは`kubelet(jurnal log)`を見ることができません。今回はその部分について、どうやったらみえるようになるか説明していきます。

[1]:https://github.com/grafana/loki/tree/master/production/helm#loki-helm-chart

- 参考  
    ここまでの話については、[CloudNative Days Tokyo2019][2]登壇時の使用した以下の資料により細かい話を記載しています。
    - [Kubernetes Logging入門][3]　　

![Kubernetes_Logging入門_-_Google_Slides.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/88a8cf1b-a56c-3082-857d-078e4510669a.png)]


[2]:cloudnativedays.jp/cndt2019/
[3]:https://speakerdeck.com/yosshi_/kubernetes-loggingru-men

### Lokiで`journal log`を見るための変更ポイント

- promtailの設定ファイルである`promtail.yaml`について

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: loki-promtail
  labels:
    app: promtail
data:
  promtail.yaml: |
    scrape_configs:
    - job_name: journal 
      journal:
        max_age: 12h
        labels:
          job: systemd-journal
      relabel_configs:
        - source_labels: ['__journal__systemd_unit']
          target_label: 'unit'
```
`job_name`で`journal`を指定することで、`promtail`に備わっている`journal log`を収集する機能を使用することができるようになります。  
その他も含めた注意点を以下に記載します。

|項目名|設定内容|説明|
|:--|:--|:--|
|job_name|journal|この項目を設定することでjournalをscrapeする機能が有効になります|
|journal.max_age|12h|promtail起動時に何時間前までのjournal logを取りに行くかを指定する項目になります。|
|relabel_configs|割愛|garafanaでみる際に絞り込むためのlabelの設定になります。今回はkubeletで絞り込みたいのでunitを指定しています|

- `promtail`の`DeamonSet`について

```yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: loki-promtail
  labels:
    app: promtail
spec:
  selector:
    matchLabels:
      app: promtail
  template:
    metadata:
      labels:
        app: promtail      
    spec:
      containers:
        - name: promtail
          image: "grafana/promtail:v1.2.0-amd64"
          args:
            - "-config.file=/etc/promtail/promtail.yaml"
            - "-client.url=http://loki:3100/loki/api/v1/push"
          volumeMounts:
            - name: config
              mountPath: /etc/promtail
            - name: journal-var
              mountPath: /var/log/journal
              readOnly: true
            - name: journal-run
              mountPath: /run/log/journal
              readOnly: true
      volumes:
        - name: config
          configMap:
            name: loki-promtail
        - hostPath:
            path: /var/log/journal
          name: journal-var
        - hostPath:
            path: /run/log/journal
          name: journal-run  
```

- ここでのポイントは2つです
    - imageについては、`amd64`となっているものを使うこと
    - ノード上のjournalのlogが格納されている場所を`hostPath`mountすること

これらがどうしてそうする必要があるのかについては、最後の方に記載します。


### Grafanaでみる`kubelet`の`log`

- `Data Source`の設定でLokiを選択します。
<img width="1284" alt="Add_data_source__Add_data_source_-_Grafana.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/f051d2c4-8462-a913-989f-47e9970ae23f.png">

- Lokiの接続先を設定します。
<img width="827" alt="Loki__Settings_-_Grafana.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/8cdf3731-553d-c1f8-86c9-6d31ac56e25d.png">

- Exploreから`unit`のlabelを指定して`kubelet`の`log`を絞り込むことができます。 
<img width="1250" alt="Alerting__Alert_Rules_-_Grafana.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/27894916-289a-d714-a81d-86ad3abcab12.png">

Grafanaから簡単に`kubelet`の`log`を見れるようになるので非常に便利です。

### Grafana Lokiと仲良くなる方法
ちょっと気難しいGrafana Lokiと仲良くなっていくための方法を記載します。

#### Grafana Labのblogを定期購読する。
Loki友の基本動作になります。[Grafana Labsのblog][4]はLokiに関する貴重な情報源になります。blogには書かれたかけど、Github上のドキュメントはありませんということも珍しくないので、Lokiの最新情報が知りたい場合はこのblogにたどり着くことになります。  

今回の`Systemd`のsupportについても、[このblogの記事][5]で知りました。

![Loki’s_Path_to_GA__Docker_Logging_Driver_Plugin___Support_for_Systemd___Grafana_Labs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/12c383cb-bc41-01ee-6594-5564f8ec4144.png)


[4]:https://grafana.com/categories/loki/
[5]:https://grafana.com/blog/2019/07/15/lokis-path-to-ga-docker-logging-driver-plugin-support-for-systemd/

#### ドキュメントの通りに動かしてみる

[ドキュメント][6]に書かれている通りに`jurnal log`をscrapeする機能を動かしてみます。

[6]:https://github.com/grafana/loki/blob/master/docs/clients/promtail/configuration.md#example-journal-config
![loki_configuration_md_at_master_·_grafana_loki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/11233dd9-12ef-175c-488b-ad24907e0ac0.png)

今回関係あるのは`scrape_configs`のところだけ書き換えて動かしてみます。  
特にエラーもなくpromtailが起動します。何も起こりません。  
  
何の変化もなく、エラーもはかないです。  

途方にくれます。  

辛いです。  

#### CHANGELOGを確認する

闇雲に探していくのも辛いので、[CHANGELOG][7]の中から`journal log`に関する変更と思われるものをピックアップして、チェックしていきます。

[7]:https://github.com/grafana/loki/blob/master/CHANGELOG.md

![loki_CHANGELOG_md_at_master_·_grafana_loki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/6ee111d7-4525-1378-f7b9-f65411a1a45e.png)

ピックアップした結果

- [#730][730] promtail: Add systemd journal support
- [#921][921] promtail: add "max_age" field to configure cutoff for journal reading
- [#1109][1109] Clarify journal warning
- [#1261][1261] Document systemd journal scraping
- [#1298][1298] pkg/promtail: remove journal target forced path 


[730]:https://github.com/grafana/loki/pull/730
[921]:https://github.com/grafana/loki/pull/921
[1109]:https://github.com/grafana/loki/pull/1109
[1261]:https://github.com/grafana/loki/pull/1261
[1298]:https://github.com/grafana/loki/pull/1298

#### issueをみていく

- [#730][730] promtail: Add systemd journal support  
`journal log`の始まりのissueになります。この時点ではblogに記載内容とだいたい一緒です。

![promtail__Add_systemd_journal_support_by_rfratto_·_Pull_Request__730_·_grafana_loki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/b31a0381-dbbb-ba9a-ae55-744687c54ba5.png)

 `Files changed`とか眺めてみるともう少し、わかります。この機能が入ったのがlokiが`0.3`の頃です。
![promtail__Add_systemd_journal_support_by_rfratto_·_Pull_Request__730_·_grafana_loki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/a01a2031-5f66-0b67-5ccf-8e6dbc998052.png)

- [#921][921] promtail: add "max_age" field to configure cutoff for journal reading  
- "max_age"が追加されたことと、その変更内容がここでわかります。設定しないくてもdefaultで`7h`が設定されることがここでわかります。
　![promtail__add__max_age__field_to_configure_cutoff_for_journal_reading_by_rfratto_·_Pull_Request__921_·_grafana_loki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/bc4d2da9-7388-13f8-3e45-fe4beb8c4f67.png)

- [#1298][1298] pkg/promtail: remove journal target forced path !  
  ここからlog fileの`path`を設定しないと、 defaultで`/var/log/journal`と`/run/log/journal`の両方が設定されることがわかります。

![pkg_promtail__remove_journal_target_forced_path_by_rfratto_·_Pull_Request__1298_·_grafana_loki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/20acf535-a398-9bfa-081a-59eaed8731a3.png)

ここから、どうやってpromtailがノード上のjournal logにアクセスするんだろうというところに思いを馳せると、該当箇所をhostpathでmountすればいいことが類推できます。　　

- 所感  
気づくと「それは、そう」って感じで少し恥ずかしいですが、ハマってる時は、迷走してるので分からないです。  

ただし、まだ動きません。


#### 見落としがないか探す。
行き詰まったので、今まで見た情報を再度丁寧に確認します。すると[CHANGELOG][7]に書いてあるメモが気になります。
![loki_CHANGELOG_md_at_master_·_grafana_loki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/94f2abf4-fb8a-d82d-3671-ce011c65a563.png)

今のversionが`1.2`でこの記述が書かれた頃が`0.3`なので、あまり気にしてなかったのですが、ここを手がかりに調べていくと`journal log`に関する機能がamd64のimageにしか含まれておらず、全ての設定が空振りしていたのでエラーも出さずにpromtailが動作していたことがわかります。(まだ、currentlyだったのか・・・)

これを乗り越えると、こんなふうにlokiで`kubelet`のlogが見れるようになります。

<img width="1250" alt="Alerting__Alert_Rules_-_Grafana.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309176/27894916-289a-d714-a81d-86ad3abcab12.png">

皆さんもLokiと仲良くしてあげてください。