FilebeatとMetricbeatを活用したElastic流の方法でKubernetesを監視する

以前のブログ記事では、PrometheusとFluentdをElastic Stackと組み合わせて使用して、Kubernetesを監視する方法をご紹介しました。すでに組織でこのようなオープンソースベースの監視ツールを使用している場合には、この方法も有効です。ただし、初めてKubernetes監視を使用する場合や、Elasticオブザーバビリティの能力をすべて活用したい場合は、もっと簡単で包括的な方法があります。このブログでは、FilebeatとMetricbeatを活用したElastic流の方法でKubernetesを監視する方法を解説します。

FilebeatとMetricbeatを使用する

ご存知のとおり、Beatsは、データシッピングに特化した無料のオープンプラットフォームです。Beatsを使用すると、何百、何千ものマシンからLogstashやElasticsearchにデータを転送できます。

Filebeatは軽量のログシッパーとして知られていますが、コンテナー化されたアーキテクチャーにも対応しています。Filebeatは、Docker、Kubernetes、クラウド環境にデプロイできます。すべてのログストリームを収集するほか、コンテナー、ポッド、ノード、仮想環境、ホストなどのメタデータを取得し、それらを対応するログイベントに自動的に相関付けることができます。Metricbeatは軽量のメトリックシッパーであり、Filebeatと同様にコンテナー化された環境に対応しています。Kubernetes環境では、コンテナーは利用可能なワーカーノードで動的にポッドとしてデプロイされます。この「動的」というのが重要です。FilebeatとMetricbeatにはAutodiscoverという便利な機能があります。コンテナーでアプリケーションを実行すると、システム監視の移動標的になります。FilebeatとMetricbeatのKubernetes Autodiscover Providersは、Kubernetesノード、ポッド、サービスの起動、更新、停止を監視します。FilebeatまたはMetricbeatがこのようなイベントを検知すると、該当するメタデータを各イベントで利用できるようにします。また、起動したKubernetesポッドの注釈に応じて、該当する設定を対象のログとメトリックに適用します。ヒントベースのAutodiscoverについては、以前のブログ記事「Beatsを使用したDockerとKubernetesのヒントベースのAutodiscover」で詳しく解説しています。

監視アーキテクチャー

以前のブログで説明したように、Cloud-Voting-AppというシンプルなマルチコンテナーアプリケーションをKubernetesクラスターにデプロイし、そのアプリケーションを含めたKubernetes環境を監視します。今回は、Filebeatを使用してログを収集し、Metricbeatを使用してメトリックを収集します。そして、そのログとメトリックを直接Elasticsearchにインジェストし、Kibanaを使用して監視します。その手順について説明します。また、Elastic APMを使用して、Prometheusカスタムメトリックを取得する方法についても説明します。次の図はアーキテクチャーの概要を示しています。また、このチュートリアルのコードは、GitHubリポジトリに掲載していますので、詳細な手順についてはそちらをご覧ください。

enter image description here

では、各ステップを確認しましょう。

FilebeatをDaemonSetとして デプロイする

1つのKubernetesノードには、Filebeatのインスタンスを1つだけデプロイしてください。DaemonSetのマニフェストはすでに「elastic/filebeat-kubernetes.yaml」で定義されていますが、関連する設定を確認してみましょう。

まず、Kubernetes Autodiscover Providerを使用して、ログを処理するためのアプリケーションポッド注釈設定を構成します。ご覧のように、Autodiscover設定は「filebeat.autodiscover」セクションで定義されています。今回は、ヒントを有効化し、コンテナーログのデフォルトパスを設定しました。Autodiscover for Filebeatの構成の詳細については、Filebeatドキュメントを参照してください。

