RKE2クラスタにfluent-bit + loki + grafanaをインストールしてログを収集する

前回loki-stackを構築 したのですが、 あまりカスタマイズできなかった上
loki-stackは非推奨 という情報も見つけたためlokiで再構築してみます。

loki-stackと比べると難しかったです。

構築環境

今回インストールした環境はいつものラズパイRKE2クラスタです。
今回ワーカーノードは2台ですが、3台あった方がいいです。

root@k8s1:~# kubectl get node -o wide
NAME   STATUS   ROLES                       AGE    VERSION           INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
k8s1   Ready    control-plane,etcd,master   134d   v1.28.10+rke2r1   192.168.0.51   <none>        Ubuntu 24.04 LTS     6.8.0-1013-raspi   containerd://1.7.11-k3s2
k8s2   Ready    worker                      11d    v1.28.10+rke2r1   192.168.0.52   <none>        Ubuntu 24.04.1 LTS   6.8.0-1013-raspi   containerd://1.7.11-k3s2
k8s3   Ready    worker                      134d   v1.28.10+rke2r1   192.168.0.53   <none>        Ubuntu 24.04 LTS     6.8.0-1013-raspi   containerd://1.7.11-k3s2

あとオブジェクトストレージは 以前docker-composeで構築したMinIO
残っていたのでそれを使いました。
事前に以下のバケットを作成しておいてください。

  • loki-admin
  • loki-chunks
  • loki-ruler
rancher_fluent-bit_loki_grafana_minio_buckets.png

scalable Lokiをインストールする

いくつかインストール方法がありますがscalable Lokiでインストールします。
こちら を参考に進めます。

まずRancherGUIでリポジトリを追加します。

rancher_fluent-bit_loki_grafana_01.png

次に事前にnamespaceを作成しておきます。

root@k8s1:~# kubectl create ns loki
namespace/loki created

バージョンは6.21.0をインストールします。

rancher_fluent-bit_loki_grafana_02.png

あらかじめ作成したnamespaceにインストールします。

rancher_fluent-bit_loki_grafana_03.png

values.yamlの変更点を説明します。
まずlokiの設定を変更します。
schemaConfigをドキュメントに通りに以下に変更します。

loki:
  schemaConfig:
    configs:
      - from: '2024-04-01'
        index:
          period: 24h
          prefix: loki_index_
        object_store: s3
        schema: v13
        store: tsdb

オブジェクトストレージの設定をします。
ご自身の環境に書き換えてください。

loki:
  storage:
    s3:
      accessKeyId: minio
      secretAccessKey: minio123
      endpoint: http://192.168.0.205:9000
    bucketNames.admin: loki-admin
    bucketNames.chunks: loki-chunks
    bucketNames.ruler: loki-ruler

加えてfluent-bitのエラー対策です。
fluent-bitで以下のエラーが出たので

level=error caller=client.go:430 id=0 component=client host=loki-6-1731942553-gateway.loki.svc.cluster.local msg="final error sending batch" status=401 tenant= error="server returned HTTP status 401 Unauthorized (401): no org id"

こちら を参考にauth_enabledをfalseに変更しました。

loki:
  auth_enabled: false

fluent-bitで以下のワーニングが出たので

level=warn caller=client.go:419 id=0 component=client host=loki-6-1731942553-gateway.loki.svc.cluster.local msg="error sending batch, will retry" status=500 tenant= error="server returned HTTP status 500 Internal Server Error (500): at least 2 live replicas required, could only find 1"

こちら を参考にreplication_factorを1に変更しました。

loki:
  replication_factor: 1

backend、read、writeについて、
ノードが2台しかないのでレプリカ数を2にしました。
また local-path-provisioner でボリュームを永続化します。

backend:
  replicas: 2
  persistence:
    storageClass: local-path
read:
  replicas: 2
  persistence:
    storageClass: local-path
write:
  replicas: 2
  persistence:
    storageClass: local-path

RKE2環境なのでcorednsのserviceの名前が違います。
現環境に合わせて変更します。

global:
  dnsService: rke2-coredns-rke2-coredns

メモリが不足したので以下の設定にしました。

chunksCache:
  allocatedMemory: 4096

これだけ変更したら僕の環境だとデプロイできました。 以下のようになっていると思います。

root@k8s1:~# kubectl get all -n loki
NAME                                            READY   STATUS    RESTARTS   AGE
pod/loki-6-1732536120-chunks-cache-0            2/2     Running   0          2m25s
pod/loki-6-1732536120-gateway-c8575d878-h4tlp   1/1     Running   0          2m25s
pod/loki-6-1732536120-results-cache-0           2/2     Running   0          2m25s
pod/loki-backend-0                              2/2     Running   0          2m25s
pod/loki-backend-1                              2/2     Running   0          2m22s
pod/loki-canary-7jhn6                           1/1     Running   0          2m26s
pod/loki-canary-rt56h                           1/1     Running   0          2m25s
pod/loki-read-f4fcb9bb-2zmt7                    1/1     Running   0          2m25s
pod/loki-read-f4fcb9bb-477xn                    1/1     Running   0          2m24s
pod/loki-write-0                                1/1     Running   0          2m25s
pod/loki-write-1                                1/1     Running   0          2m24s

