Cilium入門 (Monitoring & Metrics編)

執筆者 : 藤本 健


はじめに

KubernetesのCNIプラグインの一つであるCiliumのMonitoring Metricsの機能について調べてみました。CNI(Container Network Interface)は、コンテナのネットワーク接続とコンテナが削除されたときに割り当てられたリソースを削除することを焦点とし、コンテナのネットワーク・インターフェースを設定するためのプラグインを記述するための仕様とライブラリ、多数のプラグインで構成されています。CNIプラグインには、Calico、flannel、Ciliumなど複数の種類がありますが、Ciliumには、SecurityやObservabilityなど幅広い機能があることがわかり、実際にCiliumのMonitoring Metricsの機能を試してみました。

Ciliumとは

Ciliumは、DockerやKubernetesのコンテナプラットフォームを使用してデプロイされたアプリケーションのネットワーク接続を提供するOSSです。Ciliumは、Linuxカーネル技術であるeBPFを利用して、Networking、Security、Observabilityの機能を使用することができます。2023年10月11日にCNCFのGraduatedプロジェクトとなっています。

eBPFについては、こちらに詳しく説明されているので、ぜひ参照してください。
詳説 eBPF 概論編
詳説 eBPF 実装編

CiliumのMonitoring & Metricsの動作確認

今回は、Ciliumでどのようにすれば、MonitoringやMetricsの収集ができるかをCiliumの公式ドキュメントのMonitoring & Metricsの記載にそってCilium環境を構築し、確認しています。

Ciliumでは、次のMetricsを収集し、Monitoringすることができます。

  • Cilium Metrics: Cilium(cilium-agent、cilium-operator)のプロセスから取得した情報
  • Hubble Metrics: Ciliumで管理されているKubernetes Podのネットワーク動作

他にもCluster Mesh API Server Metricsも取得できますが、ここでは触れていません。

Cilium導入

Cilium、HubbleのMetricsは、それぞれ個別に有効化できますが、ネットワーク状況の確認のため、Hubbleも導入し、Monitoringを有効化します。
また、--set hubble.metrics.enabledオプションでMonitoringする項目も細かく設定できます。設定方法はこちらに説明されています。

$ helm install cilium cilium/cilium --version 1.15.2 \
   --namespace kube-system \
   --set prometheus.enabled=true \
   --set operator.prometheus.enabled=true \
   --set hubble.enabled=true \
   --set hubble.metrics.enableOpenMetrics=true \
   --set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true;labelsContext=source_ip\,source_namespace\,source_workload\,destination_ip\,destination_namespace\,destination_workload\,traffic_direction}"

これにより、各ノードにcilium-agent、Clusterに1つ以上のcilium-operatorが導入されます。
Metricsの収集を有効にしているため、cilium-agent、cilium-operatorのannotationsにprometheus.io/scrape: trueprometheus.io/port: port番号の定義が追加され、Prometheusの監視対象となります。

$ kubectl -n kube-system get pod  -o wide | grep cilium
cilium-jzrjp                            1/1     Running   0            22h    192.168.119.129   control-plane   <none>           <none>
cilium-operator-6cdc4568cb-nq69s        1/1     Running   0            22h    192.168.119.130   worker-1        <none>           <none>
cilium-operator-6cdc4568cb-v28hq        1/1     Running   0            22h    192.168.119.131   worker-2        <none>           <none>
cilium-t5nkv                            1/1     Running   0            22h    192.168.119.131   worker-2        <none>           <none>
cilium-v97vb                            1/1     Running   0            22h    192.168.119.130   worker-1        <none>           <none>

Hubble Metricsが有効にし、hubble.metrics.enabledに取得するMetricsを追加した場合、hubble-metricsというKubernetes Headless Serviceが作成され、annotationsにprometheus.io/scrape: trueが追加されています。

$ kubectl -n kube-system get service
NAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                  AGE
cilium-agent     ClusterIP   None          <none>        9964/TCP                 22h
hubble-metrics   ClusterIP   None          <none>        9965/TCP                 22h

次に、Monitoring用にPrometheus/Grafanaを導入します。
Ciliumのドキュメントにあるexampleを使用しています。exampleでは、scrape_configsが設定されているため、自動でMetricsが収集されます。

