kube-state-metrics(KSM)은 Kubernetes API 서버를 모니터링하며, Kubernetes 객체들의 상태에 대한 메트릭을 생성하는 간단한 서비스입니다. 이 서비스는 개별 Kubernetes 구성 요소의 상태에 중점을 두기보다는, 배포(deployments), 노드(nodes), 파드(pods)와 같은 다양한 객체들의 상태에 집중합니다.
kube-state-metrics는 Kubernetes API 객체로부터 메트릭을 수정 없이 생성하는 데 초점을 맞추고 있습니다. 이를 통해 kube-state-metrics에서 제공하는 기능은 Kubernetes API 객체와 동일한 안정성을 보장합니다. 따라서 특정 상황에서는 kube-state-metrics가 kubectl과 동일한 값을 보여주지 않을 수 있습니다. 이는 kubectl이 이해하기 쉬운 메시지를 표시하기 위해 특정한 *휴리스틱(heuristics)을 적용하는 반면, kube-state-metrics는 Kubernetes API로부터 가져온 데이터를 수정 없이 노출하기 때문입니다. 이러한 방식으로 사용자들은 필요한 모든 데이터를 확보하고, 원하는 대로 휴리스틱을 적용할 수 있습니다.
*휴리스틱(huristic)
메트릭은 기본적으로 포트 8080
에서 HTTP 엔드포인트 /metrics
를 통해 제공됩니다. 이 메트릭은 텍스트 형식으로 제공됩니다. 이러한 메트릭은 Prometheus 자체나 Prometheus 클라이언트 엔드포인트 스크래핑(scraping)에 호환되는 스크래퍼에 의해 소비되도록 설계되었습니다. 또한 브라우저에서 /metrics
를 열어 원시(raw) 메트릭을 확인할 수도 있습니다. /metrics
엔드포인트에서 노출되는 메트릭은 현재 Kubernetes 클러스터의 상태를 반영합니다. Kubernetes 객체가 삭제되면, 해당 객체는 더 이상 /metrics
엔드포인트에서 볼 수 없습니다.
--telemetry-host
및 --telemetry-port
(기본값: 8081
) 옵션을 통해 자체적인 일반 프로세스 메트릭을 노출합니다. 또한, kube-state-metrics는 리소스에 대한 list 및 watch 성공과 오류 메트릭도 제공합니다. 이러한 메트릭을 활용하면 list 또는 watch 리소스의 오류율을 계산할 수 있습니다. 만약 이러한 메트릭에서 오류가 발생하는 것을 발견했다면, 이는 대부분 구성 문제나 권한 문제일 가능성이 높습니다. 이 경우, 다음 단계로 kube-state-metrics의 로그를 조사하는 것이 좋습니다.kube_state_metrics_list_total{resource="*v1.Node",result="success"} 1
kube_state_metrics_list_total{resource="*v1.Node",result="error"} 52
kube_state_metrics_watch_total{resource="*v1beta1.Ingress",result="success"} 1
http_request_duration_seconds_bucket{handler="metrics",method="get",le="2.5"} 30
http_request_duration_seconds_bucket{handler="metrics",method="get",le="5"} 30
http_request_duration_seconds_bucket{handler="metrics",method="get",le="10"} 30
http_request_duration_seconds_bucket{handler="metrics",method="get",le="+Inf"} 30
http_request_duration_seconds_sum{handler="metrics",method="get"} 0.021113919999999998
http_request_duration_seconds_count{handler="metrics",method="get"} 30
kube_state_metrics_build_info{branch="main",goversion="go1.15.3",revision="6c9d775d",version="v2.0.0-beta"} 1
kube_state_metrics_shard_ordinal{shard_ordinal="0"} 0
kube_state_metrics_total_shards 1
kube_state_metrics_build_info{branch="main",goversion="go1.15.3",revision="6c9d775d",version="v2.0.0-beta"} 1
kube_state_metrics_shard_ordinal{shard_ordinal="0"} 0
kube_state_metrics_total_shards 1
*_labels
메트릭 계열은 Kubernetes의 라벨을 Prometheus 라벨로 노출합니다. Kubernetes는 라벨 이름에 허용되는 문자에 대해 Prometheus보다 더 자유롭기 때문에, 지원되지 않는 문자는 자동으로 밑줄(_)로 변환됩니다. 예를 들어, app.kubernetes.io/name
은 label_app_kubernetes_io_name
으로 변환됩니다.
이러한 변환은 foo-bar
와 foo_bar
와 같이 서로 다른 Kubernetes 라벨이 동일한 Prometheus 라벨인 label_foo_bar로 변환되어 충돌을 일으킬 수 있습니다.
이를 해결하기 위해 kube-state-metrics는 자동으로 접미사 _conflictN
을 추가하여 충돌을 방지합니다. 예를 들어, 위의 라벨들은 각각 label_foo_bar_conflict1
과 label_foo_bar_conflict2
로 변환됩니다.
만약 이러한 충돌 해결 방식에 대해 더 많은 제어권을 원한다면, Admission Webhook을 사용하여 Kubernetes 라벨을 표준화하고 잠재적인 충돌을 방지하는 방식으로 스택의 다른 수준에서 문제를 해결하는 것을 고려할 수 있습니다.
kube-state-metrics의 리소스 사용량은 클러스터의 크기, 즉 Kubernetes 객체(Pods, Nodes, Deployments, Secrets 등)의 수에 따라 달라집니다. 일반적으로 클러스터 내 Kubernetes 객체 수는 클러스터 노드 수와 어느 정도 비례합니다.