NAME                                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE
service/loki-6-1732536120-chunks-cache                ClusterIP   None            <none>        11211/TCP,9150/TCP   2m27s
service/loki-6-1732536120-gateway                     ClusterIP   10.43.189.233   <none>        80/TCP               2m27s
service/loki-6-1732536120-query-scheduler-discovery   ClusterIP   None            <none>        3100/TCP,9095/TCP    2m27s
service/loki-6-1732536120-results-cache               ClusterIP   None            <none>        11211/TCP,9150/TCP   2m27s
service/loki-backend                                  ClusterIP   10.43.241.150   <none>        3100/TCP,9095/TCP    2m27s
service/loki-backend-headless                         ClusterIP   None            <none>        3100/TCP,9095/TCP    2m27s
service/loki-canary                                   ClusterIP   10.43.231.11    <none>        3500/TCP             2m26s
service/loki-memberlist                               ClusterIP   None            <none>        7946/TCP             2m27s
service/loki-read                                     ClusterIP   10.43.26.162    <none>        3100/TCP,9095/TCP    2m27s
service/loki-read-headless                            ClusterIP   None            <none>        3100/TCP,9095/TCP    2m27s
service/loki-write                                    ClusterIP   10.43.90.45     <none>        3100/TCP,9095/TCP    2m26s
service/loki-write-headless                           ClusterIP   None            <none>        3100/TCP,9095/TCP    2m27s

NAME                         DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/loki-canary   2         2         2       2            2           <none>          2m26s

NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/loki-6-1732536120-gateway   1/1     1            1           2m26s
deployment.apps/loki-read                   2/2     2            2           2m26s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/loki-6-1732536120-gateway-c8575d878   1         1         1       2m26s
replicaset.apps/loki-read-f4fcb9bb                    2         2         2       2m26s

NAME                                               READY   AGE
statefulset.apps/loki-6-1732536120-chunks-cache    1/1     2m26s
statefulset.apps/loki-6-1732536120-results-cache   1/1     2m26s
statefulset.apps/loki-backend                      2/2     2m26s
statefulset.apps/loki-write                        2/2     2m26s

fluent-bitインストール

次に構築したlokiにログを送ります。
lokiではpromtailを使うのが標準ですが今の現場はfluent-bitが主流なのでこちらを使います。
また、RancherにはLoggingというRancherアプリでfluentdがインストールできますが、
こちら をみた感じlokiのプラグインが 使えなさそうなので、公式版を使います。

使い方は こちら のとおりです。

ではまず、Lokiと同じようにRancherGUIで fluent-bit のリポジトリを作成し、
Chartsでfluent-bitを選択します。

バージョンは0.48.1です。

rancher_fluent-bit_loki_grafana_04.png

こちらもあらかじめNamespaceを作成してそこにインストールします。

root@k8s1:~# kubectl create ns fluent-bit
namespace/fluent-bit created

values.yamlはほぼドキュメントの通りですが、一応書きます。
ドキュメント通りプラグインインストール済みのイメージに変更します。

image:
  repository: grafana/fluent-bit-plugin-loki
  tag: main-e2ed1c0

ドキュメント通り引数を増やします。

  - "-e"
  - "/fluent-bit/bin/out_grafana_loki.so"
  - --workdir=/fluent-bit/etc
  - --config=/fluent-bit/etc/conf/fluent-bit.conf

fluent-bitの設定はOutputだけ変更すれば良さそうです。

  outputs: |
    [OUTPUT]
        Name grafana-loki
        Match kube.*
        Url ${FLUENT_LOKI_URL}
        Labels {job="fluent-bit"}
        LabelKeys level,app
        BatchWait 1
        BatchSize 1001024
        LineFormat json
        LogLevel info
        AutoKubernetesLabels true

ここのurlで使っている環境変数を設定します。
これはgatewayのサービスを指定してあげればOKでした。

env:
  - name: FLUENT_LOKI_URL
    value: http://loki-6-1732536120-gateway.loki.svc.cluster.local/loki/api/v1/push

gatewayのnginxの設定が以下になってます。
実際のpush先はwriteみたいですね。

location = /loki/api/v1/push {
  proxy_pass       http://loki-write.loki.svc.cluster.local:3100$request_uri;
}

以下のようにデプロイされると思います。

root@k8s1:~# kubectl get pod -n fluent-bit
NAME                            READY   STATUS    RESTARTS   AGE
fluent-bit-0-1732539504-9prtn   1/1     Running   0          43s
fluent-bit-0-1732539504-fdvzc   1/1     Running   0          43s
root@k8s1:~# kubectl get all -n fluent-bit
NAME                                READY   STATUS    RESTARTS   AGE
pod/fluent-bit-0-1732539504-9prtn   1/1     Running   0          50s
pod/fluent-bit-0-1732539504-fdvzc   1/1     Running   0          50s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/fluent-bit-0-1732539504   ClusterIP   10.43.140.101   <none>        2020/TCP   50s

NAME                                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/fluent-bit-0-1732539504   2         2         2       2            2           <none>          50s

grafanaでログを表示する

では収集したログを表示してみます。
すでにRancher MonitoringでデプロイされたGrafanaがいるのでそれを使います。
データソースはカスタマイズできない ようなのでGrafanaのWebGUIで追加します。
Monitoringをインストールしてなかったらインストールしてください。
ラズパイでも動くと思います。

MonitoringからGrafanaを開きます。

rancher_fluent-bit_loki_grafana_05.png

adminでサインインしたらData sourcesを開いてadd new data sourceをクリックします。

rancher_fluent-bit_loki_grafana_06.png

Lokiを選択します。

rancher_fluent-bit_loki_grafana_07.png

URLにはGatewayのService名を入力してください。

rancher_fluent-bit_loki_grafana_08.png

Save and testで接続に成功したらOKです。

rancher_fluent-bit_loki_grafana_09.png

ではexploreでログを表示してみます。
defaultのnamespaceでNGINXを起動してみたところ以下のログが表示されました。

rancher_fluent-bit_loki_grafana_10.png

無事ログ収集できているようですね。
けどこれloki-stackの時に比べて見にくいな。
ひとまず動くようになったので色々カスタマイズを試してみたいと思います。