ElasticとOpenTelemetryで実現、最先端を行くKubernetesのオブザーバビリティとセキュリティ

azure-kubernetes-720x420-2.png

Kubernetesを利用すると、その構造化特性により、サービスとアプリケーションのデプロイと管理を再現可能な方法でスケーラブルに行うことができます。そのため、Kubernetesは、さまざまな業界で、オンプレミスモデルとクラウドの両方のデプロイモデルで幅広く採用されるようになりました。しかし、Kubernetesの運用には自律的特性があるため、包括的な完全統合型のオブザーバビリティとセキュリティが必要です。現在、それが唯一可能なのはElasticプラットフォームです。

この記事では、ElasticsearchとOpenTelemetryを使用してKubernetes上のアプリケーションとサービスのワークフローを監視し、セキュリティを確保するためのベストプラクティスについて説明します。以下の方法を取り上げます。

  • KubernetesクラスターにElastic Agentをデプロイして構成する
  • Elastic Agentを使用して、OpenTelemetryアプリケーショントレース、メトリック、イベントを取り込む
  • Elastic Agentを使用して、Kubernetesコンテナーログ、クラスターメトリック、ネットワークトラフィックパターンを取り込む
  • Elastic Defendを使用して、Kubernetesクラスターにセキュリティ重視の監視と脅威保護を追加する
  • Elasticのすぐに使えるダッシュボードを詳しく知り、運用上の問題の監視、相関付け、根本原因分析を行えるようになる

Kubernetesデプロイのトラブルシューティング上の課題はデータサイロ

長い間、アプリケーションオブザーバビリティ、インフラストラクチャーオブザーバビリティ、インフラストラクチャーセキュリティはそれぞれ別の分野だと考えられており、異なるチームが異なるツールを使って対処していました。このモデルは、組織としては便利な場合が多いのですが、よくある問題や見えない障壁にすぐに直面することになります。

アナリスト(人間または機械)は、特定の運用上の問題が、インフラストラクチャーの問題なのか、アプリケーションの欠陥なのか、セキュリティ侵害なのかを判断するために、アプリケーションオブザーバビリティ、インフラストラクチャーオブザーバビリティ、インフラストラクチャーセキュリティの分野それぞれで収集したデータを参考にする必要があります。さらに、その問題の根本原因を探るために、これら3つの分野すべてで信頼性の高いデータにアクセスする必要もあります。

それらに対処するために、良質のオブザーバビリティデータが複数のデータプラットフォームで重複して使用されるという事態がよく起こります。うまくすれば、データ保存、サポート、トレーニングのコストが2-3倍になる程度で済みますが、最悪の場合、アナリストが根本原因を適切に解明するために必要な重要なデータを見落としてしまいます。このような事態は、Kubernetesの動的でスケーラブルな特性によってさらに悪化します。オブザーバビリティプラットフォームとセキュリティプラットフォームを分ける方法は、Kubernetesで実現できる統合型のサービスデプロイモデルに対するアンチパターンであると言えるでしょう。 

オブザーバビリティ実現の良いタイミング

突き詰めていくと、開発者、オペレーター、セキュリティアナリストは一様に、アプリケーションとインフラストラクチャーにまたがった、システムのエンドツーエンドの一元的なビューを必要としています。インフラストラクチャーデプロイチームは、可視性を実現し、クラスターのセキュリティを確保するために、一元化されたKubernetesネイティブのデプロイパターンを必要としています。

これを実現するには、以下の3つの条件があります。

  1. すべてのオブザーバビリティデータとセキュリティデータ(アプリケーション、サービス、インフラストラクチャーのログ、トレース、イベント、メトリックを含む)が、検索(相関付けとレイテンシ)と保存(コスト)の両方に最適化された方法で、一元化されたデータプラットフォームに保存されていること。
  2. 一元的なデータプラットフォームに、ロールベースでデータの相関付けと提示を行う機能があること。たとえば、アナリストが問題の根本原因を突き止めようとするケースでは、可能性の高い問題にアナリストを導き、データの元の形式やソースにかかわらず、アナリストがデータをシームレスに操作できる機能が必要です。
  3. アプリケーションとインフラストラクチャーのインストルメンテーションがKubernetesの指針(カスタム構成不要の、再現可能でスケーラブルなデプロイ)に合致していること。

Elastic:Kubernetesにうってつけ

Elastic、OpenTelemetry、Kubernetes、および最新のコンピューティングハードウェアによるテクノロジーの結集により、本格的なKubernetesネイティブのオブザーバビリティとセキュリティが実現可能になりました。

  • OpenTelemetryは、(社内、サードパーティ両方の)開発者にとって、APMの実装とAPMベンダーの選択を分離し、アプリケーションとサービスのすべてを完全にインストルメントする潤滑油となります。
  • 高性能のCPUと豊富なRAMを搭載した最新のコンピューティングハードウェアにより、リアルタイムアプリケーションのパフォーマンスにさえも影響が出ない"常時稼働"のトレースが現実になります。
  • 最新のElasticアーキテクチャー(検索可能スナップショットと新しい時系列データストリームを含む)とElastic APMのインテリジェントなtailベースのサンプリングが組み合わさることで、包括的なオブザーバビリティデータとセキュリティデータの複数年にわたるオンライン保存が実務面とコスト面の両方で現実的になります。
  • 各KubernetesノードのDaemonSetにElastic Agentをデプロイすると、リモート制御された一元的データコレクターの再現可能でスケーラブルなデプロイが可能になります。デプロイ後は、複数のElastic Agentをひとまとまりとして管理でき、簡単にデータ統合を追加、構成、削除できます。
  • ElasticプラットフォームにはKubernetesセキュリティソリューション(保護、監視、ポスチャー管理)が完全に統合されています。
  • Elasticsearchを使用すると、設定不要で使えるダッシュボード、異常検知、アラート機能により、収集元データソースすべてにまたがる相関付けとガイダンスが可能です。

