Post

Cilium Metric Monitoring with Prometheus + Grafana [Cilium Study 2주차]

CiliumHubble은 모두 Prometheus 메트릭을 제공하도록 구성할 수 있습니다. Prometheus는 플러그형 메트릭 수집 및 저장 시스템이며, 메트릭 시각화 프런트엔드인 Grafana 의 데이터 소스 역할을 할 수 있습니다.

Prometheus에 대한 추가적인 내용은 Kubernetes 리소스 모니터링 (1) - Prometheus 해당 글을 참고하시면 좋을 것 같습니다.

관련 글

  1. Vagrant와 VirtualBox로 Kubernetes 클러스터 구축하기 [Cilium Study 1주차]
  2. Flannel CNI 배포하기 [Cilium Study 1주차]
  3. Cilium CNI 알아보기 [Cilium Study 1주차]
  4. Cilium 구성요소 & 배포하기 (kube-proxy replacement) [Cilium Study 1주차]
  5. Cilium Hubble 알아보기 [Cilium Study 2주차]
  6. Cilium & Hubble Command Cheet Sheet [Cilium Study 2주차]
  7. Star Wars Demo와 함께 Cilium Network Policy 알아보기 [Cilium Study 2주차]
  8. Hubble Exporter와 Dynamic Exporter Configuration [Cilium Study 2주차]
  9. Monitoring VS Observability + SLI/SLO/SLA 알아보기 [Cilium Study 2주차]
  10. Cilium Metric Monitoring with Prometheus + Grafana [Cilium Study 2주차] (현재 글)

Cilium Metrics

Cilium Metriccilium-agent, cilium-envoy, cilium-operator와 같은 Cilium Processes 자체의 상태에 대한 인사이트를 제공합니다. Prometheus 메트릭을 활성화하려면. Helm으로 배포할 때 prometheus.enabled=true 값을 설정해야 합니다.

Cilium Metrics 활성화

1
2
3
4
❯ helm upgrade --install cilium cilium/cilium --version 1.17.6 --reuse-values \
  --namespace kube-system \
  --set prometheus.enabled=true \
  --set operator.prometheus.enabled=true

Cilium Metrics 활성화 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
❯ kubectl get ds/cilium -n kube-system -o yaml | yq '.spec.template.metadata.annotations'
kubectl.kubernetes.io/restartedAt: "2025-07-27T03:40:31+09:00"
prometheus.io/port: "9962"
prometheus.io/scrape: "true"

❯ kubectl get deploy/cilium-operator -n kube-system -o yaml | yq '.spec.template.metadata.annotations'
kubectl.kubernetes.io/restartedAt: "2025-07-20T01:51:33+09:00"
prometheus.io/port: "9963"
prometheus.io/scrape: "true"

## Cilium Envoy는 위와 cilium-envoy라는 별도의 headless service를 통해 노출
❯ kubectl describe svc -n kube-system cilium-envoy                                     
Name:                     cilium-envoy
Namespace:                kube-system
Labels:                   app.kubernetes.io/managed-by=Helm
                          app.kubernetes.io/name=cilium-envoy
                          app.kubernetes.io/part-of=cilium
                          io.cilium/app=proxy
                          k8s-app=cilium-envoy
Annotations:              meta.helm.sh/release-name: cilium
                          meta.helm.sh/release-namespace: kube-system
                          prometheus.io/port: 9964 ## 확인
                          prometheus.io/scrape: true ## 확인
Selector:                 k8s-app=cilium-envoy
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       None  ## Headless Service
IPs:                      None
Port:                     envoy-metrics  9964/TCP
TargetPort:               envoy-metrics/TCP
Endpoints:                10.0.0.201:9964,10.0.0.202:9964,10.0.0.101:9964
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>

Hubble Metrics

Cilium Metric을 사용하면 Cilium 자체의 상태를 모니터링할 수 있는 반면, Hubble Metric을 사용하면 연결 및 보안과 관련하여 Cilium에서 관리하는 Kubernetes Pod의 네트워크 동작을 모니터링할 수 있습니다.

Hubble Metrics 활성화

1
2
3
4
5
6
7
❯ helm upgrade --install cilium cilium/cilium --version 1.17.6 --reuse-values \
  --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}"

