Red Hat Training

A Red Hat training course is available for Red Hat OpenStack Platform

第2章 集中ロギングスイートのインストール

2.1. 集中ログリレー/トランスフォーマーのインストール

  1. 以下の最小仕様を満たすベアメタルのシステムを特定します。

    • 8 GB メモリー
    • 単一ソケットの Xeon クラスの CPU
    • 500 GB のディスク領域
  2. Red Hat Enterprise Linux 7 をインストールします。
  3. このシステムの運用ツールパッケージへのアクセスを許可します。

    1. システムを登録して、サブスクライブします。

      # subscription-manager register
      # subscription-manager list --consumed

      OpenStack のサブスクリプションが自動的にアタッチされない場合は、「manually attaching subscriptions」に記載の説明を参照してください。

    2. 最初に有効化されているリポジトリーを無効化してから、運用ツールに適したリポジトリーのみを有効化します。

      # subscription-manager repos --disable=*
      # subscription-manager repos --enable=rhel-7-server-rpms --enable=rhel-7-server-optional-rpms --enable=rhel-7-server-openstack-8-optools-rpms
      注記

      ベースの OpenStack リポジトリー (rhel-7-server-openstack-8-rpms) は、このノードでは有効化しないでください。このリポジトリーには、特定の運用ツールの依存関係でより新しいバージョンが含まれている可能性があり、運用パッケージと互換性がない場合があります。

  4. Fluentdhttpd に接続ができるようにシステムのファイアウォールを開放します。

    # firewall-cmd --zone=public --add-port=4000/tcp --permanent
    # firewall-cmd --zone=public --add-service=http --permanent
    # firewall-cmd --reload
  5. 以下のコマンドで FluentdElasticsearch のソフトウェアをインストールします。

    # yum install elasticsearch fluentd rubygem-fluent-plugin-elasticsearch kibana httpd
  6. Elasticsearch を設定します。これには、/etc/elasticsearch/elasticsearch.yml を編集して、ファイルの最後に以下の行を追加します。

    http.cors.enabled: true
    http.cors.allow-origin: "/.*/"
  7. Elasticsearch インスタンスを起動して、ブート時に有効化されるように設定します。

    # systemctl start elasticsearch
    # systemctl enable elasticsearch

    Elasticsearch インスタンスが機能していることを確認するには、以下のコマンドを実行して、以下のように、有効な応答が返されることを確認します。

    # curl http://localhost:9200/

    このコマンドを実行すると、以下のような応答が返されます。

    {
      "status" : 200,
      "name" : "elasticsearch.example.com",
      "cluster_name" : "elasticsearch",
      "version" : {
        "number" : "1.5.2",
        "build_hash" : "c88f77ffc81301dfa9dfd81ca2232f09588bd512",
        "build_timestamp" : "2015-02-19T13:05:36Z",
        "build_snapshot" : false,
        "lucene_version" : "4.10.3"
      },
      "tagline" : "You Know, for Search"
    }
  8. Fluentd がログデータを受け入れ、Elasticsearch に書き込みができるように設定します。/etc/fluentd/fluent.conf を編集して、内容を以下のように置き換えます。

    # In v1 configuration, type and id are @ prefix parameters.
    # @type and @id are recommended. type and id are still available for backward compatibility
    
    <source>
      @type forward
      port 4000
      bind 0.0.0.0
    </source>
    
    <match **>
      @type elasticsearch
      host localhost
      port 9200
      logstash_format true
      flush_interval 5
    </match>
  9. Fluentd を起動して、ブート時に有効化されるように設定します。

    # systemctl start fluentd
    # systemctl enable fluentd
    ヒント

    Fluentd のジャーナルを確認して、起動時にエラーがないことを確認します。

    # journalctl -u fluentd -l -f
  10. KibanaElasticsearch インスタンスにポイントするように設定します。/etc/httpd/conf.d/kibana3.conf を作成して、このファイルに以下の内容を設定します。

    <VirtualHost *:80>
    
      DocumentRoot /usr/share/kibana
      <Directory /usr/share/kibana>
        Require all granted
        Options -Multiviews
      </Directory>
    
      # Proxy for _aliases and .*/_search
      <LocationMatch "^/(_nodes|_aliases|.*/_aliases|_search|.*/_search|_mapping|.*/_mapping)$">
        ProxyPassMatch http://127.0.0.1:9200/$1
        ProxyPassReverse http://127.0.0.1:9200/$1
      </LocationMatch>
    
      # Proxy for kibana-int/{dashboard,temp}
      <LocationMatch "^/(kibana-int/dashboard/|kibana-int/temp)(.*)$">
        ProxyPassMatch http://127.0.0.1:9200/$1$2
        ProxyPassReverse http://127.0.0.1:9200/$1$2
      </LocationMatch>
    
    </VirtualHost>
  11. Elasticsearch に接続するように (Apache 内の) Kibana を有効化して、Apache を起動し、ブート時に有効化されるようにします。

    # setsebool -P httpd_can_network_connect 1
    # systemctl start httpd
    # systemctl enable httpd

2.2. 全ノード上でのログ収集エージェントのインストール