データ収集モデル

以下の図に示すように、オブザーバビリティデータとセキュリティデータの収集には、ハイブリッドモデルをお勧めします。このモデルでは、Elastic Agentを使用してKubernetesインフラストラクチャーメトリックとアプリケーションコンテナーログを取得し、OpenTelemetry APMエージェントを使用してアプリケーショントレース、トレースイベント、メトリックを取得します。このアプローチをお勧めする理由は、以下で少し詳しく説明します。

アプリケーショントレース、イベント、メトリックデータ

アプリケーショントレースとメトリックを生成するには、通常、APMライブラリをアプリケーションコードに直接組み込む必要があります。APM導入にはベンダーロックインが障壁となりますが、OpenTelemetry APMエージェントを利用するとそれを回避できます。OpenTelemetryはこれまでに、アプリケーショントレースとトレースイベントをキャプチャできる強力で標準化されたエージェント実装を実現するために、多大な労力を費やしています。また、アプリケーションメトリックのサポートも新たに行うようになりました。現在では、ほぼすべての一般的なプログラミング言語に対して、かなり成熟したエージェントが存在します。多くの場合、自動インストルメンテーション機能を使用して、ほとんどあるいはまったくコーディングすることなく、アプリケーションをインストルメントできます。.NET、Java、NodeJS、またはPythonで作成し、一般的なフレームワークを使用しているアプリケーションの場合、OpenTelemetry Kubernetesオペレーターを使用して実行時にAPMライブラリを挿入することもできます。

根本原因を分析するには、APMデータをアプリケーションログとインフラストラクチャーメトリックに相関付ける必要があります。この相関付けを行うには、識別のための特定のメタデータまたはリソース属性がアプリケーションのトレースとログおよびインフラストラクチャーメトリックの間で共通していなければなりません。Elasticプラットフォームでは、service.name、pod.uidcontainer.idを使用して、Kubernetesで実行されているアプリケーションのオブザーバビリティデータを相関付けます。これまでは、このメタデータを取得するために、APMライブラリは外部を見にいっていました。この機能は現在、一部のOpenTelemetry APMライブラリ(Javaなど)でサポートされていますが、他のライブラリ(Rustなど)ではサポートされていません。このアプローチは、デプロイがシンプルになりますが、理想から程遠いことは明らかです。(アプリケーションのコンテキストで実行される)APMエージェントは、ランタイム環境(Docker、Kubernetesなど)を判断する必要があるだけでなく、その識別子にアクセスするための十分なアクセス権も必要だからです(例:/proc/self/cgroupやKubernetes APIへのアクセス権)。後者は、明らかにセキュリティ上の懸念事項です。こういった事情から、メタデータを(環境変数として)渡したり、トレースデータの作成後にメタデータを付加したりする際には、外部エンティティを利用するのが理想的です。使用するOpenTelemetry APMライブラリにかかわらずトレースデータにcontainer.idを確実に追加するために、Elasticでは、OpenTelemetry Collectorをデプロイし、ノードのDaemonSetでk8sattributesprocessorを実行します。

APMデータは、関連するKubernetesメタデータでタグを付けられた後、OpenTelemetry Collectorから(同じくノードのDaemonSetで実行されている)Elastic Agentに転送されます。Elastic Agentには、Fleetを通じてAPM統合が構成されています。APM統合を各ノードのDaemonSetに分散することで、APMインジェストの負荷を分散でき、その可用性とサポート対象のアプリケーションの結びつきがより密接になります。また、GRPC/HTTP2トラフィックがDaemonSet自体のローカルに保たれるので、複雑なGRPC/HTTP2ロードバランシングを回避できるというメリットもあります。さらなるメリットとして、セキュリティが簡素化されます。ノードとElasticsearchクラスターの間はFleetで管理するElastic Agent TLSセキュリティによって守られるので、OTLPがノード上で安全でなくても問題ありません。Elastic APM統合により、OpenTelemetryトレース、メトリック、イベントデータはElasticsearch Common Schema(ECS)に変換されます。その後、最終的なドキュメントがElasticsearchに送信され、インジェストされてインデックスされます。

コンテナーログとKubernetesインフラストラクチャーメトリック

OpenTelemetry規格はロギングをサポートしていますが、その実装はまだドラフト段階です。そのため、利用できるエージェントの多くは、ロギングフレームワークをフックする機能をまだサポートしていません。現実面では、コンテナーログファイルのインジェストが、アプリケーションのログデータをキャプチャする唯一の実用的な方法です。OpenTelemetry Collectorのfilelogreceiverを使うとそれが可能ですが、これは現在アルファリリースの段階であり、本番環境での使用にはまだお勧めしません。Kubernetesインフラストラクチャーメトリックのキャプチャを目的とするk8sclusterreceiverにも同じことが当てはまります。

それらと比較すると、Elastic Kubernetes統合は強力で、実績があり、アプリケーションログとKubernetesインフラストラクチャーメトリックを高い信頼性で収集します。さらに、Elastic Kubernetes統合はKibanaからまとめてリモートで管理できるので、構成が非常に簡単です。アプリケーションのトレースとメトリックとは異なり、Elastic Kubernetes統合はアプリケーションコードの外部で動作するため、ベンダーロックインの懸念が軽減されます。

それに加えて、各ノードのDaemonSetにElastic Agentが存在するため、Kubernetes統合以外にも大きな価値があります。この記事でも後ほど取り上げますが、これと同じElastic Agentインスタンスを利用してElastic Defendをデプロイし、Kubernetesノードを監視してセキュリティを確保できます。