Hubble Metrics 활성화 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
❯ kubectl describe svc -n kube-system hubble-metrics              
Name:                     hubble-metrics
Namespace:                kube-system
Labels:                   app.kubernetes.io/managed-by=Helm
                          app.kubernetes.io/name=hubble
                          app.kubernetes.io/part-of=cilium
                          k8s-app=hubble
Annotations:              meta.helm.sh/release-name: cilium
                          meta.helm.sh/release-namespace: kube-system
                          prometheus.io/port: 9965 ## 확인
                          prometheus.io/scrape: true ## 확
Selector:                 k8s-app=cilium
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       None ## Headless Service
IPs:                      None
Port:                     hubble-metrics  9965/TCP
TargetPort:               hubble-metrics/TCP
Endpoints:                10.0.0.201:9965,10.0.0.202:9965,10.0.0.101:9965
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>

Prometheus & Grafana 설정 (Cilium & Hubble Metric Monitoring)

위에서 CiliumHubble의 Metrics를 Prometheus가 수집할 수 있도록 설정해주었습니다. 이제 Prometheus를 배포해 Metrics를 수집하고 Grafana를 사용해 수집된 Metrics를 확인해보도록 하겠습니다. 이를 위해서는 아래와 같이 Prometheus가 Cilium과 Hubble의 Metrics을 수집할 수 있도록 Scrape Config를 추가해야합니다.

Cilium Scrape Config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scrape_configs:
- job_name: 'kubernetes-pods'
  kubernetes_sd_configs:
  - role: pod
  relabel_configs:
    - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
      action: keep
      regex: true
    - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
      action: replace
      regex: ([^:]+)(?::\d+)?;(\d+)
      replacement: ${1}:${2}
      target_label: __address__

Hubble Scrape Config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scrape_configs:
  - job_name: 'kubernetes-endpoints'
    scrape_interval: 30s
    kubernetes_sd_configs:
      - role: endpoints
    relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: (.+)(?::\d+);(\d+)
        replacement: $1:$2

Prometheus & Grafana 배포하기 (kube-prometheus-stack)

위의 scrape config 설정은 kube-prometheus-stack Helm Chart의 Values의 prometheus.prometheusSpec.additionalScrapeConfigs에 정의해주겠습니다. ingress, NodePort혹은 kubectl port-forward를 사용해서 접속하실 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
cat << EOF > kube-prometheus-stack-with-cilium-hubble-values.yaml
prometheus:
  prometheusSpec:
    additionalScrapeConfigs:
    # Hubble & Cilium Metric 수집을 위한 설정
    - job_name: 'kubernetes-pods' ## Cilium
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [ __meta_kubernetes_pod_annotation_prometheus_io_scrape ]
        action: keep
        regex: true
      - source_labels: [ __address__, __meta_kubernetes_pod_annotation_prometheus_io_port ]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: ${1}:${2}
        target_label: __address__

    - job_name: 'kubernetes-endpoints' ## Hubble
      scrape_interval: 30s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - source_labels: [ __meta_kubernetes_service_annotation_prometheus_io_scrape ]
        action: keep
        regex: true
      - source_labels: [ __address__, __meta_kubernetes_service_annotation_prometheus_io_port ]
        action: replace
        target_label: __address__
        regex: (.+)(?::\d+);(\d+)
        replacement: $1:$2
EOF

❯ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
❯ helm repo update
❯ helm upgrade --install  kube-prometheus-stack prometheus-community/kube-prometheus-stack -n monitoring \
    --version 75.12.0 --reuse-values -f kube-prometheus-stack-with-cilium-hubble-values.yaml

Scrape Config 확인

Prometheus 웹 UI에 접속 후 상단의 Status > Target Health에서 추가한 kubernetes-pods, kubernetes-endpoints Target의 State를 확인하고, Status > Configuration에서 실제 kubernetes-pods, kubernetes-endpoints Job을 확인하실 수 있습니다.

Target Health 확인

Prometheus Target Health

Scrape Config Job 확인 (kubernetes-pods)

Scrape Config - kubernetes-pods

Scrape Config Job 확인 (kubernetes-endpoints)

Scrape Config - kubernetes-endpoints

Scrape Config Job 확인 (secret 내용 확인 & pod 내부에서 config 파일 확인)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
## Secrets 확인
❯ kubectl get secret -n monitoring prometheus-kube-prometheus-stack-prometheus \
  -o jsonpath='{.data.prometheus\.yaml\.gz}' \