...
    # ヒントに基づくautodiscoverを有効化するには、「filebeat.inputs」構成を削除し、次のセクションのコメントを解除します。
    filebeat.autodiscover:
      providers:
        - type: kubernetes
          node: ${NODE_NAME}
          hints.enabled: true
          hints.default_config:
            type: container
            パス:
              - /jp/var/log/containers/*${data.kubernetes.container.id}.log
...

上記の手順を除き、基本的に、必要な作業は、ElasticsearchクラスターのURLと資格情報を追加することだけです。

...
     コンテナー:
      - name: filebeat
        image: docker.elastic.co/beats/filebeat:7.13.0
        args: [
          "-c", "/jp/etc/filebeat.yml",
          "-e",
        ]
        env:
        - name:ELASTICSEARCH_HOST
          value: elasticsearch
        - name:ELASTICSEARCH_PORT
          value:"9200"
        - name:ELASTICSEARCH_USERNAME
          value: elastic
        - name:ELASTICSEARCH_PASSWORD
          value: changeme
        - name:ELASTIC_CLOUD_ID
          value:
        - name:ELASTIC_CLOUD_AUTH
          value:
...

kube-state-metricsをデプロイする

kube-state-metricsはKubernetesのアドオンであり、Kubernetesに格納されたオブジェクトを監視します。kube-state-metricsは、KubernetesクラスターにデプロイされたKubernetesオブジェクトの状態を特定することに特化しています。たとえば、ある特定の時点で、クラスターにデプロイされたポッドがいくつあるか、クラスターで割り当て可能なCPUはどれか、失敗したジョブは何件かなどを特定します。kube-state-metricsは、デフォルトではKubernetesクラスターにデプロイされないため、自分でデプロイする必要があります。参考として、kube-state-metricsのサンプルマニフェストは「examples/standard」の下にあります。kube-state-metricsの詳細については、このGitHub repoを参照してください。

MetricbeatをDaemonSetとしてデプロイする

Filebeatと同様に、1つのKubernetesノードには、Metricbeatのインスタンスを1つだけデプロイしてください。DaemonSetのマニフェストはすでに「elastic/metricbeat-kubernetes.yaml」で定義されていますが、Filebeatよりもすこし厄介です。主な設定を見てみましょう。

Autodiscoverの設定は「metricbeat.autodiscover」セクションで定義されています。最初の「- type: kubernetes」設定はKubernetesクラスター全体に適用されます。ここでは、MetricbeatのKubernetesモジュールを使用して、Kubernetesクラスター全体のメトリックを構成します。最初の「- module: kubernetes」構成は、前述のkube-state-metricsから取得したメトリックを設定します。2番目の「- module: kubernetes」構成は、Kubernetes APIサーバー(kube-apiserver)を監視するための構成です。このサーバーは、Kubernetes APIを公開するKubernetesコントロールプレーンの中核となる要素です。MetricbeatのKubernetesモジュールの詳細については、Metricbeatドキュメントを参照してください。

metricbeat.autodiscover:
  providers:
    - type: kubernetes
      scope: cluster
      node: ${NODE_NAME}
      unique: true
      templates:
        - config:
            - module: kubernetes
              hosts: ["kube-state-metrics:8080"]
              period:10s
              add_metadata: true
              metricsets:
                - state_node
                - state_deployment
                - state_daemonset
                - state_replicaset
                - state_pod
                - state_container
                - state_cronjob
                - state_resourcequota
                - state_statefulset
                - state_service
            - module: kubernetes
              metricsets:
                - apiserver
              hosts: ["https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}"]
              bearer_token_file: /jp/var/run/secrets/kubernetes.io/serviceaccount/token
              ssl.certificate_authorities:
                - /jp/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
              period:30s

また、Kubernetes Autodiscover Providerを活用して、アプリケーションポッド注釈設定を使用したメトリックの処理ができるように、ヒントが定義されています。Autodiscover for Metricbeatの構成の詳細については、Metricbeatドキュメントを参照してください。

    # ヒントに基づくautodiscoverを有効化するには、次のセクションのコメントを解除します。
    - type: kubernetes
      node: ${NODE_NAME}
      hints.enabled: true

次のConfigMap設定は、MetricbeatのKubernetesのデフォルトMetricsetである、node/system/pod/container/volumeに適用されます。これらのメトリックは各ノードのkubeletエンドポイントから取得されます。

kubernetes.yml: |-
  - module: kubernetes
    metricsets:
      - node
      - system
      - pod
      - container
      - volume
    period:10s
    host: ${NODE_NAME}
    hosts: ["https://${NODE_NAME}:10250"]
    bearer_token_file: /jp/var/run/secrets/kubernetes.io/serviceaccount/token
    ssl.verification_mode: "none"

そして、Filebeatと同様に、必要な作業は、ElasticsearchクラスターのURLと資格情報を追加することだけです。

アプリケーションをデプロイする

前のブログのように、Cloud-Voting-Appをデプロイします。アプリケーションインターフェースはPython/Flaskを使用して構築されています。データコンポーネントはRedisを使用しています。アプリケーションがPrometheus Python Clientでインストルメントされ、Prometheusカスタムメトリックが公開されていることを思い出してください。今回はPrometheusがないにもかかわらず、どのようにしてメトリックカスタムメトリックを収集するのでしょうか。7.12以降では、Elastic APMエージェントを使用してカスタムPrometheusメトリックを収集できます

まず、アプリケーションでは「ElasticAPM」がインポートされ、Elastic APMエージェント設定の環境変数が使用されます。「SERVICE_NAME」はアプリケーションを識別するための任意の文字列です。「ENVIRONMENT」はアプリケーション環境を識別するための任意の文字列です。「SECRET_TOKEN」と「SERVER_URL」はAPMサーバーと通信するために使用されます。最後の「PROMETHEUS_METRICS」は、prometheus_clientからメトリックを取得するかどうかを示すパラメーターです。

from elasticapm.contrib.flask import ElasticAPM
...
app = Flask(__name__)
...
# Elastic APM 構成
app.config['ELASTIC_APM'] = {
# 必要なサービス名を設定します。使用できる文字:
# a-z、A-Z、0-9、-、_、スペース
'SERVICE_NAME': os.environ['SERVICE_NAME'],
#
# APMサーバーにトークンが必要な場合に使います
'SECRET_TOKEN': os.environ['SECRET_TOKEN'],
#
# カスタムのAPMサーバーURLを設定します(デフォルト:http://localhost:8200)
'SERVER_URL': os.environ['SERVER_URL'],
#
# 環境を設定する
'ENVIRONMENT': os.environ['ENVIRONMENT'],
#
# prometheus_metricsを設定する
'PROMETHEUS_METRICS': os.environ['PROMETHEUS_METRICS'],
}
apm = ElasticAPM(app)

次に、Cloud-Voting-AppをKubernetesクラスターにデプロイするためのマニフェストを示します。該当するファイルは「elastic/cloud-vote-all-in-one-redis-aks.yaml」にあります。特に、ユーザーインターフェース「cloud-vote-front」に関しては、前述のAPMエージェントに必要な変数が、コンテナー仕様で環境変数として設定されます。ここでは、ポッド固有の注釈は指定しません。このため、ログとメトリックはいずれもデフォルト設定を使用して取得されます。

apiVersion: apps/v1
kind:Deployment
metadata:
  name: cloud-vote-front
spec:
  replicas:1
  selector:
    matchLabels:
      app: cloud-vote-front
  strategy:
    rollingUpdate:
      maxSurge:1
      maxUnavailable:1
  minReadySeconds:5
  template:
    metadata:
      labels:
        app: cloud-vote-front
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      コンテナー:
      - name: cloud-vote-front
        image: your image name
        ports:
        - containerPort:80
        resources:
          requests:
            cpu:250m
          limits:
            cpu:500m
        env:
        - name:REDIS
          value: "cloud-vote-back"
        - name:SERVICE_NAME
          value: "cloud-voting"
        - name:SECRET_TOKEN
          value:"APM Server secret token"
        - name:SERVER_URL
          value:"APM Server URL"
        - name:ENVIRONMENT
          value:"Production"
        - name:PROMETHEUS_METRICS
          value:"True"

一方、バックエンドの「cloud-vote-redis」では、ポッド「annotations」を使用して、Filebeat redisモジュール(ログ)とMetricbeat redisモジュール(メトリック)を有効化し、すべての必要な設定を適用します。cloute-vote-frontでは、デフォルト設定を使用して、Beatsによってログとメトリックを収集します。Beatsは、ログとメトリックを収集するためのcloud-vote-back uses BeatsのRedisモジュールです。また、Beatsマニフェストではなく、アプリケーションマニフェストでログとメトリックを収集する方法を設定すると、開発チームとオブザーバビリティプラットフォームチームとの間で責任を分離することができます。

apiVersion: apps/v1
kind:Deployment
metadata:
  name: cloud-vote-back
spec:
  replicas:1
  selector:
    matchLabels:
      app: cloud-vote-back
  template:
    metadata:
      labels:
        app: cloud-vote-back
      annotations:
        co.elastic.logs/enabled: "true"
        co.elastic.logs/module: redis
        co.elastic.logs/fileset.stdout: log
        co.elastic.metrics/enabled: "true"
        co.elastic.metrics/module: redis
        co.elastic.metrics/hosts: "${data.host}:6379"
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      コンテナー:
      - name: cloud-vote-back
        image: redis
        ports:
        - containerPort:6379
          name: redis

Kibanaにアクセスする

すべての必要なコンポーネントがデプロイされました。Cloud-Voting-Appを使用して何回か投票を行ってから、Kibanaにアクセスしましょう。

オブザーバビリティの概要

まず、KibanaでElasticオブザーバビリティを開くと、何も操作をしなくても、Filebeatのログ入力のログレートと、Metricbeatのメトリック入力の要約が表示されます。これは、FilebeatとMetricbeatがデフォルトでECS形式でデータをインジェストするためです。

enter image description here

ログ

Filebeatによってインジェストされたログは、インデックスfilebeat-*に格納されます。Kibanaでログアプリを使用すると、Elasticsearchで収集されたすべてのログの検索、フィルター、末尾数行の表示ができます。また、特定の文字列をハイライトすることもできます。たとえば、次の例では、「cloud-vote-front」をハイライトしました。

enter image description here

メトリック

Metricbeatによってインジェストされたメトリックは、インデックスmetricbeat-*に格納されます。Kibanaのメトリックアプリでは、わかりやすい直感的な方法で、Elasticsearchで収集されたメトリックを表示できます。次のように、「Kubernetes Pods」ビューを使用すると、Kubernetesノードおよびポッドがマッピングされ、各リソースの使用方法が表示されます。

enter image description here

また、特定のポッドをクリックすると、コンテキストを維持しながら、ポッドログやAPMトレースなどの他のアプリに移動できます。「View details for kubernetes.pod.uid a47d81b1-02d7-481a-91d4-1db9fe82d7a7」が画面に表示されていることに注目してください。

enter image description here

[Kubernetesポッドログ]をクリックすると、このポッドのログに移動できます。ログアプリの検索バーには、すでに「kubernetes.pod.uid: a47d81b1-02d7-481a-91d4-1db9fe82d7a7」と入力されていることにお気付きでしょうか。Kibanaでは、この方法でコンテキストを維持することで、アプリ間をシームレスに遷移し、関連する結果を即座に返すことができます。

enter image description here

では、Prometheusカスタムメトリックには何が起こったのでしょうか。Prometheus Python Clientによって取得されたカスタムメトリックは、Elastic APMエージェント経由でインデックスapm-*に書き込まれます。Kibana Discoverで確認すると、「prometheus.metrics.cloud_votes」フィールドでメトリックが収集されていることがわかります。POSTリクエストの変数は「labels.vote」として格納されます。Elastic APM Pythonエージェントを使用したPrometheusカスタムメトリックの収集の詳細については、APMドキュメントを参照してください。

enter image description here

次のように、Kibana Lensを使用すると、簡単にapm-*インデックスを可視化できます。

enter image description here

あらかじめ定義されたダッシュボード

ここでは、Redisを使用した「cloud-vote-back」ポッドに関しては、FilebeatとMetricbeatの両方でRedisモジュールを有効化しました。これによって、関連する、設定不要のダッシュボードもあらかじめ作成されます。何も設定せずに、ただちにRedisログとメトリックを可視化できます。

enter image description here enter image description here

また、MetricbeatのKubernetesモジュールのおかげで、Kubernetesダッシュボードもすぐに使用できます。

enter image description here

##まとめ このブログでは、Elasticの機能をもっと駆使して、FilebeatとMetricbeatを使用し、Kubernetesを監視するためのログとメトリックをElastic Stackに入力する方法について説明しました。また、Elastic APMエージェントを使用して、Prometheusカスタムメトリックを取得する方法についても説明しました。Kubernetes環境の監視を今すぐ始めるには、Elastic Cloudの無料トライアルに登録するか、Elastic Stackをダウンロードしてご自身でホスティングしてください。Elasticオブザーバビリティでは、監視の効率と効果を高めることができます。また、Elastic機械学習とKibanaアラートと統合して、高度に自動化された、アクショナブルで包括的なオブザーバビリティを実現できます。お困りのことや、ご質問がおありの場合はディスカッションフォーラムをご活用ください。活発なコミュニティが待っています。

今後の続編のブログ記事では、Kubernetesの監視でElasticを利用する方法をもっと紹介しますので、ご期待ください。