作業中のメモ

よく「計算機」を使って作業をする.知らなかったことを中心にまとめるつもり.

fluentd+elasticsearch+kibanaによるログの一元管理とログの可視化

どうも,筆者です.

最近,自宅の raspberry pi とミニマシンに docker を入れて LAN 内にサーバを立てている.時々,問題が発生することがあるため,なんとか一元管理したいと考えていた.

少し調べると,fluentd でログを転送し,elasticsearch でログを蓄積する.そして,kibana により蓄積したログの可視化ができるとのこと.今回は,これらを用いてログの一元管理とログの可視化を行う.

準備

バージョンの調査

elasticsearch と kibana はバージョンが違うと動かないことがあるらしい.ここでは,下記のサイトで最新版を調べた上で導入する.また,通常のものの場合,ライセンス料がかかるみたいなので,oss 版を利用する.

今回,利用する elasticsearch と kibana のバージョンは,どちらも 7.10.2 である.

www.docker.elastic.co

www.docker.elastic.co

fluentd の config 調査

ログを転送する際に fluentd を用いる.この時,利用する fluentd のバージョンにより書き方が異なるらしい.ここでは,docker images の都合上,alpine 版のバージョン 1.12 を利用する.(ブログにまとめているときに気づくが,別途追加したフィルタリングプラグインは不要だった)

docs.fluentd.org

環境構築

環境構築時には,以下のサイトを参考にした.

qiita.com

fluentd

まずは,fluentd の環境構築を行う.

サンプルの取得

github の「How to build your own image」を参考に環境構築を行う.ここでは,VERSION を「v1.12」,OS を「alpine」とするので,それに合わせてリンクを修正する.

hub.docker.com

github.com

具体的に実行するコマンドは以下のようになる.ここで,今回の環境構築に不要な処理は削除している.

# ディレクトリを作成し,その中に移動
mkdir fluentd
cd fluentd

# config と shell script を取得
curl https://raw.githubusercontent.com/fluent/fluentd-docker-image/master/v1.12/alpine/fluent.conf > fluent.conf
curl https://raw.githubusercontent.com/fluent/fluentd-docker-image/master/v1.12/alpine/entrypoint.sh > entrypoint.sh
# Dockerfile を取得
curl https://raw.githubusercontent.com/fluent/fluentd-docker-image/master/Dockerfile.sample > Dockerfile

Dockerfile の修正

elasticsearch への転送とタグ情報の取得のために,プラグインを追加する.追加するプラグインは以下の 2 つである.

  • fluent-plugin-elasticsearch
  • fluent-plugin-forest

これらを追加した Dockerfile を以下に示す.また,entrypoint.sh に実行権限を与えている.

FROM fluent/fluentd:v1.12-1

USER root

