# ๐ฅ K8s Doctor MCP
> AI ๊ธฐ๋ฐ Kubernetes ํด๋ฌ์คํฐ ์ง๋จ ๋ฐ ์ง๋ฅํ ๋๋ฒ๊น
์ถ์ฒ ์์คํ
[](https://www.npmjs.com/package/@zerry_jin/k8s-doctor-mcp)
[](https://www.npmjs.com/package/@zerry_jin/k8s-doctor-mcp)
[](LICENSE)
[](https://nodejs.org)
[](https://kubernetes.io)
**[English](README.md)** | **[ํ๊ตญ์ด](#ํ๊ตญ์ด)**
## ๋ฐ๋ชจ
<!-- ์ฌ๊ธฐ์ ๋ฐ๋ชจ GIF ์ถ๊ฐ -->

## ์ K8s Doctor๊ฐ ํ์ํ๊ฐ์?
์ฟ ๋ฒ๋คํฐ์ค ์ด์๊ฐ ๋ฐ์ํ๋ฉด ๊ฐ๋ฐ์๋ค์ ๋ณดํต ์ด๋ฐ ๋ฌดํ๋ฃจํ์ ๋น ์ง๋๋ค:
- `kubectl get pods`
- `kubectl logs`
- `kubectl describe`
- ๊ตฌ๊ธ๋ง, ์คํ์ค๋ฒํ๋ก์ฐ ๊ฒ์...
**K8s Doctor๊ฐ ๊ฒ์์ฒด์ธ์ ์
๋๋ค.** ๋จ์ํ kubectl ๋ํผ๊ฐ ์๋๋ผ AI ๊ธฐ๋ฐ ์ง๋จ ๋๊ตฌ๋ก:
- ๐ **๊ทผ๋ณธ ์์ธ ๋ถ์** - ๋จ์ ์ํ ์ฒดํฌ๋ฅผ ๋์ด์ ๋ถ์
- ๐ง **์๋ฌ ํจํด ๊ฐ์ง** - ํํ ์ด์ ์๋ ์ธ์ (Connection Refused, OOM, DNS ์คํจ ๋ฑ)
- ๐ก **์คํ ๊ฐ๋ฅํ ํด๊ฒฐ์ฑ
์ ๊ณต** - ์ ํํ kubectl ๋ช
๋ น์ด๊น์ง ์๋ ค์ค
- ๐ **Exit code ๋ถ์** - exit 137, 143, 1์ด ๋ฌด์จ ์๋ฏธ์ธ์ง ์ค๋ช
- ๐ฏ **๋ก๊ทธ ํจํด ๋งค์นญ** - ์์ฒ ์ค ๋ก๊ทธ์์ ํต์ฌ๋ง ์ถ์ถ
- ๐ฅ **๊ฑด๊ฐ๋ ์ ์** - ํ๋/ํด๋ฌ์คํฐ ๊ฑด๊ฐ๋๋ฅผ 0-100์ ์ผ๋ก ํ๊ฐ
## ์ฃผ์ ๊ธฐ๋ฅ
| ๋๊ตฌ | ์ค๋ช
|
|------|------|
| `diagnose-pod` | **ํ๋ ์ข
ํฉ ์ง๋จ** - ์ํ, ์ด๋ฒคํธ, ๋ฆฌ์์ค ๋ถ์ ๋ฐ ๊ฑด๊ฐ๋ ์ ์ ์ ๊ณต |
| `debug-crashloop` | **CrashLoopBackOff ์ ๋ฌธ๊ฐ** - exit code ํด์, ๋ก๊ทธ ๋ถ์, ๊ทผ๋ณธ ์์ธ ํ์
|
| `analyze-logs` | **์ค๋งํธ ๋ก๊ทธ ๋ถ์** - ์๋ฌ ํจํด ๊ฐ์ง, ํํ ๋ฌธ์ ํด๊ฒฐ์ฑ
์ ์ |
| `check-resources` | **๋ฆฌ์์ค ์ฌ์ฉ๋** - CPU/Memory limit ํ์ธ, OOM ์ํ ๊ฒฝ๊ณ |
| `full-diagnosis` | **ํด๋ฌ์คํฐ ๊ฑด๊ฐ ์ฒดํฌ** - ๋ชจ๋ ๋
ธ๋์ ํ๋ ์ค์บ |
| `check-events` | **์ด๋ฒคํธ ๋ถ์** - Warning ์ด๋ฒคํธ ํํฐ๋ง ๋ฐ ๋ถ์ |
| `list-namespaces` | **๋ค์์คํ์ด์ค ๋ชฉ๋ก** - ๋ชจ๋ ๋ค์์คํ์ด์ค ๋น ๋ฅธ ์กฐํ |
| `list-pods` | **ํ๋ ๋ชฉ๋ก** - ๋ฌธ์ ๊ฐ ์๋ ํ๋ ์ํ ํ์ |
## ์ค์น
### npm์ผ๋ก ์ค์น (๊ถ์ฅ)
```bash
npm install -g @zerry_jin/k8s-doctor-mcp
```
### ์์ค์์ ๋น๋
```bash
git clone https://github.com/ongjin/k8s-doctor-mcp.git
cd k8s-doctor-mcp
npm install && npm run build
```
## Claude Code์ ๋ฑ๋ก
```bash
# npm ์ ์ญ ์ค์น ํ
claude mcp --scope project add k8s-doctor -- k8s-doctor-mcp
# ๋๋ ์์ค์์ ๋น๋ํ ๊ฒฝ์ฐ
claude mcp --scope project add k8s-doctor -- node /path/to/k8s-doctor-mcp/dist/index.js
```
## ๋น ๋ฅธ ์ค์ (๊ถ์ฅ)
๋งค๋ฒ ๋๊ตฌ ์ฌ์ฉ ์น์ธ์ ๋๋ฅด๋ ๊ฒ์ด ๋ฒ๊ฑฐ๋กญ๋ค๋ฉด, ์๋ ๋ฐฉ๋ฒ์ผ๋ก ์๋ ํ์ฉ์ ์ค์ ํ์ธ์.
### ๐ฅ๏ธ For Claude Desktop App Users
1. Claude ์ฑ์ ์ฌ์์ํฉ๋๋ค.
2. `k8s-doctor`๋ฅผ ์ฌ์ฉํ๋ ์ฒซ ๋ฒ์งธ ์ง๋ฌธ์ ๋์ง๋๋ค.
3. ์๋ฆผ์ฐฝ์ด ๋จ๋ฉด **"Always allow requests from this server"** ์ฒดํฌ๋ฐ์ค๋ฅผ ํด๋ฆญํ๊ณ **Allow**๋ฅผ ๋๋ฅด์ธ์.
(์ดํ์๋ ๋ฌป์ง ์๊ณ ์คํ๋ฉ๋๋ค.)
### โจ๏ธ For Claude Code (CLI) Users
ํฐ๋ฏธ๋ ํ๊ฒฝ(`claude` ๋ช
๋ น์ด)์ ์ฌ์ฉ ์ค์ด๋ผ๋ฉด ๊ถํ ๊ด๋ฆฌ ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ์ธ์.
1. ํฐ๋ฏธ๋์์ `claude`๋ฅผ ์คํํฉ๋๋ค.
2. ํ๋กฌํํธ ์
๋ ฅ์ฐฝ์ `/permissions`๋ฅผ ์
๋ ฅํ๊ณ ์ํฐ๋ฅผ ์นฉ๋๋ค.
3. **Global Permissions** ๋๋ **Project Permissions** ๋ฉ๋ด๊ฐ ๋์ค๋ฉด `Allowed Tools`๋ฅผ ์ ํํฉ๋๋ค.
4. `mcp__k8s-doctor__*` ๋ฅผ ์
๋ ฅํ์ฌ ๋ชจ๋ ๋๊ตฌ๋ฅผ ํ์ฉํ๊ฑฐ๋, ํ์ํ ๋๊ตฌ๋ง ๊ฐ๋ณ ๋ฑ๋กํฉ๋๋ค.
> ๐ก **Tip**: ๋๋ถ๋ถ์ ๊ฒฝ์ฐ `diagnose-pod`, `debug-crashloop`, `analyze-logs` ์ธ ๊ฐ์ง๋ง ํ์ฉํ๋ฉด ์ถฉ๋ถํฉ๋๋ค. ์ด ์ธ ๋๊ตฌ๋ก 90%์ ๋๋ฒ๊น
์๋๋ฆฌ์ค๋ฅผ ์ปค๋ฒํฉ๋๋ค.
**๊ถ์ฅ ์ค์ :**
```bash
# ๊ท ํ์กํ ์ ๊ทผ - ์ฃผ์ ์ง๋จ ๋๊ตฌ ํ์ฉ
claude config add allowedTools \
"mcp__k8s-doctor__diagnose-pod" \
"mcp__k8s-doctor__debug-crashloop" \
"mcp__k8s-doctor__analyze-logs" \
"mcp__k8s-doctor__full-diagnosis"
```
## ํ์ ์กฐ๊ฑด
- **kubectl** ์ค์ ๋ฐ ์๋ ํ์ธ (`kubectl cluster-info` ์ฑ๊ณตํด์ผ ํจ)
- **kubeconfig** ํ์ผ์ด ๊ธฐ๋ณธ ์์น(`~/.kube/config`)์ ์๊ฑฐ๋ `KUBECONFIG` ํ๊ฒฝ๋ณ์ ์ค์
- **Node.js** 18 ์ด์
- Kubernetes ํด๋ฌ์คํฐ ์ ๊ทผ ๊ถํ (๋ก์ปฌ minikube/kind ๋๋ ์๊ฒฉ)
## ์ฌ์ฉ ์์
### ์์ 1: CrashLooping ํ๋ ์ง๋จ
```
์ฌ์ฉ์: "production ๋ค์์คํ์ด์ค์ 'api-server' ํ๋๊ฐ CrashLoop ์ํ์ธ๋ฐ ์ ๊ทธ๋ฐ๊ฑฐ์ผ?"
Claude (k8s-doctor ์ฌ์ฉ):
๐ CrashLoopBackOff ์ง๋จ
Exit Code: 137 (OOM Killed)
๊ทผ๋ณธ ์์ธ: ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ผ๋ก ์ปจํ
์ด๋๊ฐ ๊ฐ์ ์ข
๋ฃ๋์์ต๋๋ค
ํด๊ฒฐ ๋ฐฉ๋ฒ:
๋ฉ๋ชจ๋ฆฌ limit์ ๋๋ฆฌ์ธ์:
```yaml
resources:
limits:
memory: "512Mi" # ํ์ฌ ๊ฐ๋ณด๋ค ๋๊ฒ ์ค์
```
๊ด๋ จ ๋ก๊ทธ:
- ๋ผ์ธ 1234: Error: JavaScript heap out of memory
- ๋ผ์ธ 1256: FATAL ERROR: Reached heap limit
```
### ์์ 2: ์ ํ๋ฆฌ์ผ์ด์
๋ก๊ทธ ๋ถ์
```
์ฌ์ฉ์: "'backend-worker' ํ๋ ๋ก๊ทธ๋ฅผ ๋ถ์ํด์ ๋ญ๊ฐ ์คํจํ๋์ง ์๋ ค์ค"
Claude (analyze-logs ์ฌ์ฉ):
๐ ๋ก๊ทธ ๋ถ์ ๊ฒฐ๊ณผ
๊ฐ์ง๋ ์๋ฌ ํจํด:
๐ด Database Connection Error (15ํ ๋ฐ์)
๊ฐ๋ฅํ ์์ธ:
- DB ์๋น์ค๊ฐ ์ค๋น๋์ง ์์
- ์๋ชป๋ ์ฐ๊ฒฐ ๋ฌธ์์ด
- ์ธ์ฆ ์คํจ
ํด๊ฒฐ ๋ฐฉ๋ฒ:
- DB Pod ์ํ ํ์ธ
- ํ๊ฒฝ๋ณ์ ํ์ธ (ConfigMap/Secret)
- ์๋น์ค ์๋ํฌ์ธํธ ํ์ธ: kubectl get endpoints
๐ก Timeout (8ํ ๋ฐ์)
๊ฐ๋ฅํ ์์ธ: ์๋ต ์๊ฐ์ด ๋๋ฌด ๊ธธ๊ฑฐ๋ ๋คํธ์ํฌ ์ง์ฐ
ํด๊ฒฐ์ฑ
: ํ์์์ ๊ฐ์ ๋๋ฆฌ๊ฑฐ๋ ์๋น์ค ์ฑ๋ฅ ์ต์ ํ
```
### ์์ 3: ํด๋ฌ์คํฐ ์ ์ฒด ๊ฑด๊ฐ ์ฒดํฌ
```
์ฌ์ฉ์: "ํด๋ฌ์คํฐ ์ ์ฒด ๊ฑด๊ฐ ์ํ ํ์ธํด์ค"
Claude (full-diagnosis ์ฌ์ฉ):
๐ฅ ํด๋ฌ์คํฐ ๊ฑด๊ฐ ์ง๋จ
์ ์ฒด ์ ์: 72/100 ๐
๋
ธ๋: 3/3 Ready โ
ํ๋: 45/52 Running
- CrashLoop: 2๊ฐ ๐ฅ
- Pending: 5๊ฐ โณ
Critical ์ด์:
๐ด ํ๋ "payment-service" CrashLooping (exit 1)
๐ด ํ๋ "worker-3" OOM Killed
๊ถ์ฅ์ฌํญ:
- 2๊ฐ CrashLoop ํ๋๋ฅผ ์ฆ์ ์์ ํ์ธ์
- Pending ํ๋๋ค์ ๋ฆฌ์์ค ๋ถ์กฑ ์ฌ๋ถ ํ์ธ
```
## ์๋ ์๋ฆฌ
1. **ํด๋ฌ์คํฐ ์ฐ๊ฒฐ** - kubeconfig๋ฅผ ํตํด ์ฐ๊ฒฐ (kubectl๊ณผ ๋์ผ)
2. **์ข
ํฉ ๋ฐ์ดํฐ ์์ง** - ํ๋ ์ํ, ์ด๋ฒคํธ, ๋ก๊ทธ, ๋ฆฌ์์ค ์ฌ์ฉ๋
3. **ํจํด ๋งค์นญ ์ ์ฉ** - ์ค์ ๊ฒฝํ์ ๋ฐํ์ผ๋ก ํ ์ผ๋ฐ์ ์ธ ์๋ฌ ํจํด ์ธ์
4. **๊ทผ๋ณธ ์์ธ ๋ถ์** - ๋จ์ํ ์ํ๋ง ๋ณด์ฌ์ฃผ๋๊ฒ ์๋๋ผ WHY(์) ์คํจํ๋์ง ์ค๋ช
5. **ํด๊ฒฐ์ฑ
์ ๊ณต** - ์ ํํ ๋ช
๋ น์ด์ YAML๋ก ์์ ๋ฐฉ๋ฒ ์ ์
## ๊ฐ์งํ๋ ์๋ฌ ํจํด
K8s Doctor๊ฐ ์ธ์ํ๋ ์ผ๋ฐ์ ์ธ ํจํด๋ค:
- ๐ด **Connection Refused** - ์๋น์ค ์ค๋น ์๋จ, ์๋ชป๋ ํฌํธ, ๋คํธ์ํฌ ์ ์ฑ
- ๐ด **Database Connection Errors** - DB ์ธ์ฆ, ์๋ชป๋ ์ฐ๊ฒฐ ๋ฌธ์์ด
- ๐ด **Out of Memory** - OOM kill, ๋ฉ๋ชจ๋ฆฌ ๋์, ๋ถ์กฑํ limit
- ๐ **File Not Found** - ConfigMap ๋ฏธ๋ง์ดํธ, ์๋ชป๋ ๊ฒฝ๋ก
- ๐ **Permission Denied** - SecurityContext ๋ฌธ์ , fsGroup ์ด์
- ๐ **DNS Resolution Failed** - CoreDNS ๋ฌธ์ , ์๋ชป๋ ์๋น์ค๋ช
- ๐ก **Port Already in Use** - ๊ฐ์ ํฌํธ์ ์ฌ๋ฌ ํ๋ก์ธ์ค
- ๐ก **Timeout** - ๋๋ฆฐ ์๋ต, ๋คํธ์ํฌ ์ง์ฐ
- ๐ก **SSL/TLS Errors** - ๋ง๋ฃ๋ ์ธ์ฆ์, CA bundle ๋๋ฝ
## ์ํคํ
์ฒ
```
k8s-doctor-mcp/
โโโ src/
โ โโโ index.ts # MCP ์๋ฒ (๋ชจ๋ ๋๊ตฌ)
โ โโโ types.ts # TypeScript ํ์
์ ์
โ โโโ diagnostics/
โ โ โโโ pod-diagnostics.ts # ํ๋ ๊ฑด๊ฐ ๋ถ์
โ โ โโโ cluster-health.ts # ํด๋ฌ์คํฐ ์ ์ฒด ์ง๋จ
โ โโโ analyzers/
โ โ โโโ log-analyzer.ts # ์ค๋งํธ ๋ก๊ทธ ํจํด ๋งค์นญ
โ โโโ utils/
โ โโโ k8s-client.ts # Kubernetes API ํด๋ผ์ด์ธํธ
โ โโโ formatters.ts # ์ถ๋ ฅ ํฌ๋งทํ
์ ํธ
โโโ package.json
```
## ๋ณด์ ๊ณ ๋ ค์ฌํญ
- K8s Doctor๋ **์ฝ๊ธฐ ์ ์ฉ** Kubernetes API๋ง ์ฌ์ฉ (list, get, describe)
- `kubectl get/describe/logs`์ ๋์ผํ ๊ถํ ํ์
- ํด๋ฌ์คํฐ ์ํ๋ฅผ ์ ๋ ๋ณ๊ฒฝํ์ง ์์
- kubeconfig ์๊ฒฉ์ฆ๋ช
์ ๋ก์ปฌ์๋ง ์ ์ง
- ์ธ๋ถ ์๋ฒ๋ก ๋ฐ์ดํฐ ์ ์ก ์ํจ
## ๋ฌธ์ ํด๊ฒฐ
### "kubeconfig๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค"
```bash
# kubectl ์๋ ํ์ธ
kubectl cluster-info
# kubeconfig ์์น ํ์ธ
echo $KUBECONFIG
# ๋ช
์์ ๊ฒฝ๋ก๋ก ํ
์คํธ
export KUBECONFIG=~/.kube/config
```
### "Permission denied"
```bash
# ํด๋ฌ์คํฐ ๊ถํ ํ์ธ
kubectl auth can-i get pods --all-namespaces
# ์ต์ํ ๋ค์์ ๋ํ ์ฝ๊ธฐ ๊ถํ ํ์:
# - pods, events, namespaces, nodes
```
### "Connection refused to cluster"
```bash
# ํด๋ฌ์คํฐ ์ฐ๊ฒฐ ํ์ธ
kubectl get nodes
# ๋ก์ปฌ ํด๋ฌ์คํฐ์ ๊ฒฝ์ฐ (minikube/kind)
minikube status
kind get clusters
```
## ๊ฐ๋ฐ
```bash
# ํด๋ก ๋ฐ ์ค์น
git clone https://github.com/ongjin/k8s-doctor-mcp.git
cd k8s-doctor-mcp
npm install
# ๊ฐ๋ฐ ๋ชจ๋
npm run dev
# ๋น๋
npm run build
# Claude Code๋ก ํ
์คํธ
npm run build
claude mcp add --scope project k8s-doctor-dev -- node $(pwd)/dist/index.js
```
## ๊ธฐ์ฌ
๊ธฐ์ฌ๋ฅผ ํ์ํฉ๋๋ค! ํนํ:
- ๐ ์๋ก์ด ์๋ฌ ํจํด ๊ฐ์ง
- ๐ ๊ตญ์ ํ (๋ ๋ง์ ์ธ์ด)
- ๐ ๋ฉํธ๋ฆญ ํตํฉ (Prometheus ๋ฑ)
- ๐งช ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง
- ๐ ๋ฌธ์ ๊ฐ์
## ๋ก๋๋งต
- [ ] Metrics Server ํตํฉ (์ค์๊ฐ CPU/Memory ์ฌ์ฉ๋)
- [ ] ๋คํธ์ํฌ ์ ์ฑ
์ง๋จ
- [ ] ์คํ ๋ฆฌ์ง/PVC ๋ฌธ์ ํด๊ฒฐ
- [ ] Helm ์ฐจํธ ๋ถ์
- [ ] ๋ฉํฐ ํด๋ฌ์คํฐ ์ง์
- [ ] ๋ํํ ๋๋ฒ๊น
๋ชจ๋
- [ ] ๋ฆฌํฌํธ ๋ด๋ณด๋ด๊ธฐ (PDF, HTML)
## ๋ผ์ด์ ์ค
MIT ยฉ [zerry](https://github.com/ongjin)
## ๊ฐ์ฌ์ ๋ง
๋ค์ ๊ธฐ์ ๋ก ๋ง๋ค์ด์ก์ต๋๋ค:
- [@modelcontextprotocol/sdk](https://github.com/anthropics/mcp) - Model Context Protocol
- [@kubernetes/client-node](https://github.com/kubernetes-client/javascript) - Kubernetes JavaScript Client
- [Claude Code](https://claude.com/claude-code) - AI ๊ธฐ๋ฐ ๊ฐ๋ฐ ๋๊ตฌ
## ์คํ ํ์คํ ๋ฆฌ
์ด ๋๊ตฌ๊ฐ ๋๋ฒ๊น
์๊ฐ์ ์ ์ฝํด์คฌ๋ค๋ฉด โญ ์คํ ๋ถํ๋๋ฆฝ๋๋ค!
## ์์ฑ์
**zerry**
- GitHub: [@zerry](https://github.com/ongjin)
- kubectl ์ง์ฅ์ ์ง์น DevOps ์ปค๋ฎค๋ํฐ๋ฅผ ์ํด ๋ง๋ค์์ต๋๋ค ๐
---
**๋ก๊ทธ์ ๋น ์ง Kubernetes ์ฌ์ฉ์๋ค์ ์ํด โค๏ธ๋ก ๋ง๋ค์์ต๋๋ค**