Prometheus·Grafana 띄우기
helm 한 번으로 설치하고, Gateway로 Grafana를 열고, down 6개를 0개로 만든 기록
kube-prometheus-stack helm 차트를 쓰면 Prometheus, Grafana, Alertmanager, node-exporter, kube-state-metrics가 한 번에 설치됩니다. 실습 PC의 kind 클러스터에서는 81초 만에 모든 파드가 Running이 됐고 메모리는 약 1.4GB를 더 썼습니다. Grafana는 3편의 Gateway에 grafana.localhost 호스트 이름으로 HTTPRoute를 붙여 Windows 브라우저에서 열었습니다. 설치 직후 Prometheus 수집 대상 28개 중 6개가 down이었는데, kind가 제어 플레인 구성 요소의 메트릭 포트를 127.0.0.1에만 열기 때문이었고 바인딩 주소를 바꾸자 28개 모두 up이 됐습니다.
1~3편에서 만든 kind 클러스터(노드 3개, Envoy Gateway의 lab-gateway가 Windows localhost:8080을 받음)를 이어서 씁니다. 차트는 kube-prometheus-stack 93.1.0, Grafana 13.3.0 기준입니다. 알림 설정, 장기 보관, 운영 환경 보안 설정은 다루지 않습니다.
kube-prometheus-stack에 들어 있는 것
kube-prometheus-stack은 쿠버네티스 모니터링에 필요한 구성 요소를 묶은 helm 차트입니다. Prometheus를 직접 설정 파일로 운영하지 않고, Prometheus Operator가 ServiceMonitor 같은 리소스를 읽어 수집 대상을 관리합니다. kube-prometheus-stack 차트
| 구성 요소 | 하는 일 | 실습에서 뜬 파드 |
|---|---|---|
| Prometheus | 메트릭을 주기적으로 긁어 저장 | prometheus-…-0 (2/2) |
| Prometheus Operator | ServiceMonitor 등을 읽어 Prometheus 설정 관리 | …-operator (1/1) |
| Grafana | 대시보드로 메트릭 시각화 | kps-grafana (3/3) |
| Alertmanager | 경고를 모아 전달 | alertmanager-…-0 (2/2) |
| node-exporter | 노드 CPU·메모리·디스크 수집 | 노드마다 1개씩 3개 |
| kube-state-metrics | 디플로이먼트·파드 같은 리소스 상태를 메트릭으로 | 1개 |
helm으로 설치하기
prometheus-community 저장소를 추가하고 설치합니다. --wait를 붙이면 모든 파드가 준비될 때까지 기다린 뒤 끝납니다.
helm repo update prometheus-community
helm install kps prometheus-community/kube-prometheus-stack -n monitoring --create-namespace --wait --timeout 10m
실습 시점의 차트 버전은 93.1.0이었고 설치는 81초가 걸렸습니다. 모든 서비스는 ClusterIP로 만들어지며, Grafana 서비스 이름은 릴리스 이름을 붙인 kps-grafana(포트 80)입니다. WSL 메모리 사용량은 설치 전 1.9GiB에서 설치 후 3.3GiB가 됐습니다. 참고로 kind에는 metrics-server가 없어서 kubectl top nodes는 Metrics API not available을 냅니다. 이 글의 메트릭은 모두 Prometheus가 따로 수집합니다.

