Kuberentesノードのログ監視

テクノロジー

はじめに

 サイオステクノロジーの中島です。Kubernetesで負荷監視ができるならば、ログ監視もということで、ログ監視を行うことの一例として、Promtail+Loki+Grafanaでログ監視できる環境を作成してみようと思います。

ソフト概要

 Kubernetesでログ監視を実現するために必要なソフトとして、Kubernetes内のノードで出力されたログを監視し、ログ集積に送信するためのソフトであるPromtail、ログ集積するためのLoki、ログ集積されたデータを視覚的に見やすくするためのソフトGrafanaを実行する必要があります。これらソフトの相関図を以下の図にしまします。

図 ログ監視起動Pod相関図

Kubernetes動作

 実際に、Kubernetes内で動作させるためのYAMLファイルを、以下ファイル構成で作成します。

./
├── config
│    ├── loki.yaml
│    └── promtail.yaml
└── pod
      ├── grafana.yaml
      ├── loki.yaml
      └── promtail.yaml

 以下に、上記フォルダ構成のファイルの中身を下記に記載します。

・config/loki.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: loki-configmap
data:
  local-config.yaml: |
    auth_enabled: false
    server:
      http_listen_port: 3100
      ingester:
        lifecycler:
          address: 127.0.0.1
          ring:
            kvstore:
              store: inmemory
            replication_factor: 1
          final_sleep: 0s
      chunk_idle_period: 5m
      chunk_retain_period: 30s
      max_transfer_retries: 0
    schema_config:
      configs:
        - from: 2018-04-15
          store: boltdb
          object_store: filesystem
          schema: v11
          index:
            prefix: index_
            period: 168h
    storage_config:
      boltdb:
        directory: /loki/index
      filesystem:
        directory: /loki/chunks
    limits_config:
      enforce_metric_name: false
      reject_old_samples: true
      reject_old_samples_max_age: 168h
    chunk_store_config:
      max_look_back_period: 0s
    table_manager:
      retention_deletes_enabled: false
      retention_period: 0s

・config/promtail.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: promtail-configmap
data:
  config.yaml: |
    server:
      http_listen_port: 9080
      grpc_listen_port: 0
    positions:
      filename: /tmp/positions.yaml
    clients:
      - url: http://loki:3100/loki/api/v1/push
    scrape_configs:
    - job_name: system
      static_configs:
      - targets:
          - localhost
        labels:
          job: varlogs
          __path__: /var/log/*log
    - job_name: journal
      journal:
        max_age: 12h
        path: /var/log/journal
        labels:
          job: system-journal
      relabel_configs:
        - source_labels: ['__journal__systemd_unit']
          target_label: 'unit'
        - source_labels:
          - __journal__hostname
          target_label: nodename
        - source_labels:
          - __journal_syslog_identifier
          target_label: syslog_identifier

・pod/promtail.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: promtail
spec:
  selector:
    matchLabels:
      name: promtail
  template:
    metadata:
      labels:
        name: promtail
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: promtail
        image: grafana/promtail:1.6.0
        args:
        - --config.file=/etc/promtail/config.yaml
        # - --config.file=/etc/promtail/config.yml
        ports:
        - containerPort: 9080
        volumeMounts:
        - name: log
          mountPath: /var/log
        - name: journal-var
          mountPath: /var/log/journal
          readOnly: true
        - name: journal-run
          mountPath: /run/log/journal
          readOnly: true
        - name: config-vol
          mountPath: /etc/promtail/config.yaml
          subPath: config.yaml
      volumes:
      - name: log
        hostPath:
          path: /var/log
      - hostPath:
          path: /var/log/journal
        name: journal-var
      - hostPath:
          path: /run/log/journal
        name: journal-run  
      - name: config-vol
        configMap:
          name: promtail-configmap
          items:
            - key: config.yaml
              path: config.yaml

・pod/loki.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: loki
spec:
  selector:
    matchLabels:
      app: loki
  template:
    metadata:
      labels:
        app: loki
    spec:
      containers:
        - name: loki
          image: grafana/loki:1.6.0
          imagePullPolicy: IfNotPresent
          args:
          - --config.file=/etc/loki/local-config.yaml       
          ports:
            - containerPort: 3100
---
apiVersion: v1
kind: Service
metadata:
  name: loki
spec:
  selector:
    app: loki
  ports:
    - port: 3100
  clusterIP: None

・pod/grafana.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
spec:
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
        - name: grafana
          image: grafana/grafana
          imagePullPolicy: IfNotPresent
          env:
            - name: TZ
              value: 'Asia/Tokyo'
          ports:
            - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: grafana-service
spec:
  selector:
    app: grafana
  ports:
    - port: 3000
      targetPort: 3000
      nodePort: 30748
  type: LoadBalancer

Promtailのポッドを実行する

 以下のコマンドで、Promtailが使用する設定ファイルを読み込みます。

kubectl apply -f config/pormtail.yaml

本設定では、Journalと/var/log内のログを監視する設定を行っております。

 以下のコマンドで、Promtailのポッドを全てのノードで起動させます。

kubectl apply -f pod/pormtail.yaml

Lokiのポッドを実行

 以下のコマンドで、Lokiが使用する設定ファイルを読み込みます。本ファイルはLokiコンテナ内の設定ファイルをそのまま、変更せずに読み込むように設定しております。

kubectl apply -f config/loki.yaml

 以下のコマンドで、Lokiのポッドを起動させます。なお、収集したデータ保存をするように記載しております。

kubectl apply -f pod/loki.yaml

収集したログの確認

 Grafanaのポッドと外部からアクセスできるサービスを立ち上げるため、以下のコマンドを実行する。ただし、本設定のYAMLファイルでは、永続保存するような設定がされていないため、ポッドが再起動すると設定は初期化するようになっています。

kubectl apply -f pod/grafana.yaml

 Grafanaのポッドとサービスがたちがったのを確認できたならば、ブラウザで、30748ポートにアクセスすると、Grafananのログインが面が表示されます。その状態で、以下の画面のように、lokiの接続を設定を行います。基本的に、URLの部分に「http://loki:3100」と入力すれば、設定は完了です。

 Lokiの登録ができならならば、Exploreで、ソースを「Loki」に設定し、Log labelsから、値を選択すれば、Lokiが収集したログを以下図のように確認することができます。