機械翻訳について

WebLogicドメイン

このドキュメントでは、Fluentdを使用してElasticsearchにログ情報を送信するようにWebLogicドメインを構成する方法について説明します。

これがどのように機能するかについての一般的なメカニズムを次に示します:

  • fluentdは、管理サーバーおよび管理対象サーバー・ポッドで個別のコンテナとして実行されます。
  • ログ・ファイルは、weblogic-serverコンテナとfluentdコンテナ間で共有されるボリュームに存在します。
  • fluentdは、ドメイン・ログ・ファイルを調整し、Elasticsearchにエクスポートします。
  • ConfigMapには、ログ・レコードをエクスポートするためのフィルタおよびフォーマット・ルールが含まれます。

サンプル・コード

このドキュメントのサンプルでは、既存のドメインが編集されていることを前提としています。 ただし、ドメインを作成する前に、ドメインYAMLファイルにすべての変更を加えることができます。

サンプルのために、このドキュメントでは、次の属性を持つドメインが構成されていることを前提としています:

  • ドメイン名はbobs-bookstoreです
  • Kubernetesネームスペースはbobです
  • Kubernetes Secretはbobs-bookstore-weblogic-credentialsです

サンプルのElasticsearch構成は次のとおりです:

    elasticsearchhost: elasticsearch.bobs-books.sample.com
    elasticsearchport: 443
    elasticsearchuser: bob
    elasticsearchpassword: changeme

ボリュームを使用するためのログ・ファイルの構成

ドメイン・ログ・ファイルは、weblogic-serverコンテナとfluentdコンテナの間で共有できるボリュームに書き込む必要があります。 これを実現するには、次の要素が必要です:

  • logHomeは、コンテナ間で共有できるパスである必要があります。
  • ログがポッドの外側に書き込まれ、ポッドの再起動後も保持されるように、logHomeEnabledtrueに設定する必要があります。
  • ログ・ファイルが存在するvolumeを定義する必要があります。 この例では、emptyDirはポッドの作成時に空で作成されるボリュームです。 ポッドの再起動後も保持されますが、ポッドを削除するとemptyDirコンテンツが削除されます。
  • volumeMountsは、emptyDirで作成された名前付きボリュームをマウントし、ボリュームにアクセスするためのベース・パスを確立します。

ノート: 簡潔にするために、追加される関連構成へのパスのみが表示されます。 ドメイン定義の完全な例は、このドキュメントの最後にあります。

例: $ kubectl edit domain bobs-bookstore -n bobを使用して、次の編集を行います:

spec:
  logHome: /scratch/logs/bobs-bookstore
  logHomeEnabled: true
  serverPod:
    volumes:
    - emptyDir: {}
      name: weblogic-domain-storage-volume
    volumeMounts:
    - mountPath: /scratch
      name: weblogic-domain-storage-volume

Elasticsearchシークレットの作成

fluentdコンテナは、KubernetesシークレットでElasticsearchパラメータを検索するように構成されます。 次のキーを使用してシークレットを作成します:

例:

$ kubectl -n bob create secret generic fluentd-credential
  --from-literal elasticsearchhost=quickstart-es-http.default
  --from-literal elasticsearchport=9200
  --from-literal elasticsearchuser=elastic
  --from-literal elasticsearchpassword=xyz

ドメイン・リソースでfluentdSpecificationを指定

  spec:
    fluentdSpecification:
      elasticSearchCredentials: fluentd-credential
      watchIntrospectorLogs: false
      volumeMounts:
      - mountPath: /shared
        name: weblogic-domain-storage-volume

オペレータは次のことを行います:

  1. デフォルトのfluentd構成でConfigMap webogic-fluentd-configmapを作成します。 「Fluentd構成」を参照してください。
  2. 各ポッドにfluentdコンテナを設定して、Elasticsearchシークレットを使用します。

ユースケースにあわせてfluentd構成をカスタマイズできます。 次のfluentdSpecificationオプションを参照してください:

