기록 84편을 계약 에이전트로 다시 썼다. 기존 71편(kss 25 · virt 46)과, 계약에만 있고 안 쓰여 있던 새 글감 13편이다. 원장 84개를 열어 단계마다 스킬 영수증과 관문 종료 코드를 적었고 verify-pipeline-run.py 가 error 0 으로 닫는다. SSOT 결함 둘을 고쳤다. - kss 의 `약 58일` 이 반입 중 `약 59일` 로 바뀌어 있었다. 원 증거 파일이 「남은 일수: 88일 … 실제 갱신까지 약 58일」로 산수를 직접 적는다. D-4a 쪽 `약 59일` 은 강제 갱신 뒤(`VALID: 89 days`)라 맞는 값이라 그대로 뒀다. - virt §198 의 `11.6GB` 는 §178 의 원 측정 `Mem: 11648`(MiB)과 어긋나는데 원 가이드의 표기 그대로라 고치지 않고 쓰이는 자리에 대조를 적었다. 기록의 수치 오류 셋을 고쳤다 — CASE 요약의 「게스트 셋에 8240MB」(5120+3120 은 둘이다), k3s 편이 같은 것을 여섯·일곱·여덟로 세던 것, no-docker 편의 「셋을 더 든다」(§281 의 표는 네 행이고 디스크 행이 빠져 있었다). 계약을 셋 고쳤다. - kss 의 sourceRepository 리비전이 cdac9b8 이었는데 그 커밋에는 docs/guides/** 28개가 아예 없다. 9465582b 로 바꾸고, 반입한 바이트가 어느 커밋과도 같지 않다는 것을 측정값과 함께 적었다 — 반입은 커밋이 아니라 그 시점의 작업 트리에서 떠 온 것이다(kss 297/306 · virt 12/14 가 작업 트리와 같고, 200 커밋을 거슬러 전수 대조했을 때 가장 가까운 커밋도 28개가 어긋났다). - virt 계약이 「2026-09-11 재배분」이라고 적는데 SSOT 는 재배분 날짜를 적지 않고 재배분 뒤 값은 이미 2026-09-10 측정에 찍혀 있다. - kss 후보 대장이 지나친 절 아홉에 처분을 적었다(warn 9 → 0). 새 글감은 0건이고 넷은 앵커가 h3 슬러그의 접두가 아니라 중간 토막이라 검사기가 못 본 것이었다. style_profile.mjs 의 결함 둘을 고쳤다 — frontmatter 가 문장으로 세어져 (실측 398자짜리 「문장」 하나) 평균 길이를 기준 안으로 밀어 올리고 있었고, engPerSent 의 분자는 목록을 포함한 글에서, 분모는 목록을 걷어낸 글에서 세고 있었다(Question 기록에서 11.94 → 3.86). verify-pipeline.py 전 항목 PASS · error 0 · unittest 334건 OK. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
291 lines
19 KiB
Markdown
291 lines
19 KiB
Markdown
---
|
|
id: 0cb0f195-b06b-4f8e-b52e-675eb0918805
|
|
kind: SETUP
|
|
slug: prometheus-and-grafana-for-the-lab
|
|
title: Prometheus 와 Grafana 를 올려 클러스터 안을 밖에서 본다
|
|
topic: lab-environment-build
|
|
topicName: 실험대 환경 구성
|
|
project: virtualization
|
|
status: 게시 전
|
|
studio: "https://hyeonworks.com/studio/documents/0cb0f195-b06b-4f8e-b52e-675eb0918805/edit"
|
|
pinnedVersions:
|
|
- name: k3s
|
|
version: v1.36.4+k3s1
|
|
- name: Debian GNU/Linux
|
|
version: 12 (bookworm)
|
|
sourceRevision: 9465582b5d1630eb4ae7c4e078021486919bf6b6
|
|
source:
|
|
- final/document.md#192-단계-06-prometheus-와-grafana
|
|
- final/document.md#184-이-부의-출처와-범위
|
|
---
|
|
|
|
# Prometheus 와 Grafana 를 올려 클러스터 안을 밖에서 본다
|
|
|
|
매니페스트 한 장을 `apply` 해 네임스페이스 `observability` 에 Prometheus 와 Grafana 와 node-exporter 를 세우는 절차다. 밖에서만 판정하면 분단된 노드가 스스로 빠지는 것을 놓치기 때문에 이 스택을 둔다.
|
|
|
|
## 관계
|
|
|
|
- **Keycloak 2노드와 PostgreSQL 을 k3s 에 올리고 클러스터가 묶였는지 확인한다**
|
|
그 단계가 세운 두 노드를 긁는다. 거기서 임시 파드로 물었던 클러스터 크기를 여기서는 Prometheus 에 묻는다.
|
|
- **k3s server 와 agent 를 게스트 두 대에 깔고 lab host 에서 kubectl 로 본다**
|
|
node-exporter 가 노드마다 하나씩 뜨므로 줄이 하나뿐이면 그 단계의 노드 상태부터 다시 본다.
|
|
- **도구가 낸 출력은 대상의 상태가 아니다 — 그 명령이 무엇을 세는지부터 가른다**
|
|
`up` 이 1 이라는 것은 프로세스가 살아 있고 응답한다는 뜻이지 그 노드가 쓸모 있다는 뜻이 아니다. 빈 결과가 0 을 뜻하지 않는 것도 같다.
|
|
- **가이드대로 다시 쳐서 이 실험대가 같은 상태로 서는가**
|
|
스크레이프 대상 넷과 파드 네 줄이 다시 세운 실험대에서도 같은지가 그 질문이 셀 항목에 들어간다.
|
|
|
|
## 본문
|
|
|
|
<!-- body:start -->
|
|
|
|
## 읽기 전에 — 어디서 치는가
|
|
|
|
전부 `[lab host]` 에서 치고, 매니페스트를 적용하는 명령은 저장소 루트에서 친다.
|
|
|
|
| 번호 | 무엇 | 어디서 |
|
|
|---|---|---|
|
|
| 1 | 매니페스트 적용 | `[lab host]` — `~/workspace/keycloak-pattern` 안에서 |
|
|
| 2 | 파드 네 줄 세기 | `[lab host]` |
|
|
| 판정 | 대상 · 상태 · 클러스터 크기 | `[lab host]` |
|
|
| 판정 | Grafana 포트포워드 | **브라우저로 볼 그 기계** |
|
|
|
|
**마지막 포트포워드만 예외다.** 그 터널은 명령을 친 기계에서만 열리므로, 브라우저로 볼 기계에서 쳐야 한다.
|
|
|
|
이 단계에도 손으로 쓰는 파일이 없다. 세우는 것이 전부 매니페스트 한 장에 들어 있고, 그 원문은 저장소의 `deploy/lab/k8s/observability.yaml` 이다.
|
|
|
|
## 이 단계가 세우는 것
|
|
|
|
가이드 06 의 「이 단계가 끝나면」은 두 줄이다.
|
|
|
|
> Prometheus 가 Keycloak 을 긁고, `vendor_cluster_size` 로 클러스터 상태를
|
|
> 밖에서 볼 수 있다.
|
|
|
|
**왜 두는가**(observed) — 판정을 밖에서만 하면 놓친다. 7800 을 끊었는데 외부 응답이 전부 200 이었고, 분단된 노드가 스스로 로드밸런서에서 빠졌기 때문이다. 클러스터 안을 보는 눈이 따로 있어야 한다.
|
|
|
|
| 무엇 | 값 |
|
|
|---|---|
|
|
| 네임스페이스 | `observability` |
|
|
| 파드 | `grafana` 1 · `prometheus` 1 · `node-exporter` 2 (DaemonSet, 노드마다 하나) |
|
|
| 스크레이프 대상 | `keycloak` · `kubelet` · `node-exporter` · `prometheus` |
|
|
| Prometheus API | 파드 안 `localhost:9090` — `/api/v1/targets` · `/api/v1/query` |
|
|
| Grafana | 밖에 열지 않고 `port-forward svc/grafana 3000:3000` |
|
|
| 도구 | `jq` 가 없다. `grep -o` 와 `tr ',' '\n'` 로 필드만 뽑는다 |
|
|
|
|
**판 번호는 여기 없다**(unknown). 가이드 06 은 Prometheus 와 Grafana 의 이미지 태그를 적지 않았고 `observability.yaml` 원문은 반입되지 않았다. 파드 이름의 해시는 판 번호가 아니다.
|
|
|
|
## 전제와 되돌리기
|
|
|
|
전제는 한 줄이다 — 앞 단계가 끝나 Keycloak 두 노드가 떴다.
|
|
|
|
**되돌리는 절차는 원본 가이드 06 에 없다**(unknown). 이 단계가 남기는 것은 `observability` 네임스페이스와 그 안의 전부이고, `node-exporter` 는 DaemonSet 이라 노드마다 하나씩 붙어 있다. 지우는 순서도 지운 뒤의 확인도 가이드에 없다.
|
|
|
|
## 세우기 전에 먼저 본다
|
|
|
|
**무엇을 확인하는가** — 이 스택이 없으면 같은 질문에 어떻게 답하게 되는지. 앞 단계가 이미 한 번 보여 주었다.
|
|
|
|
```bash label="[lab host] 관측 스택 없이 클러스터 크기를 묻는 형태"
|
|
K0=$(kubectl -n keycloak-lab get pod keycloak-0 -o jsonpath='{.status.podIP}')
|
|
kubectl -n keycloak-lab run m --rm -i --restart=Never \
|
|
--image=curlimages/curl:8.11.1 --quiet --command -- \
|
|
sh -c "curl -s http://$K0:9000/metrics | grep '^vendor_cluster_size'"
|
|
```
|
|
|
|
**어디를 봐야 하는가** — 이 명령은 고른 파드 하나에게만 물을 수 있다. `keycloak-1` 을 보려면 IP 를 다시 잡아 한 번 더 친다.
|
|
|
|
**이 결과가 의미하는 것** — 한 노드만 보면 분단을 놓친다. 두 노드를 매번 따로 물어야 하고, 값을 나란히 놓아 비교하기도 어렵다. 이 단계는 그 질문을 한 번에 받아 준다.
|
|
|
|
## 실행 절차
|
|
|
|
### 1. 매니페스트 한 장을 적용한다
|
|
|
|
**목적** — 네임스페이스 `observability` 에 Prometheus 와 Grafana 와 node-exporter 를 세운다.
|
|
|
|
```bash label="[lab host] ① 매니페스트가 있는 저장소 루트로 간다"
|
|
cd ~/workspace/keycloak-pattern
|
|
```
|
|
|
|
```bash label="[lab host] ② 매니페스트를 적용하고 Prometheus 가 설 때까지 기다린다"
|
|
kubectl apply -f deploy/lab/k8s/observability.yaml
|
|
kubectl -n observability rollout status deploy/prometheus --timeout=180s
|
|
```
|
|
|
|
**예상 결과** — ② 가 끝나면 Prometheus 가 Ready 다. node-exporter 는 DaemonSet 이라 이 명령이 기다리는 대상에 들어가지 않으므로 2번에서 따로 센다.
|
|
|
|
**왜 필요한가** — `deploy/...` 로 시작하는 상대경로는 저장소 루트 기준이라 다른 디렉터리에서 치면 파일을 못 찾는다. 관측 스택을 두는 까닭은 밖에서만 판정하면 놓치기 때문이고, 그 근거는 위에 적었다.
|
|
|
|
**문제가 생기면** — ② 가 타임아웃으로 끝나면 2번의 파드 목록부터 보고, 거기서도 안 보이면 k3s 단계의 노드 상태로 돌아간다.
|
|
|
|
### 2. 파드 네 줄을 센다
|
|
|
|
**목적** — 노드 둘에 node-exporter 가 하나씩 떴는지 확인한다.
|
|
|
|
```bash label="[lab host] ① 네임스페이스의 파드를 전부 본다"
|
|
kubectl -n observability get pods
|
|
```
|
|
|
|
**예상 결과**(observed)
|
|
|
|
```text
|
|
grafana-845b5678cf-b6gvc 1/1 Running
|
|
node-exporter-9qk9w 1/1 Running
|
|
node-exporter-c2mz4 1/1 Running
|
|
prometheus-6774f94f7c-pzr2t 1/1 Running
|
|
```
|
|
|
|
줄이 네 개인가, READY 칸이 전부 `1/1` 인가, 특히 `node-exporter` 로 시작하는 줄이 둘인가를 센다.
|
|
|
|
**왜 필요한가** — node-exporter 가 둘인 것은 DaemonSet 이라 노드마다 하나씩 뜨기 때문이다. 하나뿐이면 노드 하나가 빠진 것이고, 그러면 그 노드의 CPU 와 메모리와 디스크 지표가 통째로 없는 채로 실험을 하게 된다.
|
|
|
|
**문제가 생기면** — 줄이 하나면 관측을 더 볼 것이 아니라 k3s 단계의 노드 상태부터 본다. 어느 노드에 붙었는지는 이렇게 확인한다.
|
|
|
|
```bash label="[lab host] 어느 노드에 붙었는지 본다"
|
|
kubectl -n observability get pods -o wide
|
|
```
|
|
|
|
NODE 열에서 Prometheus 와 Grafana 가 어느 노드에 있는지 본다. 죽는 순간을 기록해야 하는 쪽이 대상과 함께 내려가면 기록이 남지 않으므로, 관측 스택은 관측 대상과 같이 죽으면 안 된다. 노드가 둘뿐인 실험대에서는 완전히 갈라 둘 수 없어서 규칙으로 정했다 — 관측 스택은 server 노드인 `kc-lab-1` 에 두고 장애 주입은 agent 노드인 `kc-lab-2` 에 한다. `nodeSelector` 로 못박아 두면 실험을 다시 돌려도 같은 노드에 뜬다. node-exporter 는 DaemonSet 이라 이 규칙 밖이고 두 노드에 다 떠 있어야 한다.
|
|
|
|
## 구성 값
|
|
|
|
자주 보는 지표들이다. 실험 중에는 Grafana 보다 Prometheus 쿼리 API 가 편하다 — 값을 그대로 뽑아 비교할 수 있고 스크린샷보다 근거로 남기기 좋다.
|
|
|
|
| 지표 | 무엇 |
|
|
|---|---|
|
|
| `vendor_cluster_size` | 이 노드가 아는 멤버 수 |
|
|
| `vendor_jgroups_*` | JGroups 프로토콜별 카운터 |
|
|
| `vendor_statistics_approximate_entries_unique{cache="sessions"}` | 이 노드의 세션 캐시 엔트리 수 |
|
|
| `agroal_*` | JDBC 커넥션 풀 |
|
|
| `up` | 스크레이프 성공 여부 |
|
|
|
|
이 실험대에는 `jq` 가 깔려 있지 않다. 아래 확인 명령이 `grep -o` 와 `tr` 로 필드를 뽑는 모양인 것은 그 때문이고, 그 이상 가공해야 하면 파서를 짜지 않고 화면에 나온 JSON 을 그대로 읽는다.
|
|
|
|
## 끝났는지 판정한다
|
|
|
|
### 확인 ① 무엇을 긁고 있나
|
|
|
|
**무엇을 확인하는가** — Prometheus 가 어느 대상을 스크레이프하고 있는지.
|
|
|
|
```bash label="[lab host] 스크레이프 대상의 job 이름만 뽑는다"
|
|
kubectl -n observability exec deploy/prometheus -- \
|
|
wget -qO- localhost:9090/api/v1/targets | grep -o '"job":"[^"]*"' | sort -u
|
|
```
|
|
|
|
**실측**(observed)
|
|
|
|
```text
|
|
"job":"keycloak"
|
|
"job":"kubelet"
|
|
"job":"node-exporter"
|
|
"job":"prometheus"
|
|
```
|
|
|
|
**어디를 봐야 하는가** — 거기 있는 이름이 아니라 없는 이름이다. 응답은 JSON 한 덩어리이고 그대로는 못 읽으므로 `grep -o` 로 필요한 필드만 뽑고 `sort -u` 로 중복을 없앴다. 사람이 손으로 치는 선이 여기까지다.
|
|
|
|
**이 결과가 의미하는 것** — Redis 와 BFF 와 PostgreSQL 이 없다. 이 실험대는 그것들을 긁지 않는다. 그래서 어떤 실험에 Grafana 화면이 없는데, 안 찍은 것이 아니라 지표가 없는 것이다. 어떤 실험에서 지표를 못 찾으면 「측정이 실패했다」로 적기 전에 이 목록에 그 job 이 있었는지부터 본다. 가이드는 그것을 스크린샷 누락이 아니라 측정된 공백으로 기록했다.
|
|
|
|
### 확인 ② 목록에는 있는데 값이 안 나올 때
|
|
|
|
**무엇을 확인하는가** — 목록에 있는 대상이 실제로 긁히고 있는지.
|
|
|
|
```bash label="[lab host] job 과 health 와 lastError 를 세로로 늘어놓는다"
|
|
kubectl -n observability exec deploy/prometheus -- \
|
|
wget -qO- localhost:9090/api/v1/targets | tr ',' '\n' | grep -E '"(job|health|lastError)"'
|
|
```
|
|
|
|
**어디를 봐야 하는가** — `"health":"up"` 이 아닌 줄과 그 바로 뒤의 `lastError`. `tr ',' '\n'` 로 쉼표마다 줄을 나눴으므로 필드가 원래 순서대로 세로로 늘어서고, job 줄 아래에 그 대상의 health 가 온다.
|
|
|
|
**이 결과가 의미하는 것** — `down` 인 대상이 있으면 `lastError` 가 까닭을 그대로 말해 준다. 연결 거부인지 타임아웃인지 404 인지가 거기 적혀 있다. 확인 ③ 에서 값이 한 노드만 나오는 증상의 원인이 대개 여기 있고, 그때는 클러스터가 아니라 스크레이프가 문제다.
|
|
|
|
권한이 모자라 대상 하나만 빠지는 일이 이 실험대에서 실제로 있었다. Prometheus 는 타깃을 적어 두지 않고 쿠버네티스 API 에 물어서 찾으므로 읽기 권한이 필요하다. 그 권한을 담는 `ClusterRole` 에서 `nodes/proxy` 를 빠뜨리자 kubelet 타깃만 `403 Forbidden` 으로 실패하고 나머지 잡은 전부 정상이었다. `nodes` 와 `nodes/metrics` 와 `nodes/proxy` 는 서로 다른 권한이라, 노드 지표를 긁는 경로 `/api/v1/nodes/<name>/proxy/metrics` 에는 셋째 것이 따로 있어야 한다. 부분 실패라 1번의 `rollout status` 는 성공이라고 말하고, 타깃 목록을 직접 봐야 드러난다. 권한만 따로 물을 수도 있다.
|
|
|
|
```bash label="[lab host] 그 ServiceAccount 가 그 동사를 쓸 수 있는지 묻는다"
|
|
kubectl auth can-i get nodes/proxy --as=system:serviceaccount:observability:prometheus
|
|
kubectl describe clusterrole prometheus
|
|
```
|
|
|
|
### 확인 ③ 클러스터 상태 — 두 노드가 각각 몇 명을 보고 있는가
|
|
|
|
**무엇을 확인하는가** — 두 Keycloak 이 서로를 보고 있는지.
|
|
|
|
```bash label="[lab host] 두 노드가 각각 아는 멤버 수"
|
|
kubectl -n observability exec deploy/prometheus -- \
|
|
wget -qO- 'localhost:9090/api/v1/query?query=vendor_cluster_size'
|
|
```
|
|
|
|
**실측**(observed) — 줄바꿈 없는 JSON 한 줄에서 읽어낸 값이다
|
|
|
|
```text
|
|
keycloak-1 → 2
|
|
keycloak-0 → 2
|
|
```
|
|
|
|
**어디를 봐야 하는가** — `data.result` 배열의 원소가 몇 개인가, 각 원소에서 `metric` 안의 `node` 라벨과 `value` 배열의 둘째 원소만 읽는다. `jq` 가 없으므로 눈으로 읽는다.
|
|
|
|
**이 결과가 의미하는 것** — 두 노드가 각각 자기가 아는 멤버 수를 보고한다. 둘 다 2 면 클러스터가 온전하다. 분단되면 한쪽은 2, 다른 쪽은 1 이 된다 — 한 노드만 보면 분단을 놓친다. 원소가 하나뿐이면 분단이 아니라 스크레이프 실패일 수 있으므로 확인 ② 의 `health` 를 먼저 본다. 값이 아예 안 나오면 `"result":[]` 로 빈 배열이 오는데, 이것은 「0 이다」가 아니라 「그런 지표가 없다」는 뜻이다. 지표 이름을 잘못 쳤거나 그 대상을 긁고 있지 않은 것이므로 확인 ① 로 돌아간다.
|
|
|
|
### 확인 ④ up 을 믿지 않는다
|
|
|
|
**무엇을 확인하는가** — 스크레이프 성공 지표가 무엇까지 말해 주는지.
|
|
|
|
```bash label="[lab host] 대상마다 스크레이프가 성공했는지 본다"
|
|
kubectl -n observability exec deploy/prometheus -- \
|
|
wget -qO- 'localhost:9090/api/v1/query?query=up'
|
|
```
|
|
|
|
**어디를 봐야 하는가** — 원소마다 `job` 라벨과 값이다. 값이 1 이라는 것은 마지막 스크레이프가 성공했다는 사실 하나만 말한다.
|
|
|
|
**이 결과가 의미하는 것** — 503 이 나는 동안에도 `up` 은 1 이었다(observed). 프로세스가 살아 있고 `/metrics` 가 응답하기만 하면 1 이 되므로, 살아 있지만 쓸모없는 상태를 이 지표로는 보지 못한다. 경보를 `up == 0` 하나로 걸면 그 상태를 통째로 놓친다. 그래서 기능 지표를 함께 본다. 밖에서 실제 응답을 받아 보는 것이 가장 짧다.
|
|
|
|
```bash label="[lab host] up 과 나란히 놓고 비교한다"
|
|
curl -s -o /dev/null -w '%{http_code}\n' https://auth.hyeonworks.com/realms/master
|
|
```
|
|
|
|
코드 한 칸을 `up` 의 1 과 0 옆에 놓는다. `up=1` 인데 이쪽이 200 이 아니면 그 조합이 곧 「살아 있지만 쓸모없는」 상태의 증거가 된다. 처음 보는 오류를 파고들 때는 값만 뽑는 형태를 버리고 헤더까지 읽는 형태로 바꾼다.
|
|
|
|
### 확인 ⑤ Grafana 를 볼 때
|
|
|
|
**무엇을 확인하는가** — 대시보드가 뜨는지. 밖에 열지 않고 포트포워드로 본다.
|
|
|
|
```bash label="[브라우저로 볼 기계] 보는 동안만 터널을 연다"
|
|
kubectl -n observability port-forward svc/grafana 3000:3000
|
|
```
|
|
|
|
**어디를 봐야 하는가** — `Forwarding from 127.0.0.1:3000 -> 3000` 한 줄이 찍히고 명령이 그대로 멈춰 있는가. 이 명령은 끝나지 않는 것이 정상이라 터미널 하나를 여기에 내준다. 브라우저를 열면 그 아래에 `Handling connection` 줄이 하나씩 붙는데, 그것이 안 붙으면 브라우저가 다른 곳을 보고 있다.
|
|
|
|
**이 결과가 의미하는 것** — 이 터널은 명령을 실행한 기계에서만 열린다. 워크스테이션에서 쳤으면 워크스테이션 브라우저로, lab host 에서 쳤으면 lab host 에서 봐야 한다. `bind: address already in use` 면 3000 을 이미 누가 쓰는 것이니 왼쪽만 바꾼다. Ctrl+C 로 끊으면 터널도 사라진다 — 밖에 포트를 여는 것이 아니라 보는 동안만 뚫는 것이라 실험대의 노출면이 늘지 않는다.
|
|
|
|
## 통과 조건을 한 번에 다시 본다
|
|
|
|
| 무엇 | 명령 | 통과 |
|
|
|---|---|---|
|
|
| 파드 | `kubectl -n observability get pods` | 네 줄 · `node-exporter` 가 둘 |
|
|
| 대상 | `… /api/v1/targets \| grep -o '"job":"[^"]*"' \| sort -u` | `keycloak` 이 목록에 있다 |
|
|
| 상태 | `… /api/v1/targets \| tr ',' '\n' \| grep -E …` | `"health":"up"` 아닌 줄이 없다 |
|
|
| 클러스터 | `… query=vendor_cluster_size` | 원소 둘 · 값 둘 다 2 |
|
|
|
|
## 막히면
|
|
|
|
| 증상 | 원인 | 확인 |
|
|
|---|---|---|
|
|
| Keycloak 지표가 안 보임 | 9000 이 안 열렸거나 스크레이프 설정 누락 | 확인 ① 의 targets |
|
|
| 값이 한 노드만 나옴 | 다른 노드 스크레이프 실패 | targets 의 `health` 필드 |
|
|
| 컨테이너 안에서 curl 실패 | Keycloak 이미지에 curl 이 없다 | 밖에서 Prometheus 로 묻는다 |
|
|
| Grafana 에 데이터 없음 | 데이터소스 주소 오류 | Prometheus 서비스 이름 확인 |
|
|
| `node-exporter` 가 한 줄 | 노드 하나가 빠졌다 | k3s 단계의 `kubectl get nodes` |
|
|
| `"result":[]` | 그런 지표가 없다 — 0 이 아니다 | 확인 ① 에 그 job 이 있는가 |
|
|
| `bind: address already in use` | 3000 을 이미 누가 쓴다 | `3001:3000` 처럼 왼쪽만 바꾼다 |
|
|
|
|
## 무엇이 관측이고 무엇이 아닌가
|
|
|
|
- (observed) 파드 네 줄과 job 네 개, `vendor_cluster_size` 가 둘 다 2, 503 중에도 `up` 이 1 이었던 것.
|
|
- (observed) Redis 와 BFF 와 PostgreSQL 이 스크레이프 대상에 없다는 것. 안 찍은 것이 아니라 지표가 없는 것이다.
|
|
- (observed) `ClusterRole` 에서 `nodes/proxy` 를 빠뜨렸을 때 kubelet 타깃만 403 으로 실패하고 나머지 잡은 정상이었던 것. 그때의 화면은 남아 있지 않다(unknown).
|
|
- 관측 스택을 `kc-lab-1` 에 두고 `kc-lab-2` 를 장애 주입 대상으로 삼는 것은 이 실험대가 정한 규칙이다. `observability.yaml` 원문이 없어 `nodeSelector` 가 거기 어떻게 적혀 있는지는 대조하지 못했다(unknown).
|
|
- (unknown) `observability.yaml` 원문이 반입되지 않아 Prometheus 와 Grafana 와 node-exporter 의 이미지 태그, 스크레이프 주기, 보존 기간, Grafana 대시보드 구성은 대조하지 못했다. 위에 고정한 버전은 이 스택이 올라탄 k3s 와 게스트 OS 까지다.
|
|
- (unknown) `get pods -o wide` 와 targets 의 `health` 훑기, `query=up`, `port-forward` 의 출력은 가이드가 봐야 할 줄만 적었고 값이 남아 있지 않다.
|
|
- (unknown) 원본 가이드 06 에 되돌리는 절차가 없다. DaemonSet 이 노드마다 남긴 것을 걷어내 본 적이 없다.
|
|
- (unknown) 이 단계에는 「이 실험대는 이렇게 했다」와 「따라 하는 사람은」 두 갈래가 없다. 06 은 파일을 직접 쓰지 않고 저장소의 매니페스트를 적용한다.
|
|
- (inferred) node-exporter 가 재는 것은 게스트 안에서 본 값이다. 호스트에서 같은 것을 재면 다른 수가 나올 수 있는데, 스크레이프 대상 넷이 전부 클러스터 안이라 이 실험대는 호스트 쪽 지표를 긁지 않는다.
|
|
- (unknown) 만드는 명령은 구축할 때 친 것을 옮긴 것이라 다시 쳐서 같은 상태가 되는지는 확인되지 않았다.
|
|
|
|
<!-- body:end -->
|