セキュリティイベントとホストデータ

問題の根本原因をアナリストが特定するためには、最新のKubernetesのオブザーバビリティワークフローとセキュリティワークフローが密接に連携する必要があります。Elasticのセキュリティソリューションには、完全に統合された、高性能の、Kubernetes対応SIEMSOARXDRソリューション(エンドポイント保護を含む)があります。

注目すべきは、ElasticのDefend統合によって、大幅に強化されたKubernetesオブザーバビリティが提供されることです。また、ElasticのKubernetesセキュリティ態勢管理統合によって、アプリケーションの構成に潜在的な問題がある場合は、その問題をセキュリティチームが特定する前に、開発、DevOps、DevSecOpsチームに通知できます。さらに、Kubernetesセキュリティダッシュボードを使用すると、Kubernetesノードでどのようなプロセスが、いつ、どのようなランタイムパラメーターで、どのアカウントを使って実行されたのかを確認できます。このようにランタイムの状況を比類ないレベルで可視化されているため、コンテナー化したアプリケーションで依存関係として使用されるコンテナーレイヤーに発生する予期せぬセキュリティ脅威の検知が可能になります。

ElasticのAPM統合と同様に、このようなセキュリティ統合は、Fleetを使って追加、構成、削除ができ、Kubernetesクラスターの各ノード上のDaemonSetのElastic Agent内で実行されます。

実装に挑戦しよう

要件

まず、アプリ、Elastic Agent、OpenTelemetry Collectorのデプロイ先となるKubernetesクラスターが必要です。私は、ハイパースケーラーでテストクラスターの作成、管理、削除を簡単に行うことができるkOpsをよく使います。なお、AWS EC2 t3.xlargeを1つ用意すれば、OpenTelemetryデモとElastic Agentをデプロイするのに十分です。ここで使うサンプルは、セルフマネージドとマネージド(EKS、GKEなど)のどちらのKubernetesクラスターでも動作します。また、デプロイ先は大手ハイパースケーラーでも、オンプレミス(OpenShiftなど)でもかまいません。理論的には、デスクトップのKubernetesクラスター(MicroK8sやDockerの組み込みKubernetesエンジンなど)でも、その環境にRAMとCPUが十分(4 vCPU、16GB RAMなど)用意されていれば動作します。また、Kubernetesの管理に関する基礎知識(yamlのデプロイ、Podステータスの確認、Podのログファイルの表示など)も必要です。始める前に、Kubernetesコンテキストに適切なクラスターが設定されていることを確認します。

当然ですが、OpenTelemetryでインストルメントできるアプリケーションまたはサービスも必要になります。自分で用意しなくても、OpenTelemetry DemoのElasticのフォークを使い、それを元に、この記事で説明する、アプリケーションとサービスをインストルメントするためのベストプラクティスを試してもかまいません。

最後の要件は、最新(8.5以降)のElasticsearchデプロイにKubernetesアプリケーションクラスターからアクセスできることです(ElasticsearchデプロイはElastic Cloudで無料で作成できます)。

ツール

このチュートリアルでは、LinuxまたはMacOSベースのホストを使ってKubernetesクラスターを構成することを前提としています。以下のツールがインストールされていることを確認してください。

Elasticsearchクラスターを作成する

最新のElasticsearchデプロイがすでに使える状態の方は、準備万端です。準備がまだの方は、cloud.elastic.coで無料の試用版クラスターを作成してデプロイをセットアップしましょう。

  1. cloud.elastic.coに移動して無料トライアルに登録します(クレジットカードは不要です)。
  2. Elasticsearchクラスターに「o11y」などの名前を付けます。他の設定はデフォルト値のままにします。
  3. [Create Deployment](デプロイを作成)をクリックします。
  4. Elasticsearch Cloudに「Your deployment is ready!」(デプロイの準備が完了しました)と表示されるまで待ちます。
  5. [Continue](続行)をクリックしてKibanaにログインします。

DaemonSetにElastic Agentをデプロイする

データをElasticsearchに取り込むために、Kubernetesクラスターの各ノード上のDaemonSetにインストールされたElastic Agent(および統合)を使用します。

1. 以下のYAML(詳しくはこちら)をローカルマシンにダウンロードします。このYAMLを使用して、Elastic Agent(とElastic Defend)をKubernetesノードのDaemonSetにデプロイします。

curl -L -O https://raw.githubusercontent.com/elastic/endpoint/main/releases/8.5.0/kubernetes/deploy/elastic-defend.yaml 

2. ローカルマシンに以下のパッチをダウンロードします。このパッチは、デフォルトのElastic AgentコンテナーのRAMとCPUの割り当てを引き上げ、今後インストールするすべての統合に余裕を持って対応できるようにするためのものです。本番環境では、以下で取り上げる統合の一部だけをデプロイする判断をしてもかまいません。その場合、この変更を適用しなくても問題ありません。

curl -L -O https://raw.githubusercontent.com/ty-elastic/elastic-otel-k8s/main/agent/8.5.0/elastic-defend.yaml.patch 

3. パッチをインプレースで適用します。

patch elastic-defend.yaml elastic-defend.yaml.patch 

4. ElasticsearchクラスターのKibanaにログインしていることを確認します。

5. [Management](管理)の[Fleet]に移動します。

6. [Add agent](エージェントを追加)をクリックします。

7. 新しいポリシーに「k8s-apps」などの名前を付けます。 

  • この"k8s-apps"ポリシーは、アプリケーションKubernetesクラスターのノードのDaemonSetに統合をデプロイするために使用します。