オプション 説明 ノート
elasticSearchCredentials Elasticsearchエンジンと通信するためのfluentdコンテナのKubernetesシークレット名。
watchIntrospectorLogs trueに設定すると、イントロスペクタ・ジョブの出力を監視するために、オペレータもfluentdコンテナを設定します。 デフォルトはfalseです。 オペレータは、fluentd構成を含むConfigMapボリュームを参照するボリューム・マウントを自動的に追加しました。
volumeMounts fluentdコンテナのvolumeMountsの追加リスト。 少なくともlogHome共有ボリュームが含まれている必要があります。
image fluentdコンテナ・イメージ名。 デフォルト : fluent/fluentd-kubernetes-daemonset:v1.14.5-debian-elasticsearch7-1.1
imagePullPolicy fluentdコンテナのImagePullポリシー。
env fluentdコンテナの環境変数の追加リスト。 fluentdコンテナの環境変数」を参照してください。
resources fluentdコンテナのリソース。
fluentdConfiguration オペレータのデフォルトではなく、fluentd構成のテキスト。 「Fluentd構成」を参照してください。 ノート: ユーザーが構成を指定した場合、ユーザーにはfluentd構成全体に責任が生じ、オペレータはその一部を追加または変更しません。

例えば:

 fluentdSpecification:
    elasticSearchCredentials: fluentd-credential
    watchIntrospectorLogs: true
    volumeMounts:
    - mountPath: /shared
      name: weblogic-domain-storage-volume
    fluentdConfiguration: |-
      <match fluent.**>
        @type null
      </match>
      <source>
        @type tail
        path "#{ENV['LOG_PATH']}"
        pos_file /tmp/server.log.pos
        read_from_head true
        tag "#{ENV['DOMAIN_UID']}"
        # multiline_flush_interval 20s
        <parse>
          @type multiline
          format_firstline /^####/
          format1 /^####<(?<timestamp>(.*?))>/
          format2 / <(?<level>(.*?))>/
          format3 / <(?<subSystem>(.*?))>/
          format4 / <(?<serverName>(.*?))>/
          format5 / <(?<serverName2>(.*?))>/
          format6 / <(?<threadName>(.*?))>/
          format7 / <(?<info1>(.*?))>/
          format8 / <(?<info2>(.*?))>/
          format9 / <(?<info3>(.*?))>/
          format10 / <(?<sequenceNumber>(.*?))>/
          format11 / <(?<severity>(.*?))>/
          format12 / <(?<messageID>(.*?))>/
          format13 / <(?<message>(.*?))>.*/
          # use the timestamp field in the message as the timestamp
          # instead of the time the message was actually read
          time_key timestamp
          keep_time_key true
        </parse>
      </source>
      <source>
        @type tail
        path "#{ENV['INTROSPECTOR_OUT_PATH']}"
        pos_file /tmp/introspector.log.pos
        read_from_head true
        tag "#{ENV['DOMAIN_UID']}-introspector"
        # multiline_flush_interval 20s

        <parse>
          @type multiline
          format_firstline /@\[/
          format1 /^@\[(?<timestamp>.*)\]\[(?<filesource>.*?)\]\[(?<level>.*?)\](?<message>.*)/
          # use the timestamp field in the message as the timestamp
          # instead of the time the message was actually read
          time_key timestamp
          keep_time_key true
        </parse>

      </source>
      <match **>
        @type elasticsearch
        host "#{ENV['ELASTICSEARCH_HOST']}"
        port "#{ENV['ELASTICSEARCH_PORT']}"
        user "#{ENV['ELASTICSEARCH_USER']}"
        password "#{ENV['ELASTICSEARCH_PASSWORD']}"
        index_name "#{ENV['DOMAIN_UID']}"
        scheme https
        ssl_version TLSv1_2
        ssl_verify false
        key_name timestamp
        types timestamp:time
        suppress_type_name true
        # inject the @timestamp special field (as type time) into the record
        # so you will be able to do time based queries.
        # not to be confused with timestamp which is of type string!!!
        include_timestamp true
      </match>

ノート: watchIntrospectorLogsを設定してイントロスペクタ・ジョブのポッド・ログを監視します。 ジョブ・ポッド遷移のステータスがRunningからNotReadyに短時間で表示される場合があります。その後、Terminatingが通常の動作になります。


NAME                                READY   STATUS     RESTARTS   AGE
sample-domain1-introspector-kndk7    2/2     Running     0          57
sample-domain1-introspector-kndk7    1/2     NotReady    0          60s
sample-domain1-introspector-kndk7    0/2     Terminating 0          63s

fluentdコンテナの環境変数

オペレータは、fluentd構成で参照される次の環境変数を使用してfluentdコンテナを設定します:

    env:
    - name: ELASTICSEARCH_HOST
      valueFrom:
        secretKeyRef:
          key: elasticsearchhost
          name: fluentd-credential
          optional: false
    - name: ELASTICSEARCH_PORT
      valueFrom:
        secretKeyRef:
          key: elasticsearchport
          name: fluentd-credential
          optional: false
    - name: ELASTICSEARCH_USER
      valueFrom:
        secretKeyRef:
          key: elasticsearchuser
          name: fluentd-credential
          optional: true
    - name: ELASTICSEARCH_PASSWORD
      valueFrom:
        secretKeyRef:
          key: elasticsearchpassword
          name: fluentd-credential
          optional: true
    - name: FLUENT_ELASTICSEARCH_SED_DISABLE
      value: "true"
    - name: FLUENTD_CONF
      value: fluentd.conf
    - name: DOMAIN_UID
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.labels['weblogic.domainUID']
    - name: SERVER_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.labels['weblogic.serverName']
    - name: LOG_PATH
      value: /shared/logs/sample-domain1/admin-server.log
    - name: INTROSPECTOR_OUT_PATH
      value: /shared/logs/sample-domain1/introspector_script.out

Fluentd構成

オペレータは、ドメインのネームスペースにwebogic-fluentd-configmapという名前のConfigMapを作成します。 ConfigMapには、解析ルールおよびElasticsearch構成が含まれます。

ConfigMapで定義されている要素について説明します:

  • @type tailは、tailを使用してログ・ファイルの更新を取得することを示します。
  • ログ・ファイルのpathは、fluentdコンテナで定義されているLOG_PATH環境変数から取得されます。
  • ログ・レコードのtag値は、fluentdコンテナで定義されているDOMAIN_UID環境変数から取得されます。
  • <parse>セクションでは、ログ・レコードの各要素を解釈およびタグ付けする方法を定義します。
  • <match **>セクションには、Elasticsearchに接続するための構成情報が含まれ、各レコードの索引名をdomainUIDとして定義します。

fluentdConfigurationが指定されていない場合のデフォルトのfluentd構成は、次のとおりです:

       <match fluent.**>
          @type null
        </match>
        <source>
          @type tail
          path "#{ENV['LOG_PATH']}"
          pos_file /tmp/server.log.pos
          read_from_head true
          tag "#{ENV['DOMAIN_UID']}"
          # multiline_flush_interval 20s
          <parse>
            @type multiline
            format_firstline /^####/
            format1 /^####<(?<timestamp>(.*?))>/
            format2 / <(?<level>(.*?))>/
            format3 / <(?<subSystem>(.*?))>/
            format4 / <(?<serverName>(.*?))>/
            format5 / <(?<serverName2>(.*?))>/
            format6 / <(?<threadName>(.*?))>/
            format7 / <(?<info1>(.*?))>/
            format8 / <(?<info2>(.*?))>/
            format9 / <(?<info3>(.*?))>/
            format10 / <(?<sequenceNumber>(.*?))>/
            format11 / <(?<severity>(.*?))>/
            format12 / <(?<messageID>(.*?))>/
            format13 / <(?<message>(.*?))>/
            # use the timestamp field in the message as the timestamp
            # instead of the time the message was actually read
            time_key timestamp
            keep_time_key true
          </parse>
        </source>
        <source>
          @type tail
          path "#{ENV['INTROSPECTOR_OUT_PATH']}"
          pos_file /tmp/introspector.log.pos
          read_from_head true
          tag "#{ENV['DOMAIN_UID']}-introspector"
          # multiline_flush_interval 20s
          <parse>
            @type multiline
            format_firstline /@\[/
            format1 /^@\[(?<timestamp>.*)\]\[(?<filesource>.*?)\]\[(?<level>.*?)\](?<message>.*)/
            # use the timestamp field in the message as the timestamp
            # instead of the time the message was actually read
            time_key timestamp
            keep_time_key true
          </parse>
         </source>
        <match "#{ENV['DOMAIN_UID']}-introspector">
          @type elasticsearch
          host "#{ENV['ELASTICSEARCH_HOST']}"
          port "#{ENV['ELASTICSEARCH_PORT']}"
          user "#{ENV['ELASTICSEARCH_USER']}"
          password "#{ENV['ELASTICSEARCH_PASSWORD']}"
          index_name "#{ENV['DOMAIN_UID']}"
          suppress_type_name true
          type_name introspectord
          logstash_format true
          logstash_prefix introspectord
          # inject the @timestamp special field (as type time) into the record
          # so you will be able to do time based queries.
          # not to be confused with timestamp which is of type string!!!
          include_timestamp true
        </match>
        <match "#{ENV['DOMAIN_UID']}">
          @type elasticsearch
          host "#{ENV['ELASTICSEARCH_HOST']}"
          port "#{ENV['ELASTICSEARCH_PORT']}"
          user "#{ENV['ELASTICSEARCH_USER']}"
          password "#{ENV['ELASTICSEARCH_PASSWORD']}"
          index_name "#{ENV['DOMAIN_UID']}"
          suppress_type_name true
          type_name fluentd
          logstash_format true
          logstash_prefix fluentd
          # inject the @timestamp special field (as type time) into the record
          # so you will be able to do time based queries.
          # not to be confused with timestamp which is of type string!!!
          include_timestamp true
        </match>

ログがElasticsearchにエクスポートされていることを確認

前述のすべての変更で管理サーバーおよび管理対象サーバー・ポッドが起動すると、ログはElasticsearchに送信されます。

$ kubectl logs -f bobs-bookstore-admin-server -n bob fluentdなどのコマンドを実行して、fluentdコンテナがログを正常に調整しているかどうかを確認できます。 ログ出力は次のようになります:

2019-10-01 16:23:44 +0000 [info]: #0 starting fluentd worker pid=13 ppid=9 worker=0
2019-10-01 16:23:44 +0000 [warn]: #0 /scratch/logs/bobs-bookstore/managed-server1.log not found. Continuing without tailing it.
2019-10-01 16:23:44 +0000 [info]: #0 fluentd worker is now running worker=0
2019-10-01 16:24:01 +0000 [info]: #0 following tail of /scratch/logs/bobs-bookstore/managed-server1.log

Kibanaに接続すると、domainUID用に作成された索引が表示されます。

Kibanaログ出力の例:

timestamp:Oct 1, 2019 4:18:07,111 PM GMT level:Info subSystem:Management serverName:bobs-bookstore-admin-server serverName2:
threadName:Thread-8 info1: info2: info3: sequenceNumber:1569946687111 severity:[severity-value: 64] [partition-id: 0] [partition-name: DOMAIN]
messageID:BEA-141107 message:Version: WebLogic Server 12.2.1.3.0 Thu Aug 17 13:39:49 PDT 2017 1882952
_id:OQIeiG0BGd1zHsxmUrEJ _type:fluentd _index:bobs-bookstore _score:1