Gateway에 Grafana 붙이기: 다른 네임스페이스 라우트 허용
3편의 Gateway(lab-gateway)는 default 네임스페이스에 있고 Grafana는 monitoring 네임스페이스에 있습니다. Grafana용 HTTPRoute를 monitoring에 만들고, grafana.localhost라는 호스트 이름으로 web 앱과 구분합니다.
kind: HTTPRoute
metadata:
name: grafana
namespace: monitoring
spec:
parentRefs:
- name: lab-gateway
namespace: default
hostnames:
- grafana.localhost
rules:
- backendRefs:
- name: kps-grafana
port: 80
이 라우트만 먼저 적용해 보면 붙지 않습니다. HTTPRoute 상태에 아래처럼 나오고, grafana.localhost로 보낸 요청은 404가 돌아왔습니다. Gateway 리스너는 기본적으로 같은 네임스페이스의 라우트만 받기 때문입니다. Gateway 리소스 설명
Gateway 리스너에 allowedRoutes를 추가해 다른 네임스페이스의 라우트도 받게 합니다. 실습 환경이라 from: All로 열었고, 실제 운영에서는 from: Selector로 라벨이 붙은 네임스페이스만 허용하는 편이 안전합니다.
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
적용 후 HTTPRoute는 Accepted=True가 됐고, Gateway의 attachedRoutes는 2(web, grafana)가 됐습니다. 호스트 이름이 없는 web 라우트는 그대로 나머지 요청을 받습니다.

Windows에서 grafana.localhost로 접속
Windows는 localhost로 끝나는 이름을 내 PC 주소로 풀어 줍니다. 실습 PC에서 Resolve-DnsName grafana.localhost를 실행하면 ::1이 나왔고, hosts 파일을 고치지 않아도 바로 접속됐습니다.
{
"database": "ok",
"version": "13.3.0",
...
}
PS> curl.exe -s -o NUL -w "HTTP %{http_code}" http://grafana.localhost:8080/login
HTTP 200
브라우저에서 http://grafana.localhost:8080을 열면 Grafana 13.3.0 로그인 화면이 나옵니다. 사용자 이름은 admin이고, 비밀번호는 차트가 만든 시크릿에 들어 있습니다.
로그인하면 차트가 미리 넣어 둔 대시보드가 있습니다. 실습 클러스터에는 대시보드용 ConfigMap이 29개 있었고, Dashboards 메뉴를 열면 Alertmanager, CoreDNS, etcd와 Kubernetes / Compute Resources / …, Kubernetes / Networking / …, Node Exporter / … 같은 대시보드가 태그와 함께 나옵니다. 따로 만들지 않아도 노드·네임스페이스·파드 단위로 바로 볼 수 있습니다.

예를 들어 Kubernetes / Compute Resources / Pod 대시보드에서 namespace를 default, pod를 2편에서 만든 web-… 파드로 고르면 그 파드의 CPU와 메모리가 그래프로 나옵니다. 실습 화면에서 nginx 컨테이너는 CPU를 거의 쓰지 않았고(0에 가까움), 메모리는 Working Set 기준 12.0MiB, RSS 8.37MiB였습니다. 요청이 거의 없는 nginx라 값이 작지만, 같은 화면에서 리소스 요청·제한(Quota)과 실제 사용량을 나란히 볼 수 있어 파드 크기를 정할 때 쓸 수 있습니다. 실습 PC에서 어떤 파드가 자원을 많이 쓰는지 찾을 때도 이 대시보드부터 보면 편합니다.

