Red Hat Training
A Red Hat training course is available for Red Hat OpenStack Platform
第2章 集中ロギングスイートのインストール
2.1. 集中ログリレー/トランスフォーマーのインストール
以下の最小仕様を満たすベアメタルのシステムを特定します。
- 8 GB メモリー
- 単一ソケットの Xeon クラスの CPU
- 500 GB のディスク領域
- Red Hat Enterprise Linux 7 をインストールします。
このシステムの運用ツールパッケージへのアクセスを許可します。
システムを登録して、サブスクライブします。
# subscription-manager register # subscription-manager list --consumed
OpenStack のサブスクリプションが自動的にアタッチされない場合は、「manually attaching subscriptions」に記載の説明を参照してください。
最初に有効化されているリポジトリーを無効化してから、運用ツールに適したリポジトリーのみを有効化します。
# 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) は、このノードでは有効化しないでください。このリポジトリーには、特定の運用ツールの依存関係でより新しいバージョンが含まれている可能性があり、運用パッケージと互換性がない場合があります。
Fluentdとhttpdに接続ができるようにシステムのファイアウォールを開放します。# firewall-cmd --zone=public --add-port=4000/tcp --permanent # firewall-cmd --zone=public --add-service=http --permanent # firewall-cmd --reload
以下のコマンドで
FluentdとElasticsearchのソフトウェアをインストールします。# yum install elasticsearch fluentd rubygem-fluent-plugin-elasticsearch kibana httpd
Elasticsearchを設定します。これには、/etc/elasticsearch/elasticsearch.ymlを編集して、ファイルの最後に以下の行を追加します。http.cors.enabled: true http.cors.allow-origin: "/.*/"
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" }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>
Fluentdを起動して、ブート時に有効化されるように設定します。# systemctl start fluentd # systemctl enable fluentd
ヒントFluentdのジャーナルを確認して、起動時にエラーがないことを確認します。# journalctl -u fluentd -l -f
KibanaがElasticsearchインスタンスにポイントするように設定します。/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>Elasticsearchに接続するように (Apache 内の)Kibanaを有効化して、Apache を起動し、ブート時に有効化されるようにします。# setsebool -P httpd_can_network_connect 1 # systemctl start httpd # systemctl enable httpd
2.2. 全ノード上でのログ収集エージェントのインストール
OpenStack 環境の全システムからのログを収集して集中ロギングサーバーに送信するには、全 OpenStack システムで以下のコマンドを実行します。
運用ツールのリポジトリーを有効にします。
# subscription-manager repos --enable=rhel-7-server-openstack-8-optools-rpms
fluentdとrubygem-fluent-plugin-addをインストールします。# yum install fluentd rubygem-fluent-plugin-add
Fluentdユーザーがすべての OpenStack ログファイルを読み取りできるパーミッションが割り当てられるように設定します。これには、以下のコマンドを実行してください。# for user in {keystone,nova,neutron,cinder,glance}; do usermod -a -G $user fluentd; doneノードによっては、グループがないとのエラーが発生する可能性がある点に注意してください。すべてのノードで全サービスが実行されるわけではないため、このエラーは無視しても構いません。
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>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