8. [Advanced options](高度なオプション)の下にある[Unenrollment timeout](登録解除タイムアウト)を「3600」秒に設定します。 

  • Kubernetesではノードを動的に作成、削除できます。この設定を行うと、Elastic Agentのデプロイ先のノードが削除されたときに、エージェントが自動的に削除されます。

9. [Create policy](ポリシーを作成)をクリックします。

10. [Install Elastic Agent on your host](ホストにElastic Agentをインストール)の下で[Kubernetes]を選択します。

11. "FLEET_URL"変数の値を探してコピーし、以前ダウンロードしてパッチを適用した"elastic-defend.yaml"ファイルの"FLEET_URL"の値に貼り付けます。

12. "FLEET_ENROLLMENT_TOKEN"変数の値を探してコピーし、以前ダウンロードしてパッチを適用した"elastic-defend.yaml"ファイルの"FLEET_ENROLLMENT_TOKEN"の値に貼り付けます。

13. 以下のコマンドを実行して、elastic-defend.yamlをクラスターに適用します。

kubectl apply -f elastic-defend.yaml 

14. [Confirm agent enrollment](エージェント登録の確認)に"1 agent has been enrolled"(1個のエージェントが登録されました)と表示されるまで待ちます。

15. [Incoming data confirmed](受信データの確認)に"Incoming data received from 1 of 1 recently enrolled agent"(最近登録された1個のエージェントのうち1個から受信データを受け取りました)と表示されるのを待ちます。

16. [Close](閉じる)をクリックします。

Kubernetesホストオプションを選択したときに、Elasticに事前設定済みのElastic Agentデプロイ用YAMLが用意されていることに気付いたかもしれません。このデプロイYAMLには、Elastic Defendイメージがまだ含まれていません。

Elastic Agent統合をセットアップする

ここからは簡単な作業です。DaemonSetにデプロイされた、Fleetによる管理対象のElastic Agentは、Kibana統合インターフェースを使って統合の追加/構成/削除をリモートで簡単に行うことができます。

APM

Elastic APM統合は、OpenTelemetry APMデータをElasticにインポートするために使用します。

  1. Kibanaで[Management](管理)の[Integrations](統合)に移動します。
  2. 「APM」を検索します。
  3. [APM]をクリックします。
  4. [Manage APM integration in Fleet](FleetでAPM統合を管理)をクリックします。
  5. [Add Elastic APM](Elastic APMを追加)をクリックします。
  6. [General](全般)の[Server configuration](サーバー構成)にある[Host](ホスト)を「0.0.0.0:8200」に設定します(これでAPM統合の取り込みがノード上の他のPodに公開されます(同じくDaemonSetで実行されているOpenTelemetry Collectorを含む))。
  7. [Agent authorization](エージェント認証)の[Anonymous Agent access](匿名エージェントアクセス)を無効にします(このように簡素化することで、認可トークンなしでOpenTelemetry CollectorからElastic APM統合にOTELデータを送信できます。これのメリットは、APM統合がノード外部に公開されない点です)。
  8. (任意)[Tail-based sampling](tailベースのサンプリング)を有効にします(これにより、トレースデータのインテリジェントなサブサンプリングが可能になり、異常や全体的なパフォーマンスをキャプチャしながら、ストレージ要件を緩和できます)。
  9. [Where to add this integration](この統合の追加先)を[Existing hosts](既存のホスト)に設定し、[Agent policy](エージェントポリシー)を「k8s-apps」に設定します。
  10. [Save and continue](保存して続行)をクリックします。
  11. [Save and deploy changes](保存して変更をデプロイ)をクリックします。

Kubernetes

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

Kubernetes統合を行うには、kube-state-metricsをKubernetesクラスターで利用できるようにして、デフォルトのKubernetesダッシュボードを有効にする必要があります。

1. kube-state-metrics helmレポジトリを追加します。

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts 

helm repo update 

2. kube-state-metricsをKubernetesクラスターにインストールします。ネームスペースはElastic Agentと同じにします(Elastic Agentの前述のデプロイYAMLで使用したもの。デフォルトは"kube-system")。

helm install --set namespaceOverride=kube-system kube-state-metrics prometheus-community/kube-state-metrics 

Kubernetes統合をインストールする

Elastic Kubernetes統合は、KubernetesのメトリックとログをElasticsearchにインポートするために使用します。

  1. Kibanaで[Management](管理)の[Integrations](統合)に移動します。
  2. 「Kubernetes」を検索します。
  3. [Kubernetes]を選択します。
  4. [Add Kubernetes](Kubernetesを追加)をクリックします。
  5. [Collect Kubernetes metrics from kube-state-metrics](kube-state-metricsからKubernetesメトリックを収集)を有効にします(まだ設定していない場合)。
  6. [Where to add this integration](この統合の追加先)を[Existing hosts](既存のホスト)に設定し、[Agent policy](エージェントポリシー)を「k8s-apps」に設定します。
  7. [Save and continue](保存して続行)をクリックします。
  8. [Save and deploy changes](保存して変更をデプロイ)をクリックします。

Elastic Defend

