執筆者 : 藤本 健
はじめに
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: true
、prometheus.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には他にも機能があるので、これからもう少し深堀してみたいと思います。