Kubernetes + Grafana Loki + Promtail で任意の VM のログ収集する

# 目的

システムを安定稼働させるためにログの監視は重要な項目である。
ログを収集することでシステムトラブルや不審な操作・動作の検知に役立ち、その解決の一助とできる。
今回は前回記事である [Loki + NFS で Kubernetes 上のログ取得](https://qiita.com/yoshi_1010/items/a009f5394aacef046e21) の続きとして、任意の VM に Promtail をインストールし、VM のログも収集可能にする。

ログの保存には NFS サーバを用いる。
Loki としては保存先に NFS サーバを用いることは非推奨であるが、Kubernetes 含めすべてローカルの環境を利用するケースでも Loki の動作を確認することを目的に NFS サーバを用いる。

- 第 1 章: [Loki + NFS で Kubernetes 上のログ取得](https://qiita.com/yoshi_1010/items/a009f5394aacef046e21)

NFS をボリュームとして利用し、Loki をインストールする。

- 第 2 章: この章

Promtail をインストールし、今回インストールした Loki に集約する。

# 構成

Linux Machine (Ubuntu 20.04) を 3 台を使用し、下記の構成で Kubernetes Cluster を構築した。
Kubernetes 上にはすでに Prometheus + Grafana + Loki が動作している状態である。
また、Linux Machine (Ubuntu 20.04) を NFS サーバ用とログ収集用の任意の VM 用に 1 台ずつ準備する。

- Kubernetes (Master Node)
	- 10.100.2.220
- Kubernetes (Worker Node)
	- 10.100.2.221
	- 10.100.2.222
- NFS サーバ
    - 10.100.2.170
- ログ収集用の任意の VM 
    - 10.100.3.10

# 手順

## Helm インストール

- 実行場所
  - Kubernetes (Master Node) 

Kubernetes のパッケージマネージャである Helm をインストールする。

手順は 第 1 章: [Loki + NFS で Kubernetes 上のログ取得](https://qiita.com/yoshi_1010/items/a009f5394aacef046e21) で記載しているため、省略する。

## Promtail

- 実行場所
  - Kubernetes (Master Node) 

Loki がサポートしているログ収集のツール用のクライアントソフトウェアには Docker Driver, Fluentd, Logstash などがある。
この中から今回は Promtail を導入する。
Promtail は Promtail が実行されているノードと同じノード上で実行されている Pod からログを自動的に収集するように構成できる。
そのため、Kubernetes を実行する場合に最適なクライアントである。
また、Promtail はホストパスが指定されたすべてのファイルからログを追跡するように構成できるため、ベアメタル上で最適なクライアントでもある。

今回は Kubernetes と任意の VM の両方でログを取得するため、Promtail を導入する。

### Helm リポジトリの追加

Helm リポジトリを追加する。

```
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
```

### 設定ファイル作成

Promtail 起動時に使用する設定ファイルを作成する。

```
cat << _EOF_ > loki-values-promtail.yaml
extraPorts:
  syslog:
    name: tcp-syslog
    containerPort: 31002
    service:
      port: 31002    
      type: NodePort
      nodePort: 31002  

config:
  snippets:
    extraScrapeConfigs: |
      - job_name: syslog
        syslog:
          listen_address: 0.0.0.0:31002
          listen_protocol: tcp
          idle_timeout: 60s
          label_structured_data: yes
          labels:
            job: syslog
        relabel_configs:
          - source_labels:
              - __syslog_message_hostname
            target_label: host
_EOF_
```

### インストール

Promtail をインストールする。
インストール時には `--namespace` で Prometehus + Grafana + Loki が動作しているネームスペースと同じものを指定する。

```
helm install  --namespace monitoring --values loki-values-promtail.yaml promtail  grafana/promtail
```

確認する。

```
$ kubectl get all -n monitoring | grep promtail
pod/promtail-mjrjt                                           1/1     Running   0          76m
pod/promtail-t4jn4                                           1/1     Running   0          76m
service/promtail-syslog                           NodePort    10.99.220.27     <none>        31002:31002/TCP                 76m
daemonset.apps/promtail                                  2         2         2       2            2           <none>                   76m
```

## ログ収集

- 実行場所
  - ログ収集用の任意の VM  

VM 上の syslog ファイルを Loki に転送する。

### Promtail インストール

Promtail バイナリも Loki と同じ場所から入手する。
必要に応じてバージョンの変更する。

```
wget https://github.com/grafana/loki/releases/download/v2.8.0/promtail-linux-amd64.zip
mkdir -p /opt/promtail
unzip promtail-linux-amd64.zip
mv promtail-linux-amd64 /opt/promtail
```

### 設定ファイル作成

Promtail の設定ファイルを作成する。
clients.url には Loki に接続するための URL を指定する。
今回は [Kubernetes + Grafana Loki + NFS のインストール](https://qiita.com/yoshi_1010/private/a009f5394aacef046e21) の Loki インストール時に設定した gateway.serivce として NodePort の 31001 ポートを開けているため、`10.100.2.220:31001` を指定している。
scrape_configs 内の labels では Grafana 等で確認する際などに利用するラベルや収集するファイルを指定する。

```
$  cat << _EOF_ > /opt/promtail/promtail-config.yaml
server:
  http_listen_port: 9080
  grpc_listen_port: 0
  grpc_server_max_recv_msg_size: 15728640
  grpc_server_max_send_msg_size: 15728640

positions:
  filename: /opt/promtail/positions.yaml

clients:
 - url: http://10.100.2.220:31001/loki/api/v1/push

scrape_configs:
- job_name: app_log
  static_configs:
  - targets:
      - localhost
    labels:
      job: test-10.100.3.10
      __path__: /var/log/syslog
_EOF_
```

### サービス化

Promtail をサービスとして起動させ、バックグラウンドで実行し続けることができるようにする。

```
$  cat << _EOF_ > /etc/systemd/system/promtail.service
[Unit]
Description=promtail
Documentation=https://github.com/grafana/loki/releases
After=network.target
[Service]
User=root
Type=simple
ExecStart=/opt/promtail/promtail-linux-amd64 --config.file=/opt/promtail/promtail-config.yaml
Restart=on-failure
[Install]
WantedBy=multi-user.target
_EOF_
```

作成した Promtail サービスを起動する。

```
systemctl start promtail.service
systemctl enable promtail.service
```

起動後、エラーが発生していないか確認する。

```
$ systemctl status promtail.service
● promtail.service - promtail
     Loaded: loaded (/etc/systemd/system/promtail.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2023-08-18 06:54:12 UTC; 2h 3min ago
       Docs: https://github.com/grafana/loki/releases
   Main PID: 12330 (promtail-linux-)
      Tasks: 8 (limit: 4721)
     Memory: 15.3M
        CPU: 38.298s
     CGroup: /system.slice/promtail.service
             └─12330 /opt/promtail/promtail-linux-amd64 --config.file=/opt/promtail/promtail-config.yaml
```

ここまで実行できれば、Grafana から VM の syslog を確認できる。
ブラウザから Grafana に接続し、Explore の [Label filters] で `job: test-10.100.3.10` の組み合わせで検索することで確認できる。

# まとめ

前回と今回で Kubernetes + Grafana Loki + Promtail + NFS の環境を構築した。
これにより、任意の VM や Pod のログを取得し、NFS サーバに保存するところまで達成できた。

今回実施した内容の拡張として、Loki のマイクロサービス化や Kubernetes 基盤拡張に伴う Loki サービスの拡張対応も考えている。
また、今回は動作させることを念頭においたため、Loki 等の動作時に細かくパラメータを設定していない。
そのため、取得したログの圧縮保存やアーカイブ化の自動化や保存期間の設定といった Loki を動作させるパラメータを調整・設定し、セキュリティに配慮した効率の良いログ保存ができればよいとも考える。