Elastic Defend統合は、Kubernetesノードの保護と、セキュリティ重視のオブザーバビリティデータの追加収集に使用します。

  1. Kibanaで[Management](管理)の[Integrations](統合)に移動します。
  2. 「Elastic Defend」を検索します。
  3. [Elastic Defend]を選択します。
  4. [Add Elastic Defend](Elastic Defendを追加)をクリックします。
  5. [Integration name](統合名)を「defend-1」に設定します。
  6. [Select configuration settings](構成設定の選択)に移動して[Select the type of environment you want to protect](保護対象の環境の種類を選択)を[Cloud Workloads (Linux servers or Kubernetes environments)](クラウドワークロード(LinuxサーバーまたはKubernetes環境))に設定し、[To reduce data ingestion volume, select Interactive only](データインジェストボリュームを削減するには[Interactive only](インタラクティブのみ)を選択)を[All events](すべてのイベント)に設定します。
  7. [Where to add this integration](この統合の追加先)を[Existing hosts](既存のホスト)に設定し、[Agent policy](エージェントポリシー)を「k8s-apps」に設定します。
  8. KubernetesクラスターがGKEまたはEKS上で実行されていない場合は、[Advanced options](高度なオプション)で[Namespace](ネームスペース)を「k8sapps」などに設定します。この"k8sapps"は、アプリケーションKubernetesクラスターを識別します(これは、適用対象のKubernetesクラスターの名前でElastic Defendテレメトリーにタグを付けるために必要です)。
  9. [Save and continue](保存して続行)をクリックします。
  10. [Settings](設定)を選択します。
  11. [Elastic Defend version](Elastic Defendバージョン)に移動して[Keep integration policies up to date automatically](統合ポリシーを自動的に最新の状態に保つ)を有効にします。
  12. [Integration policies](統合ポリシー)を選択して、[defend-1]をクリックします。
  13. [Type: Operating system / Event Collection: Linux](タイプ:オペレーティングシステム/イベントコレクション:Linux)で[Capture terminal output](ターミナル出力をキャプチャ)を有効にします。
  14. [Save and continue](保存して続行)をクリックします。
  15. [Save and deploy changes](保存して変更をデプロイ)をクリックします。

特定のElasticsearch Kubernetesダッシュボードを使うには、Kubernetesクラスターの名前とIDを把握しておく必要があります。GKEまたはEKSでクラスターを実行している場合、Elastic Agentが自動的にこのメタデータを取得します。セルフマネージドKubernetesクラスターを実行している場合は、インジェストパイプラインを作成して、前の手順で定義したポリシーネームスペースから自動的に設定されるorchestrator.cluster.nameフィールドとorchestrator.cluster.idフィールドでセキュリティイベントを装飾できます。

  1. [Management](管理)の[Dev Tools](開発ツール)に移動します。
  2. 以下を実行します。
PUT _ingest/pipeline/logs-endpoint.events.process@custom
{
  "processors": [
    {
      "set": {
        "field": "orchestrator.cluster.name",
        "copy_from": "data_stream.namespace",
        "ignore_empty_value": true,
        "ignore_failure": true
      }
    },
    {
      "set": {
        "field": "orchestrator.cluster.id",  		
        "copy_from": "data_stream.namespace",
        "ignore_empty_value": true,
        "ignore_failure": true
      }
    }
  ]
}

Kubernetesセキュリティ態勢管理

Elastic Kubernetesセキュリティ態勢管理統合は、KubernetesクラスターとアプリケーションがCenter for Internet Security(CIS)で定義されている安全なKubernetes構成のベストプラクティスに従っているかどうかの検証に使用します。この統合により、セキュリティ侵害が発生する前に、開発チームやデプロイチームが誤設定を発見できるようになります。

  1. Kibanaで[Management](管理)の[Integrations](統合)に移動します。
  2. 「Kubernetes Security Posture Management」を検索します。
  3. [Kubernetes Security Posture Management](Kubernetesセキュリティ態勢管理)を選択します。
  4. [Add Kubernetes Security Posture Management](Kubernetesセキュリティ態勢管理を追加)をクリックします。
  5. [Kubernetes Deployment](Kubernetesデプロイ)を、セルフマネージドKubernetesの場合は[Unmanaged Kubernetes](アンマネージドKubernetes)に設定し、KubernetesアプリケーションクラスターをAWS EKSで実行している場合は[EKS (Elastic Kubernetes Service)]に設定します。
  6. [Where to add this integration](この統合の追加先)を[Existing hosts](既存のホスト)に設定し、[Agent policy](エージェントポリシー)を「k8s-apps」に設定します。
  7. [Save and continue](保存して続行)をクリックします。
  8. [Save and deploy changes](保存して変更をデプロイ)をクリックします。

ネットワークパケットキャプチャ

Elasticネットワークパケットキャプチャ統合は、Kubernetesノードで送受信されるネットワークトラフィックに関するインサイトを得るために使用します。

  1. Kibanaで[Management](管理)の[Integrations](統合)に移動します。
  2. 「Network Packet Capture」を検索します。
  3. [Network Packet Capture](ネットワークパケットキャプチャ)を選択します。
  4. [Add Network Packet Capture](ネットワークパケットキャプチャを追加)をクリックします。
  5. [Where to add this integration](この統合の追加先)を[Existing hosts](既存のホスト)に設定し、[Agent policy](エージェントポリシー)を「k8s-apps」に設定します。
  6. [Save and continue](保存して続行)をクリックします。
  7. [Save and deploy changes](保存して変更をデプロイ)をクリックします。

OpenTelemetryでインストルメントする

OpenTelemetry DemoOpenTelemetry Helm Chartsは、Elasticオブザーバビリティに合わせて最適化してあります(アプリケーションをインストルメントしてアプリケーションの変更内容と変更理由を把握する方法に関するドキュメント参照してください)。ElasticがKubernetesのオブザーバビリティとセキュリティにもたらす価値を確認するためにOpenTelemetryデモに含まれるアプリケーションだけを使用する場合は、OpenTelemetryデモのセットアップから始めてください。自分で用意したアプリケーションやサービスを監視したい場合は、アプリケーションのインストルメントに関する説明に従ってください。

OpenTelemetryデモをセットアップする