OpenStack 環境の全システムからのログを収集して集中ロギングサーバーに送信するには、全 OpenStack システムで以下のコマンドを実行します。

  1. 運用ツールのリポジトリーを有効にします。

    # subscription-manager repos --enable=rhel-7-server-openstack-8-optools-rpms
  2. fluentdrubygem-fluent-plugin-add をインストールします。

    # yum install fluentd rubygem-fluent-plugin-add
  3. Fluentd ユーザーがすべての OpenStack ログファイルを読み取りできるパーミッションが割り当てられるように設定します。これには、以下のコマンドを実行してください。

    # for user in {keystone,nova,neutron,cinder,glance}; do usermod -a -G $user fluentd; done

    ノードによっては、グループがないとのエラーが発生する可能性がある点に注意してください。すべてのノードで全サービスが実行されるわけではないため、このエラーは無視しても構いません。

  4. Fluentd を設定します。/etc/fluentd/fluent.conf が以下のようになるように設定します。LOGGING_SERVER は、上記で設定した集中ロギングサーバーのホスト名または IP アドレスに置き換えるのを忘れないでください。

    # In v1 configuration, type and id are @ prefix parameters.
    # @type and @id are recommended. type and id are still available for backward compatibility
    
    # Nova compute
    <source>
      @type tail
      path /var/log/nova/nova-compute.log
      tag nova.compute
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match nova.compute>
      type add
      <pair>
        service nova.compute
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Nova API
    <source>
      @type tail
      path /var/log/nova/nova-api.log
      tag nova.api
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match nova.api>
      type add
      <pair>
        service nova.api
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Nova Cert
    <source>
      @type tail
      path /var/log/nova/nova-cert.log
      tag nova.cert
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match nova.cert>
      type add
      <pair>
        service nova.cert
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Nova Conductor
    <source>
      @type tail
      path /var/log/nova/nova-conductor.log
      tag nova.conductor
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match nova.conductor>
      type add
      <pair>
        service nova.conductor
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Nova Consoleauth
    <source>
      @type tail
      path /var/log/nova/nova-consoleauth.log
      tag nova.consoleauth
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match nova.consoleauth>
      type add
      <pair>
        service nova.consoleauth
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Nova Scheduler
    <source>
      @type tail
      path /var/log/nova/nova-scheduler.log
      tag nova.scheduler
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match nova.scheduler>
      type add
      <pair>
        service nova.scheduler
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Neutron Openvswitch Agent
    <source>
      @type tail
      path /var/log/neutron/openvswitch-agent.log
      tag neutron.openvswitch
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match neutron.openvswitch>
      type add
      <pair>
        service neutron.openvswitch
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Neutron Server
    <source>
      @type tail
      path /var/log/neutron/server.log
      tag neutron.server
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match neutron.server>
      type add
      <pair>
        service neutron.server
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Neutron DHCP Agent
    <source>
      @type tail
      path /var/log/neutron/dhcp-agent.log
      tag neutron.dhcp
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match neutron.dhcp>
      type add
      <pair>
        service neutron.dhcp
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Neutron L3 Agent
    <source>
      @type tail
      path /var/log/neutron/l3-agent.log
      tag neutron.l3
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match neutron.l3>
      type add
      <pair>
        service neutron.l3
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Neutron Metadata Agent
    <source>
      @type tail
      path /var/log/neutron/metadata-agent.log
      tag neutron.metadata
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match neutron.metadata>
      type add
      <pair>
        service neutron.metadata
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Keystone
    <source>
      @type tail
      path /var/log/keystone/keystone.log
      tag keystone
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match keystone>
      type add
      <pair>
        service keystone
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Glance API
    <source>
      @type tail
      path /var/log/glance/api.log
      tag glance.api
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match glance.api>
      type add
      <pair>
        service glance.api
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Glance Registry
    <source>
      @type tail
      path /var/log/glance/registry.log
      tag glance.registry
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match glance.registry>
      type add
      <pair>
        service glance.registry
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Cinder API
    <source>
      @type tail
      path /var/log/cinder/api.log
      tag cinder.api
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match cinder.api>
      type add
      <pair>
        service cinder.api
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Cinder Scheduler
    <source>
      @type tail
      path /var/log/cinder/scheduler.log
      tag cinder.scheduler
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match cinder.scheduler>
      type add
      <pair>
        service cinder.scheduler
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    # Cinder Volume
    <source>
      @type tail
      path /var/log/cinder/volume.log
      tag cinder.volume
      format multiline
      format_firstline /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      format /(?<time>[^ ]* [^ ]*) (?<pid>[^ ]*) (?<loglevel>[^ ]*) (?<class>[^ ]*) \[(?<context>.*)\] (?<message>.*)/
      time_format %F %T.%L
    </source>
    
    <match cinder.volume>
      type add
      <pair>
        service cinder.volume
        hostname "#{Socket.gethostname}"
      </pair>
    </match>
    
    <match greped.**>
      @type forward
      heartbeat_type tcp
      <server>
        name LOGGING_SERVER
        host LOGGING_SERVER
        port 4000
      </server>
    </match>
  5. Fluentd が設定されたので、Fluentd サービスを起動して、ブート時に有効になるように設定します。

    # systemctl start fluentd
    # systemctl enable fluentd

http://LOGGING_SERVER/index.html#/dashboard/file/logstash.json で実行中の Kibana にアクセスでき、ログの生成が開始されていることが分かるはずです。

注記

デフォルトでは、ロギングサーバーのフロントページ (http://LOGGING_SERVER/) は、技術要件と追加の設定情報を提供する Kibana のウェルカム画面になっています。ここにログを表示するには、Kibana アプリケーションディレクトリーの default.json ファイルを logstash.json に置き換えてください。ただし、後ほどこのファイルがもう一度必要になったときに備えて、まず default.json のバックアップコピーを作成してください。

# mv /usr/share/kibana/app/dashboards/default.json /usr/share/kibana/app/dashboards/default.json.orig
# cp /usr/share/kibana/app/dashboards/logstash.json /usr/share/kibana/app/dashboards/default.json