target down 6개: kind에서 생기는 이유와 해결
설치 직후 Prometheus 수집 대상을 확인하면 28개 중 22개만 up이었습니다. Prometheus 화면의 Status → Targets에서 볼 수도 있고, API로 세어 볼 수도 있습니다.
| 대상 | 포트 | 오류 |
|---|---|---|
| kube-controller-manager | 10257 | connection refused |
| kube-scheduler | 10259 | connection refused |
| kube-etcd | 2381 | connection refused |
| kube-proxy (노드 3개) | 10249 | connection refused |
모두 connection refused라는 점이 실마리입니다. Prometheus는 노드 주소로 접속하는데, kind가 만든 이 구성 요소들은 메트릭 포트를 노드 안의 127.0.0.1에서만 엽니다. 실제로 제어 플레인 노드 안의 정적 파드 매니페스트에는 --bind-address=127.0.0.1이, etcd에는 --listen-metrics-urls=http://127.0.0.1:2381이 들어 있었고, kube-proxy 설정의 metricsBindAddress는 빈 값(기본값 127.0.0.1:10249)이었습니다.
실습 클러스터이므로 바인딩 주소를 0.0.0.0으로 바꿨습니다. kube-proxy는 ConfigMap을 고친 뒤 데몬셋을 다시 시작하고, 나머지 셋은 제어 플레인 노드 컨테이너 안의 매니페스트를 고치면 kubelet이 파드를 다시 만듭니다.
| sed 's/metricsBindAddress: .*/metricsBindAddress: 0.0.0.0:10249/' \
| kubectl apply -f -
kubectl -n kube-system rollout restart ds/kube-proxy
docker exec lab-control-plane sh -c "
sed -i 's/--bind-address=127.0.0.1/--bind-address=0.0.0.0/' /etc/kubernetes/manifests/kube-controller-manager.yaml /etc/kubernetes/manifests/kube-scheduler.yaml
sed -i 's#--listen-metrics-urls=http://127.0.0.1:2381#--listen-metrics-urls=http://0.0.0.0:2381#' /etc/kubernetes/manifests/etcd.yaml"
약 40초 뒤 네 구성 요소가 다시 Running이 됐고, 그다음 수집 주기에 28개 모두 up으로 바뀌었습니다. 이때 켜져 있던 경고는 Watchdog 하나뿐이었는데, 경고 전달 경로가 살아 있는지 확인하려고 항상 켜 두는 정상 경고입니다.
매니페스트를 고치기 전에 백업을 같은 /etc/kubernetes/manifests 폴더에 두면 kubelet이 그 파일까지 파드로 읽어 같은 구성 요소가 두 번 뜰 수 있습니다. 이 실습에서는 백업을 폴더 밖(/root/manifest-backup)에 두었습니다. 또 이 수정은 kind 클러스터를 다시 만들면 사라지므로, 다시 만들 때 같은 작업을 반복해야 합니다.
자주 묻는 질문
운영 클러스터에서도 bind-address를 0.0.0.0으로 바꿔도 되나요?
그대로 따라 하면 안 됩니다. 메트릭 포트가 모든 네트워크에 열리므로 운영 환경에서는 노드 방화벽이나 네트워크 정책으로 Prometheus만 접근하게 막아야 합니다. EKS 같은 관리형 클러스터는 제어 플레인 구성 요소를 사용자가 직접 바꿀 수 없으므로 수집 방식이 다릅니다.
Grafana를 localhost:8080/grafana 같은 경로로 열 수는 없나요?
가능하지만 Grafana에 하위 경로 설정(root_url과 serve_from_sub_path)을 따로 해야 합니다. 이 글은 설정을 바꾸지 않아도 되는 호스트 이름 방식(grafana.localhost)을 썼습니다.
작성 방식과 다음 편
이 글의 명령과 출력은 1편의 실습 PC에서 직접 실행한 결과이며, 설치와 설정은 kube-prometheus-stack 차트와 Gateway API 공식 문서를 기준으로 했습니다. 실행 기록 정리와 글 작성에 AI 도구를 함께 사용했습니다. 다음 편에서는 Loki를 설치해 파드 로그를 모으고, 같은 Grafana 화면에서 메트릭과 로그를 함께 봅니다.
'Kubernetes Guides' 카테고리의 다른 글
| NGINX Ingress 대신 Gateway API: kind 클러스터 앱을 Windows localhost로 접속하기 (0) | 2026.11.08 |
|---|---|
| Headlamp 설치와 사용법: 로컬 쿠버네티스를 화면으로 보고 파드 배포하기 (0) | 2026.11.08 |
| Windows에서 무료 쿠버네티스 실습 환경 만들기: WSL2 + Docker Engine + kind (0) | 2026.11.08 |
| 쿠버네티스 PVC 용량 확장이 반영되지 않을 때: 요청 용량·CSI·파일시스템 점검하기 (0) | 2026.09.09 |
| Kubernetes 트래픽 진입 구조 이해하기: ALB Controller, NGINX Ingress, Gateway, Istio 차이 (0) | 2026.08.31 |