このセクションは、OpenTelemetryデモに含まれるインストルメント済みのアプリケーションをデプロイして監視することを前提としています。変更済みのOpenTelemetry Helm Chartsを使用します。これは、DemoアプリケーションとOpenTelemetry Collectorインスタンスの両方をデプロイします。

1. helmレポジトリを追加します。

helm repo add elastic-open-telemetry https://ty-elastic.github.io/opentelemetry-helm-charts 
helm repo update 

2. DemoアプリとCollectorをKubernetesクラスターにインストールします。

helm install elastic-otel elastic-open-telemetry/opentelemetry-demo 

3. 実行中のPodを一覧表示して、インストール結果を確認します。

kubectl get pods 

以下のように、すべてのOpenTelemetryデモのPodと1つのOpenTelemetry Collectorインスタンスが表示されるはずです。

> kubectl get pods
NAME                                                  READY   STATUS    RESTARTS   AGE
elastic-otel-adservice-86b5b4f779-8lsgf               1/1     Running   0          3h28m
elastic-otel-cartservice-55659bd5f4-lvtjx             1/1     Running   0          3h28m
elastic-otel-checkoutservice-88bfcf745-42nvt          1/1     Running   0          3h28m
elastic-otel-currencyservice-659dd55fc8-pcrrx         1/1     Running   0          3h28m
elastic-otel-emailservice-64df788455-mkb56            1/1     Running   0          3h28m
elastic-otel-featureflagservice-6dcf49d84c-n5jtk      1/1     Running   0          3h28m
elastic-otel-ffspostgres-67dcd7596d-htbpm             1/1     Running   0          3h28m
elastic-otel-frontend-674c8fdc74-zmv8r                1/1     Running   0          3h28m
elastic-otel-frontendproxy-5bd757dc89-r2728           1/1     Running   0          3h28m
elastic-otel-loadgenerator-5b98bd9656-8z8hz           1/1     Running   0          3h28m
elastic-otel-otelcol-agent-kbb54                      1/1     Running   0          3h28m
elastic-otel-paymentservice-5c4b5c57bd-wkbqj          1/1     Running   0          3h28m
elastic-otel-productcatalogservice-6995496975-7wm46   1/1     Running   0          3h28m
elastic-otel-quoteservice-849797dfdd-bkj29            1/1     Running   0          3h28m
elastic-otel-recommendationservice-6cb4476f-zpqqv     1/1     Running   0          3h28m
elastic-otel-redis-5698bf675b-dl2xv                   1/1     Running   0          3h28m
elastic-otel-shippingservice-6b9fdcc467-knlxb         1/1     Running   0          3h28m

4. 手順を検証と監視まで飛ばし、アプリケーショントレース、メトリック、イベントがElasticsearchに取り込まれていることを確認します。

OpenTelemetryでアプリケーションをインストルメントする

このセクションは、自分のアプリケーションをOpenTelemetryでインストルメントすることを前提としています。自分のアプリケーションがこの記事で示すデプロイモデルと連携するためには、アプリケーションに対して以下の作業が必要です。

  1. 安定したOpenTelemetry APM Agentリリースでインストルメントします。
  2. 特定のOpenTelemetry環境変数でインストルメントします。
  3. 手動でインストルメントする場合は、特定のspanプロパティを適切に設定します。
  4. (任意)ログ行に特定のメタデータを追加します。
  5. ログデータをstdoutとstderrに対して生成して、Elastic Kubernetes統合でキャプチャされるようにします。

コンテナー環境変数

Elasticにデフォルトで用意されているAPMダッシュボードを有効にするには、アプリケーショントレース、メトリック、イベントに適切なコンテキストメタデータが含まれている必要があります。このメタデータは、Kubernetes Downward APIから取得して、OTEL_RESOURCE_ATTRIBUTES環境変数を通じてメタデータをアプリケーションに渡すことができます。

また、OTEL_EXPORTER_OTLP_ENDPOINTを設定して、OpenTelemetryデータをOTLPを通じてOpenTelemetry Collectorインスタンスに送信するようにアプリケーションに対して指示する必要もあります。このOpenTelemetry Collectorは後ほど、ノードのDaemonSetにデプロイします。

以下のKubernetesコンテナー構成スニペットを使うと、デプロイYAMLでアプリケーションに適用する必要のある環境変数がセットアップされます。

---
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    ...
    spec:
      containers:
        ...
        env:
          - name: OTEL_K8S_CONTAINER_NAME
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: "metadata.labels['app.kubernetes.io/component']"
          - name: OTEL_K8S_NODE_IP
            valueFrom:
              fieldRef:
                fieldPath: status.hostIP
          - name: OTEL_K8S_POD_UID
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: metadata.uid
          - name: OTEL_K8S_POD_IP
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: status.podIP
          - name: OTEL_SERVICE_NAME
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: "metadata.labels['app.kubernetes.io/component']"
          - name: OTEL_K8S_NAMESPACE
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: metadata.namespace
          - name: OTEL_K8S_NODE_NAME
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: spec.nodeName
          - name: OTEL_K8S_POD_NAME
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: metadata.name
          - name: OTEL_EXPORTER_OTLP_ENDPOINT
            value: '$(OTEL_K8S_NODE_IP):4317'
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: service.name=$(OTEL_SERVICE_NAME),k8s.namespace.name=$(OTEL_K8S_NAMESPACE),k8s.node.name=$(OTEL_K8S_NODE_NAME),k8s.pod.name=$(OTEL_K8S_POD_NAME),k8s.pod.uid=$(OTEL_K8S_POD_UID),k8s.pod.ip=$(OTEL_K8S_POD_IP),k8s.container.name=$(OTEL_K8S_CONTAINER_NAME),k8s.container.restart_count=0