RUN    apk add --no-cache --update --virtual .build-deps sudo build-base ruby-dev \
    # cutomize following instruction as you wish
    && sudo gem install fluent-plugin-elasticsearch fluent-plugin-forest \
    && sudo gem sources --clear-all \
    && apk del .build-deps \
    && rm -rf /home/fluent/.gem/ruby/2.5.0/cache/*.gem

COPY fluent.conf /fluentd/etc/
COPY entrypoint.sh /bin/
RUN chmod +x /bin/entrypoint.sh

USER fluent

fluent.conf の設定

fluentd の config を設定する.ここでは,ログの転送元でコンテナ名をタグとして割り当て,そのタグに合わせて集計できるようにする.例えば,nginx 向けの場合,転送時に「docker.nginx」というタグをつけ,fluentd 側でタグごとに index を割り当てる.index については,詳細を知らないため,各自調べてほしい.

今回は,外部から送られてきたログを elasticsearch に転送する.その際に,コンテナ名を index に割り当てる.これを config として設定した結果を以下に示す.この config の書き方は細かく理解できていない.

<source>
    @type forward
    port 24224
    bind 0.0.0.0
</source>

<match docker.**>
    @type forest
    subtype elasticsearch
    remove_prefix docker.

    <template>
        host elasticsearch
        port 9200
        type_name docker.${tag_parts[1]}
        logstash_format true
        logstash_prefix logstash-${tag_parts[1]}
    </template>
</match>

先ほど導入した「fluent-plugin-forest」プラグインを用いて,docker.xxx の xxx を取り出し,index に logstash-xxx という形式で prefix を付ける.logstash_format と index の関係は,公式サイトを参考のこと.

docs.fluentd.org

ここまでの作業により,以下のようなディレクトリ構成となる.

./  --- fluentd
          |
          + --- Dockerfile
          |
          + --- entrypoint.sh
          |
          + --- fluent.conf
               

elasticsearch と kibana

次に,elasticsearch と kibana の設定を行う. elasticsearch と kibana は,image を取得しそのまま起動させるだけである.このため,Dockerfile や config ファイルの設定は不要である.

docker-compose.yml の作成

今回作成した docker-compose.yml を以下に示す.

version: '3.7'

x-logging:
    &default-json-logging
    driver: json-file
    options:
        max-size: "10m"
        max-file: "1"

services:
    elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
        container_name: elasticsearch
        restart: always
        expose:
            - "9200"
            - "9300"
        environment:
            discovery.type: "single-node"
            ES_JAVA_OPTS: "-Xms512m -Xmx512m"
        ulimits:
            memlock:
                soft: -1
                hard: -1
        volumes:
            - elasticsearch-data:/usr/share/elasticsearch/data
        logging: *default-json-logging

    kibana:
        image: docker.elastic.co/kibana/kibana-oss:7.10.2
        container_name: kibana
        restart: always
        ports:
            - "5601:5601"
        depends_on:
            - elasticsearch
        links:
            - elasticsearch:elasticsearch
        logging: *default-json-logging

    fluentd:
        build:
            context: ./fluentd
            dockerfile: Dockerfile
        container_name: fluentd
        image: custom-fluentd:latest
        ports:
            - "24224:24224"
        volumes:
            - ./fluentd/fluent.conf:/fluentd/etc/fluent.conf:ro
        depends_on:
            - elasticsearch
        logging: *default-json-logging

volumes:
    elasticsearch-data:
        driver: local

ディレクトリ構成は,以下のようになる.

ここまでの作業により,以下のようなディレクトリ構成となる.

./  --- + --- docker-compose.yml
        |
        + --- fluentd
                  |
                  + --- Dockerfile
                  |
                  + --- entrypoint.sh
                  |
                  + --- fluent.conf               

ログの転送設定

最後に,ログの転送設定を行う.筆者の環境では,dns や nginx,web サーバを立ち上げている.これらを fluentd を立ち上げたマシンに転送する.docker-compose.yml の例を以下に示す.

version: '3.4'

x-logging:
    &default-logging
    driver: fluentd
    options:
        fluentd-address: 192.168.33.5:24224  # fluentd+elasticsearch+kibana が起動しているサーバを指定
        tag: docker.{{.Name}}                # docker.container_name となるようにタグを指定

services:
    nginx:
        build:
            context: ./nginx
            dockerfile: Dockerfile
        image: custom_nginx
        restart: always
        container_name: nginx
        ports:
            - 80:80
        volumes:
            - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
            - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params:ro
        logging: *default-logging
        links:
            - django
        depends_on:
            - django

    django:
        build:
            context: ./django
            dockerfile: Dockerfile
        image: custom_django
        container_name: django
        restart: always
        volumes:
            - ./django/uwsgi.ini:/uwsgi.ini:ro
            - ./django/src:/code:ro
        logging: *default-logging
        expose:
            - 8001
        links:
            - database
        depends_on:
            - database

    database:
        build:
            context: ./mariadb
            dockerfile: Dockerfile
        image: custom_mariadb
        container_name: mariadb
        restart: always
        environment:
            MYSQL_ROOT_PASSWORD: rootpassword
            MYSQL_DATABASE: db
            MYSQL_USER: django
            MYSQL_PASSWORD: password
            TZ: "Asia/Tokyo"
        volumes:
            - database:/var/lib/mysql
        logging: *default-logging
        expose:
            - 3306

volumes:
    database:

上記の設定で,stdout/stderr に出力されたログが fluentd に転送される.