Isovalent Enterprise Platform と Splunk Observability Cloud の統合
105 minutes Author Alec Chamberlainこのワークショップでは、Isovalent Enterprise Platform と Splunk Observability Cloud の統合を実演し、eBPFテクノロジーを使用してKubernetesのネットワーキング、セキュリティ、ランタイム動作の包括的な可視性を提供する方法を説明します。
学習内容
このワークショップを完了すると、以下のことができるようになります:
- ENIモードでCiliumをCNIとして使用するAmazon EKSをデプロイする
- L7可視性を備えたネットワークオブザーバビリティのためのHubbleを設定する
- ランタイムセキュリティ監視のためのTetragonをインストールする
- OpenTelemetryを使用してeBPFベースのメトリクスをSplunk Observability Cloudと統合する
- 統合ダッシュボードでネットワークフロー、セキュリティイベント、インフラストラクチャメトリクスを監視する
- eBPFによるオブザーバビリティとkube-proxyの置き換えを理解する
セクション
- 概要 - CiliumアーキテクチャとeBPFの基礎を理解する
- 前提条件 - 必要なツールとアクセス権
- EKS セットアップ - Cilium用のEKSクラスターを作成する
- Cilium インストール - Cilium、Hubble、Tetragonをデプロイする
- Splunk 統合 - メトリクスをSplunk Observability Cloudに接続する
- 検証 - 統合を検証する
- デモスクリプト - エンドツーエンドのDNS調査シナリオをウォークスルーする
ヒント
この統合は、Linuxカーネル内で直接、高性能で低オーバーヘッドのオブザーバビリティを実現するためにeBPF(Extended Berkeley Packet Filter)を活用しています。
前提条件
- 適切な認証情報で設定されたAWS CLI
- kubectl、eksctl、Helm 3.xがインストールされていること
- EKSクラスター、VPC、EC2インスタンスを作成する権限を持つAWSアカウント
- アクセストークンを持つSplunk Observability Cloudアカウント
- 完全なセットアップに約90分
統合のメリット
Isovalent Enterprise PlatformをSplunk Observability Cloudに接続することで、以下のメリットが得られます:
- 🔍 深い可視性: ネットワークフロー、L7プロトコル(HTTP、DNS、gRPC)、ランタイムセキュリティイベント
- 🚀 高パフォーマンス: 最小限のオーバーヘッドでeBPFベースのオブザーバビリティを実現
- 🔐 セキュリティインサイト: プロセス監視、システムコールトレーシング、ネットワークポリシーの適用
- 📊 統合ダッシュボード: Cilium、Hubble、TetragonのメトリクスをインフラストラクチャおよびAPMデータと並べて表示
- ⚡ 効率的なネットワーキング: kube-proxyの置き換えとENIモードによるネイティブVPCネットワーキング
ソースリポジトリ
このワークショップで参照されるすべての設定ファイル、Helm values、ダッシュボードJSONファイルは、以下のリポジトリで入手できます:
- isovalent_splunk_o11y — Helm values、OTel Collector設定、SplunkダッシュボードJSONファイル、および完全な統合ガイド
- isovalent-demo-jobs-app — デモシナリオで使用されるjobs-app Helm chart(エラーインジェクションと修復スクリプトを含む)
ステップ 1: Cilium Enterprise の設定 cilium-enterprise-values.yaml という名前のファイルを作成します。
を前のステップで取得したエンドポイントに置き換えてください(https:// プレフィックスは除きます)。 Enable/disable debug logging debug: enabled: false verbose: ~ # Configure unique cluster name & ID cluster: name: isovalent-demo id: 0 # Configure ENI specifics eni: enabled: true updateEC2AdapterLimitViaAPI: true # Dynamically fetch ENI limits from EC2 API awsEnablePrefixDelegation: true # Assign /28 CIDR blocks per ENI (16 IPs) instead of individual IPs enableIPv4Masquerade: false # Pods use their real VPC IPs — no SNAT needed in ENI mode loadBalancer: serviceTopology: true # Prefer backends in the same AZ to reduce cross-AZ traffic costs ipam: mode: eni routingMode: native # No overlay tunnels — traffic routes natively through VPC # BPF / KubeProxyReplacement # Cilium replaces kube-proxy entirely with eBPF programs in the kernel. # This requires a direct path to the API server, hence k8sServiceHost. kubeProxyReplacement: “true” k8sServiceHost:
k8sServicePort: 443 # TLS for internal Cilium communication tls: ca: certValidityDuration: 3650 # 10 years for the CA cert # Hubble: network observability built on top of Cilium’s eBPF datapath hubble: enabled: true metrics: enableOpenMetrics: true # Use OpenMetrics format for better Prometheus compatibility enabled: # DNS: query/response tracking with namespace-level label context - dns:labelsContext=source_namespace,destination_namespace # Drop: packet drop reasons (policy deny, invalid, etc.) per namespace - drop:labelsContext=source_namespace,destination_namespace # TCP: connection state tracking (SYN, FIN, RST) per namespace - tcp:labelsContext=source_namespace,destination_namespace # Port distribution: which destination ports are being used - port-distribution:labelsContext=source_namespace,destination_namespace # ICMP: ping/traceroute visibility with workload identity context - icmp:labelsContext=source_namespace,destination_namespace;sourceContext=workload-name|reserved-identity;destinationContext=workload-name|reserved-identity # Flow: per-workload flow counters (forwarded, dropped, redirected) - flow:sourceContext=workload-name|reserved-identity;destinationContext=workload-name|reserved-identity # HTTP L7: request/response metrics with full workload context and exemplars for trace correlation - “httpV2:exemplars=true;labelsContext=source_ip,source_namespace,source_workload,destination_namespace,destination_workload,traffic_direction;sourceContext=workload-name|reserved-identity;destinationContext=workload-name|reserved-identity” # Policy: network policy verdict tracking (allowed/denied) per workload - “policy:sourceContext=app|workload-name|pod|reserved-identity;destinationContext=app|workload-name|pod|dns|reserved-identity;labelsContext=source_namespace,destination_namespace” # Flow export: enables Hubble to export flow records to Timescape for historical storage - flow_export serviceMonitor: enabled: true # Creates a Prometheus ServiceMonitor for auto-discovery tls: enabled: true auto: enabled: true method: cronJob # Automatically rotate Hubble TLS certs on a schedule certValidityDuration: 1095 # 3 years per cert rotation relay: enabled: true # Hubble Relay aggregates flows from all nodes cluster-wide tls: server: enabled: true prometheus: enabled: true serviceMonitor: enabled: true timescape: enabled: true # Stores historical flow data for time-travel debugging # Cilium Operator: cluster-wide identity and endpoint management operator: prometheus: enabled: true serviceMonitor: enabled: true # Cilium Agent: per-node eBPF datapath metrics prometheus: enabled: true serviceMonitor: enabled: true # Cilium Envoy: L7 proxy metrics (HTTP, gRPC) envoy: prometheus: enabled: true serviceMonitor: enabled: true # Enable the Cilium agent to hand off DNS proxy responsibilities to the # external DNS Proxy HA deployment, so policies keep working during upgrades extraConfig: external-dns-proxy: “true” # Enterprise feature gates — these must be explicitly approved enterprise: featureGate: approved: - DNSProxyHA # High-availability DNS proxy (installed separately) - HubbleTimescape # Historical flow storage via Timescape ラベルコンテキストが重要な理由 各Hubbleメトリクスの labelsContext および sourceContext/destinationContext パラメータは、メトリクスをどのディメンションで分割するかを制御します。labelsContext=source_namespace,destination_namespace を設定すると、すべてのメトリクスにこれら2つのラベルが付与され、カーディナリティの爆発を起こすことなくSplunkでnamespaceによるフィルタリングが可能になります。workload-name|reserved-identity のフォールバックチェーンは、利用可能な場合はワークロード名を使用し、利用できない場合はセキュリティIDにフォールバックすることを意味します。 - 概要 Splunk OpenTelemetry Collectorは、Prometheusレシーバーを使用してすべてのIsovalentコンポーネントからメトリクスをスクレイプします。各コンポーネントは異なるポートでメトリクスを公開しており、CiliumとHubbleは同じPodを共有しています(ポートが異なるだけです)。そのため、Podアノテーションに依存するのではなく、各コンポーネントに対して個別のレシーバーを設定します。 コンポーネント ポート 提供する情報 Cilium Agent 9962 eBPF データパス、ポリシー適用、IPAM、BPF マップ統計 Cilium Envoy 9964 L7 プロキシメトリクス(HTTP、gRPC) Cilium Operator 9963 クラスター全体のアイデンティティとエンドポイント管理 Hubble 9965 ネットワークフロー、DNS、HTTP L7、TCP フラグ、ポリシー判定 Tetragon 2112 ランタイムセキュリティ、ソケット統計、ネットワークフローイベント ステップ 1: 設定ファイルの作成 splunk-otel-collector-values.yaml という名前のファイルを作成します。認証情報のプレースホルダーを実際の値に置き換えてください。 terminationGracePeriodSeconds: 30 agent: config: extensions: # k8s_observer watches the Kubernetes API for pod and port changes. # This enables automatic service discovery without static endpoint lists. k8s_observer: auth_type: serviceAccount observe_pods: true receivers: kubeletstats: collection_interval: 30s insecure_skip_verify: true # Cilium Agent (port 9962) and Hubble (port 9965) both run in the # same DaemonSet pod, identified by label k8s-app=cilium. # We use two separate scrape jobs because they’re on different ports. prometheus/isovalent_cilium: config: scrape_configs: - job_name: ‘cilium_metrics_9962’ scrape_interval: 30s metrics_path: /metrics kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_k8s_app] action: keep regex: cilium - source_labels: [__meta_kubernetes_pod_ip] target_label: address replacement: ${__meta_kubernetes_pod_ip}:9962 - target_label: job replacement: ‘cilium_metrics_9962’ - job_name: ‘hubble_metrics_9965’ scrape_interval: 30s metrics_path: /metrics kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_k8s_app] action: keep regex: cilium - source_labels: [__meta_kubernetes_pod_ip] target_label: address replacement: ${__meta_kubernetes_pod_ip}:9965 - target_label: job replacement: ‘hubble_metrics_9965’ # Cilium Envoy uses a different pod label (k8s-app=cilium-envoy) prometheus/isovalent_envoy: config: scrape_configs: - job_name: ’envoy_metrics_9964’ scrape_interval: 30s metrics_path: /metrics kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_k8s_app] action: keep regex: cilium-envoy - source_labels: [__meta_kubernetes_pod_ip] target_label: address replacement: ${__meta_kubernetes_pod_ip}:9964 - target_label: job replacement: ‘cilium_metrics_9964’ # Cilium Operator is a Deployment (not DaemonSet), identified by io.cilium.app=operator prometheus/isovalent_operator: config: scrape_configs: - job_name: ‘cilium_operator_metrics_9963’ scrape_interval: 30s metrics_path: /metrics kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_io_cilium_app] action: keep regex: operator - target_label: job replacement: ‘cilium_metrics_9963’ # Tetragon is identified by app.kubernetes.io/name=tetragon prometheus/isovalent_tetragon: config: scrape_configs: - job_name: ’tetragon_metrics_2112’ scrape_interval: 30s metrics_path: /metrics kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name] action: keep regex: tetragon - source_labels: [__meta_kubernetes_pod_ip] target_label: address replacement: ${__meta_kubernetes_pod_ip}:2112 - target_label: job replacement: ’tetragon_metrics_2112’ processors: # Strict allowlist filter: only forward metrics we’ve explicitly named. # Without this, Cilium and Tetragon can generate thousands of metric series # and overwhelm Splunk Observability Cloud with cardinality. filter/includemetrics: metrics: include: match_type: strict metric_names: # — Kubernetes base metrics — - container.cpu.usage - container.memory.rss - k8s.container.restarts - k8s.pod.phase - node_namespace_pod_container - tcp.resets - tcp.syn_timeouts # — Cilium Agent metrics — # API rate limiting — detect if the agent is being throttled - cilium_api_limiter_processed_requests_total - cilium_api_limiter_processing_duration_seconds # BPF map utilization — alerts when eBPF maps are near capacity - cilium_bpf_map_ops_total # Controller health — tracks background reconciliation tasks - cilium_controllers_group_runs_total - cilium_controllers_runs_total # Endpoint state — how many pods are in each lifecycle state - cilium_endpoint_state # Agent error/warning counts — early warning for problems - cilium_errors_warnings_total # IP address allocation tracking - cilium_ip_addresses - cilium_ipam_capacity # Kubernetes event processing rate - cilium_kubernetes_events_total # L7 policy enforcement (HTTP, DNS, Kafka) - cilium_policy_l7_total # DNS proxy latency histogram — key metric for catching DNS saturation - cilium_proxy_upstream_reply_seconds_bucket # — Hubble metrics — # DNS query and response counts — primary indicator in the demo scenario - hubble_dns_queries_total - hubble_dns_responses_total # Packet drops by reason (policy_denied, invalid, TTL_exceeded, etc.) - hubble_drop_total # Total flows processed — overall network activity volume - hubble_flows_processed_total # HTTP request latency histogram and total count - hubble_http_request_duration_seconds_bucket - hubble_http_requests_total # ICMP traffic tracking - hubble_icmp_total # Policy verdict counts (forwarded vs. dropped by policy) - hubble_policy_verdicts_total # TCP flag tracking (SYN, FIN, RST) — connection lifecycle visibility - hubble_tcp_flags_total # — Tetragon metrics — # Total eBPF events processed - tetragon_events_total # DNS cache health - tetragon_dns_cache_evictions_total - tetragon_dns_cache_misses_total - tetragon_dns_total # HTTP response tracking with latency - tetragon_http_response_total - tetragon_http_stats_latency_bucket - tetragon_http_stats_latency_count - tetragon_http_stats_latency_sum # Layer3 errors - tetragon_layer3_event_errors_total # TCP socket statistics — per-connection RTT, retransmits, byte/segment counts # These power the latency and throughput views in Network Explorer - tetragon_socket_stats_retransmitsegs_total - tetragon_socket_stats_rxsegs_total - tetragon_socket_stats_srtt_count - tetragon_socket_stats_srtt_sum - tetragon_socket_stats_txbytes_total - tetragon_socket_stats_txsegs_total - tetragon_socket_stats_rxbytes_total # UDP statistics - tetragon_socket_stats_udp_retrieve_total - tetragon_socket_stats_udp_txbytes_total - tetragon_socket_stats_udp_txsegs_total - tetragon_socket_stats_udp_rxbytes_total # Network flow events (connect, close, send, receive) - tetragon_network_connect_total - tetragon_network_close_total - tetragon_network_send_total - tetragon_network_receive_total resourcedetection: detectors: [system] system: hostname_sources: [os] service: pipelines: metrics: receivers: - prometheus/isovalent_cilium - prometheus/isovalent_envoy - prometheus/isovalent_operator - prometheus/isovalent_tetragon - hostmetrics - kubeletstats - otlp processors: - filter/includemetrics - resourcedetection autodetect: prometheus: true clusterName: isovalent-demo splunkObservability: accessToken:
realm: # e.g. us1, us2, eu0 profilingEnabled: true cloudProvider: aws distribution: eks environment: isovalent-demo # Gateway mode runs a central collector deployment that receives from all agents. # Agents send to the gateway, which handles batching and export to Splunk. # This reduces the number of direct connections to Splunk’s ingest endpoint. gateway: enabled: true resources: requests: cpu: 250m memory: 512Mi limits: cpu: 1 memory: 1Gi # certmanager handles mTLS between the OTel Collector agent and gateway certmanager: enabled: true 重要: 以下を置き換えてください: - このデモで示すこと このデモは、すべての運用チームやプラットフォームチームが経験したことのあるストーリーを語ります。何かが壊れていて、ユーザーが不満を訴えていて、どこから始めればよいかわからない状況です。調査は通常の最初のステップを経由します — APMは問題なさそう、インフラストラクチャも問題なさそう — そしてネットワーク層へとピボットします。そこでIsovalentのHubbleオブザーバビリティがSplunkに流れ込み、本当の問題を明らかにします。それは他のすべてのツールからは完全に見えなかったDNS過負荷です。 アプリケーションは jobs-app で、tenant-jobs namespaceで実行されるシミュレートされたマルチサービスの採用プラットフォームです。フロントエンド(recruiter、jobposting)、中央API(coreapi)、バックグラウンドデータパイプライン(Kafka + resumes + loader)、および定期的にインターネットへHTTP呼び出しを行う crawler サービスがあります。このcrawlerがこのストーリーの悪役になります。 重要なポイント APMとインフラストラクチャのメトリクスは正常に見えます。根本原因であるDNS過負荷は、アプリケーション層より下に存在するため、SplunkのIsovalent Hubbleダッシュボードを通じてのみ見ることができます。 開始前の準備 これは誰もいない状態で行ってください。デモが始まるときには、クリーンで正常なダッシュボードの前に座っていたいものです — 人々が見ている中でkubectlをいじっているのではなく。 Jobs App のデプロイ まだ行っていない場合は、isovalent-demo-jobs-app リポジトリからjobs-app Helm chartをデプロイします。 helm dependency build . helm upgrade –install jobs-app . –namespace tenant-jobs –create-namespace すべてが実行中であることを確認 デモ中に驚かないよう、これらのチェックを実行します。