| base64 -d | gunzip -c \
| yq '.scrape_configs[] | select(.job_name=="kubernetes-pods" or .job_name=="kubernetes-endpoints")'

job_name: kubernetes-pods
kubernetes_sd_configs:
  - role: pod
relabel_configs:
  - action: keep
    regex: true
    source_labels:
      - __meta_kubernetes_pod_annotation_prometheus_io_scrape
  - action: replace
    regex: ([^:]+)(?::\d+)?;(\d+)
    replacement: ${1}:${2}
    source_labels:
      - __address__
      - __meta_kubernetes_pod_annotation_prometheus_io_port
    target_label: __address__
job_name: kubernetes-endpoints
kubernetes_sd_configs:
  - role: endpoints
relabel_configs:
  - action: keep
    regex: true
    source_labels:
      - __meta_kubernetes_service_annotation_prometheus_io_scrape
  - action: replace
    regex: (.+)(?::\d+);(\d+)
    replacement: $1:$2
    source_labels:
      - __address__
      - __meta_kubernetes_service_annotation_prometheus_io_port
    target_label: __address__
scrape_interval: 30s

## 내부에서 확인
❯ kubectl exec -n monitoring sts/prometheus-kube-prometheus-stack-prometheus -c prometheus -- cat "/etc/prometheus/config_out/prometheus.env.yaml" \
| yq '.scrape_configs[] | select(.job_name=="kubernetes-pods" or .job_name=="kubernetes-endpoints")' 
job_name: kubernetes-pods
kubernetes_sd_configs:
  - role: pod
relabel_configs:
  - action: keep
    regex: true
    source_labels:
      - __meta_kubernetes_pod_annotation_prometheus_io_scrape
  - action: replace
    regex: ([^:]+)(?::\d+)?;(\d+)
    replacement: ${1}:${2}
    source_labels:
      - __address__
      - __meta_kubernetes_pod_annotation_prometheus_io_port
    target_label: __address__
job_name: kubernetes-endpoints
kubernetes_sd_configs:
  - role: endpoints
relabel_configs:
  - action: keep
    regex: true
    source_labels:
      - __meta_kubernetes_service_annotation_prometheus_io_scrape
  - action: replace
    regex: (.+)(?::\d+);(\d+)
    replacement: $1:$2
    source_labels:
      - __address__
      - __meta_kubernetes_service_annotation_prometheus_io_port
    target_label: __address__
scrape_interval: 30s

Cilium & Hubble Metrics 확인하기 (Prometheus)

간단한 Prometheus Query를 통해 Cilium과 Hubble의 Metrics을 확인해보겠습니다. 우측 상단 톱니 바퀴 모양에서 autocompletesyntax highlighting 기능을 활성화 하시면 쿼리를 조금 더 편리하게 작성하실 수 있습니다.

Prometheus Setting

Prometheus Setting

Prometheus Sample Query

Cilium BPF Prometheus Sample Query

Prometheus Sample Query (결과)

Cilium BPF Prometheus Sample Query Result

Prometheus Sample Query (Graph)

Cilium BPF Prometheus Sample Query Result Graph


Cilium & Hubble Metrics 확인하기 (Grafana)

Grafana에서 Prometheus가 DataSource로 등록되어있는지 확인한 뒤, Explore에서 쿼리를 시험하고, 공개된 Cilium 대시보드(ID: 6658)를 Import해 확인해보도록 하겠습니다. Grafana도 위와 동일하게 ingress, NodePort혹은 kubectl port-forward를 사용한 방식 중 편한 방식을 사용해 접속하시면 됩니다.

default 계정 정보 (추가로 ID,PW를 지정하지 않았다면 아래 정보로 접속)
Default ID: admin
Default PW: prom-operator

Data Source 확인

Grafana Data Sources

Explorer에서 Query 확인

Grafana Explorer

Dashboard Import 하기

1. Grafana Dashboard Import 클릭

Grafana Dashboard Import Button

2. Grafana-Dashboard Import에서 Dashboard의 ID 삽입 후 Load

Grafana Dashboard Import ID

3. Dashboard Name, Folder, Datasource 지정 후 Import

Grafana Dashboard Import

Dashboard Import 확인

Grafana Imported Dashboard Check


Reference


궁금하신 점이나 추가해야 할 부분은 댓글이나 아래의 링크를 통해 문의해주세요.
Written with KKam._.Ji

This post is licensed under CC BY 4.0 by the author.