リソース属性の1つとしてk8s.container.restart_count=0を設定している理由が気になるかもしれません。現在のOpenTelemetry Collectorのk8sattributesprocessorが、コンテナーと実行中のコンテナーインスタンスを(k8s.container.nameを通じて)照合して、container.idを取得するために、この部分が必要です。k8s.container.restart_count=0を設定するのは単純化のためです。というのも、Pod内で特定のコンテナーがKubernetesによって再起動された回数を追跡して、それを何らかの形で環境変数に設定するのは厄介な作業だからです。通常のシナリオでは、Podの有効期間中、コンテナーは1回しか起動されません。Podによってコンテナーが再起動される場合、この単純化は失敗します。

Spanプロパティ

Elastic APMは、spanデータを適切に特徴付け、分類し、可視化するために、特定のspanプロパティが正確に設定されている必要があります。ほとんどのOpenTelemetry APM自動インストルメンテーションライブラリでは、それらのフィールドが自動的に設定されます。アプリケーションを手動でインストルメントする場合は、次のプロパティを正確に設定する必要があります。SpanKind:Elastic APMが適切にspanを分類するためには、SpanKind(INTERNAL、SERVER、CLIENTなど)を把握する必要があります。ほとんどのOpenTelemetry APM自動インストルメンテーションライブラリでは、このフィールドが自動的に設定されます。しかし、アプリケーションを手動でインストルメントする場合は、RPCまたはREST呼び出しを受け取るspanのSpanKindはSERVERに、RPC、REST、またはデータベース呼び出しを開始するspanのSpanKindはCLIENTに、サービス内の関数呼び出しはINTERNAL(デフォルト)に設定する必要があります。たとえば、Javaの場合、以下のようなコードを使用して、gRPC呼び出しを受け取るspanのSpanKindをSERVERに設定します。

Span span = tracer.spanBuilder("testsystem.TestService/TestFunction").setSpanKind(SpanKind.SERVER).startSpan();

RpcSystem/DbSystem:Elastic APMが適切にspanを分類するためには、そのspanが表しているのがRPCトランザクションなのかデータベーストランザクションなのか、加えて、どのような種類のRPCまたはDBシステムが使われているのかを把握する必要があります。ほとんどのOpenTelemetry APM自動インストルメンテーションライブラリでは、このフィールドが自動的に設定されます。アプリケーションを手動でインストルメントする場合は、RpcSystemまたはDbSystem span属性を設定する必要があります。たとえば、Rustの場合、以下のようなものを使用して、gRPC呼び出しを受け取るspanのRpcSystemを"grpc"に設定します。

span.set_attribute(semcov::trace::RPC_SYSTEM.string("grpc"));

NetPeerHostとNetPeerPort:Elastic APMがサービス間の依存関係を適切にマップするためには、SpanKindがCLIENTに設定されている場合(つまり、gRPCまたはデータベース呼び出しを送信する場合)、NetPeerNameおよびNetPeerPort span属性を設定して、想定する呼び出しの受信側を示す必要があります。一部のOpenTelemetry APM自動インストルメンテーションライブラリでは、このフィールドが自動的に設定されます。アプリケーションを手動でインストルメントする場合は、これらの属性を明示的に設定する必要があります。たとえば、JavaScriptの場合、以下のようなコードを使用して、gRPC呼び出しを送信するspanのNetPeerNameとNetPeerPortを設定します。

// this => grpcJs.Client, this.getChannel().getTarget() => "dns:elastic-otel-productcatalogservice:8080"
const URI_REGEX = /(?:([A-Za-z0-9+.-]+):(?:\/\/)?)?(?<name>[A-Za-z0-9+.-]+):(?<port>[0-9+.-]+)$/;
const parsedUri = URI_REGEX.exec(this.getChannel().getTarget());        
if (parsedUri != null && parsedUri.groups != null) {
    span.setAttribute(SemanticAttributes.NET_PEER_NAME, parsedUri.groups['name']);
    span.setAttribute(SemanticAttributes.NET_PEER_PORT, parseInt(parsedUri.groups['port']));
}

ログ属性

Elastic APMは、特定のログ行を特定のトレースに相関付けることができます。この機能を有効にするには、アプリケーションで生成されるログ行にspan.idとtrace.idのキーバリューペア(状況に応じて)でタグを付ける必要があります。一部のElastic APM Agent(Javaエージェントなど)は、自動的にロギングテンプレートを変更して、このコンテキストに応じたメタデータを追加します。

OpenTelemetry CollectorをDaemonSetにデプロイする

OpenTelemetryデモと変更済みのOpenTelemetry Helm Chartsを使用している場合、OpenTelemetry Collectorは各ノードのDaemonSetにすでにインストールされています。

自分でアプリケーションをインストルメントする場合、以下のYAMLをベースにOpenTelemetry Collectorを構成し、クラスターに含まれるノードのDaemonSetにデプロイできます。このサンプル構成(ConfigMapを使用してデプロイ)は、アプリケーションのOTLPトレース、メトリック、イベントデータをTCPポート4317(grpc)と4318(http)で取り込みます。CollectorはDaemonSetで実行されているので、そのポートには、同じノード上で実行される他のPodからもノードのIPを通じてアクセスできます。受信OTLPデータは、k8sattributesprocessorを経由して、container.idが追加されます。受信するログデータはすべて破棄し(このデータはElastic Kubernetes統合を通じて取得していることを思い出してください)、トレース、イベントメトリックは同じくDaemonSetで実行されているElastic APM統合にパススルーします。Elastic APM統合はポート8200でリッスンしています。このポートも、ノードのIPを通じてアクセスできます(Kubernetes Downward APIから取得した環境変数としてここに渡されます)。