$  kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.15.2/examples/kubernetes/addons/prometheus/monitoring-example.yaml

Monitoringの確認

ここまでで、Metricsの収集とGrafanaでのMonitoringができるようになります。
Ciliumは、helmでの導入時に構成されるので、ほぼ手間がかからずに利用できました。また、Prometheus、Grafanaについては、公式ドキュメント内のexampleを使用していますが、Grafanaのダッシュボード設定が用意されていて、とても利用しやすくなっています。既存環境のPrometheus、Grafanaを利用する場合でも、以下にあるリンクの設定を使って導入できます。 https://github.com/cilium/cilium/tree/main/examples/kubernetes/addons/prometheus

ブラウザでGrafanaにアクセスして、DashboardsからCilium Metricsを表示します。 次のように、Performance、eBPF、Networkなど各ノードで動作しているcilium-agentから情報が取得できています。

次にDashboardsからHubbleを表示してみます。

Drop状況やProtocol使用状況などネットワーク関連の情報が表示されています。HTTPやDNSのL7通信は、CiliumNetworkPolicyルールに一致するトラフィックをMonitoringするため、CiliumNetworkPolicyを適用していない状態では表示されていません。
Monitoringするため、以下のCiliumNetworkPolicyを適用します。このルールでは、k8s:run=webのラベルを持ったcilium endpointに対して、"/"のパスへのGETのみを許可しています。 動作確認用に該当のLabelを持ったリソースを事前にDeployしています。

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "allow-http"
spec:
  description: "Allow HTTP GET /"
  endpointSelector:
    matchLabels:
      "k8s:run": web
  ingress:
  - toPorts:
    - ports:
      - port: "80"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/"

Policyの適用

$ kubectl apply -f cilium_np_http.yaml
ciliumnetworkpolicy.cilium.io/allow-http created

事前に用意しておいたwebサーバー用のPodにアクセス後、次のようにHTTP RequestのMonitoringができるようになっています。

Monitoringの確認とは話がそれますが、上記で適用したNetworkPolicyは、GETのみを許可しています。POSTでアクセスした場合、正常にブロックされ、L7レベルでのRuleが適用されていることがわかります。 そして、この場合にHTTPのレスポンスコードは、403として応答されます。

$ curl -X POST http://10.101.235.33 -i
HTTP/1.1 403 Forbidden
content-length: 15
content-type: text/plain
date: Thu, 21 Mar 2024 08:27:58 GMT
server: envoy

Access denied

ここまでexampleを使って導入したGrafanaのダッシュボードに用意されているものを中心に確認していますが、参照できるMetricsは他にも多数あり、以下の公式ドキュメントに記載があります。
https://docs.cilium.io/en/stable/observability/metrics/#metrics-reference

個人的には、以下の項目は、トラブルシューティングの際や通信状況の把握に役立つと思います。

  • endpoint: cilium-agentごとのendpoint数。
  • node_connectivity_status: cilium-agentと各node間との通信状況。ノード間通信に異常がないかがわかる。
  • drop_count_total: パケットdrop数。Dropの理由も確認でき、policyで拒否されているかなどがわかるため、通信不可の場合には原因の材料になる。
  • drop_total: パケットdrop数。こちらは、Hubble Metricsで取得できるMetricsでプロトコルも表示される。
  • http_requests_total: HTTP Request数。リクエストメソッドやステータスを参照することができる。

他にも有効に利用できるものがあると思うので、これから見ていきます。

おわりに

今回は、公式ドキュメントにそって一通りMonitoringができることを試してみました。CiliumからパケットDropなど通信の状況を取得し、視覚化ができるので、ネットワーク接続に関するトラブルシューティングに利用できると思います。他にもHTTPリクエストの情報も収集できるのは便利だと思いました。また、大規模環境で運用する場合には、Endpoint数や適用しているPolicyの数なども取得できるので、構成の確認にも役立ちます。

KubernetesのCNIプラグインは複数ありますが、Metricsの収集とMonitoringを取り入れたいという観点でもCiliumを選択する理由の一つになると思いました。Ciliumには他にも機能があるので、これからもう少し深堀してみたいと思います。