1. このサンプルOpenTelemetry CollectorデプロイYAMLをダウンロードします。

curl -L -O https://raw.githubusercontent.com/ty-elastic/elastic-otel-k8s/main/collector/otel-collector.yaml 

2. デプロイにあわせて適宜編集します。

3. Kubernetesクラスターに適用します。

kubectl apply -f otel-collector.yaml 

検証と監視

このセクションでは、上記で構成したオブザーバビリティとセキュリティデータが期待どおりにElasticsearchクラスターに送信されているかどうかを検証します。この作業には、Elasticsearchにデフォルトで用意されているオブザーバビリティとセキュリティダッシュボードのいくつかをざっと確認する役割もあります。ぜひ、この作業を通じて、Elasticのリッチな可視化と分析機能を体験してください。

APMサービスマップ

APMサービスマップでは、サービスとサービス間の関係が可視化されます。サービスで発生した特定の種類のエラーとアラートがこのマップ上で必要に応じてハイライトされます。このマップを起点に、OpenTelemetry(またはElastic独自のAPMエージェント)でインストルメントされたサービスを詳細に確認できます。

  1. Kibanaのナビゲーションサイドバーで、[Observability](オブザーバビリティ)の下にある[APM]を選択します。
  2. [APM]の下にある[Service Map](サービスマップ)を選択します。
Video thumbnail

APMサービス

APMサービスビューには、特定のサービスの概要が表示されます。このダッシュボードで、トレース、ログ、関連するインフラストラクチャーメトリックを簡単にドリルダウンできます。従来は、それらのデータソースの間を大ざっぱに相関付けるには、サイロ化した複数のオブザーバビリティプラットフォームのタイムスタンプとサービス識別子を手動で変換する必要がありました。ElasticとOpenTelemetryを組み合わせると、この相関付けが自動的に行われます。それにより、アナリスト、オペレーター、開発者は、オブザーバビリティツールの微妙な差異に煩わされることなく、根本原因の分析に集中できます。

  1. Kibanaのナビゲーションサイドバーで、[Observability](オブザーバビリティ)の下にある[APM]を選択します。
  2. [APM]の下にある[Service Map](サービスマップ)を選択します。
  3. マップ内の任意のサービスを右クリックします。
  4. [Service Details](サービスの詳細)を選択します。
Video thumbnail

この同じビューで、ユーザーとサービスをつないだり、サービスを相互につないだりして、トランザクションやspanを簡単に調べることができます。

  1. ヘッダーの[Transactions](トランザクション)を選択します。
  2. [Transactions](トランザクション)サブセクションで、調べたいトランザクションを選択します。
Video thumbnail

Kubernetesクラスターのメトリック

Elastic Kubernetesダッシュボードでは、Kubernetesクラスターの運用状況の概要と詳細の両方を確認できます。このダッシュボードで、クラスター、ノード、Pod、DaemonSet、サービスなどのメトリックを監視できます。

  1. Kibanaのナビゲーションサイドバーで、[Analytics](分析)の下にある[Dashboard](ダッシュボード)を選択します。
  2. [Tags](タグ)メニューから[Kubernetes]を選択します。
  3. [Cluster Overview](クラスターの概要)ダッシュボードを選択します。
Video thumbnail

Kubernetesプロセスの監視

Elastic Defend統合により、Kubernetesリソース全体にわたるセキュリティ重視のオブザーバビリティが実現します。Kubernetesセキュリティダッシュボードを使用すると、Kubernetesノードでどのようなプロセスが、いつ、どのようなランタイムパラメーターで、どのアカウントを使って実行されたのかを確認できます。

  1. Kibanaのナビゲーションサイドバーで、[Security](セキュリティ)の下にある[Dashboards](ダッシュボード)を選択します。
  2. [Kubernetes]を選択します。

Video thumbnail

Kubernetesセキュリティ態勢管理

Kubernetesセキュリティ態勢管理(KSPM)ダッシュボードは、セキュアなデプロイのためのKubernetesのベストプラクティスに従っているかどうかを自動的に分析し、修正するための推奨事項を提示します。開発者とDevOps担当者は、このダッシュボードから、本番環境で問題が発生する前に、潜在的な構成の問題を示す貴重な注意喚起を得ることができます。

  1. Kibanaのナビゲーションサイドバーで、[Security](セキュリティ)の下にある[Dashboards](ダッシュボード)を選択します。
  2. [Cloud Posture](クラウドポスチャー)を選択します。
Video thumbnail

ネットワークトラフィック分析

ネットワークパケットキャプチャ統合を使用すると、Kubernetesノードで送受信されるIPトラフィックを詳しく調査して、異常な動作をしているサービスやセキュリティ侵害を見付けることができます。

  1. Kibanaのナビゲーションサイドバーで、[Security](セキュリティ)の下にある[Explore](調査)を選択します。
  2. [Network](ネットワーク)を選択します。

Video thumbnail

Elastic:Kubernetesのためのオブザーバビリティとセキュリティ

Kubernetesは、多くの企業にとってグリーンフィールドアプリケーションのデプロイモデルとなります。グリーンフィールドデプロイモデルには、でオブザーバビリティとセキュリティに対する、公平で偏りがなく、先進的かつ包括的なアプローチが必要です。ここで説明したように、Elasticプラットフォームは、完全に統合され、機能が充実し、高精度のオブザーバビリティとセキュリティをKubernetesに提供する能力を、業界で唯一備えています。

詳細についてご興味をお持ちの場合、Elasticのプリセールスチームにお問い合わせください。Elasticを利用した開発を始めましょう。