โ Back to list

k8s-debugging
by eco2-team
๐ฑ ์ด์ฝ์์ฝ(Ecoยฒ) BE
โญ 0๐ด 0๐
Jan 25, 2026
SKILL.md
name: k8s-debugging description: Kubernetes ์ด์/๋๋ฒ๊น ๊ฐ์ด๋. Pod ํธ๋ฌ๋ธ์ํ , ๋ก๊ทธ ๋ถ์, ๋คํธ์ํฌ ์ง๋จ, ํด๋ฌ์คํฐ ๊ตฌ์กฐ, GitOps/ArgoCD, Operator/CRD/CR, Helm ๋ฐฐํฌ ์ ์ฐธ์กฐ. "k8s", "kubernetes", "pod", "debug", "logs", "kubectl", "argocd", "helm", "operator", "crd" ํค์๋๋ก ํธ๋ฆฌ๊ฑฐ.
Kubernetes Debugging Guide
Ecoยฒ ํด๋ฌ์คํฐ ๊ฐ์
์์ฒด ๊ด๋ฆฌํ K8s ํด๋ฌ์คํฐ (EKS ์๋)
| ํญ๋ชฉ | ๊ฐ |
|---|---|
| ๋ง์คํฐ ๋ ธ๋ | k8s-master (13.209.44.249) |
| SSH ์ ์ | ssh -i ~/.ssh/sesacthon.pem ubuntu@13.209.44.249 |
| GitOps ๋ธ๋์น | develop (ArgoCD๊ฐ ๋ฐ๋ผ๋ณด๋ ๋ธ๋์น) |
| ์ด๋ฏธ์ง ๋ ์ง์คํธ๋ฆฌ | docker.io/mng990/eco2:<app>-<env>-latest |
๋ฐฐํฌ ํ๋ก์ฐ
PR โ develop ๋จธ์ง โ ArgoCD auto-sync โ ํด๋ฌ์คํฐ ๋ฐ์
์ฃผ์ Namespace
| Namespace | ์ปดํฌ๋ํธ |
|---|---|
chat | chat-api, chat-worker |
auth | auth-api, auth-worker, ext-authz |
scan | scan-api, scan-worker |
character | character-api, character-grpc, character-worker |
location | location-api, location-grpc |
rabbitmq | RabbitMQ Cluster (eco2-rabbitmq) |
redis | Redis Sentinel (rfr-streams, rfr-pubsub) |
postgres | PostgreSQL |
event-router | event-router (Redis Streams โ Pub/Sub) |
sse-consumer | sse-gateway (SSE ์คํธ๋ฆฌ๋ฐ) |
Istio ๋ผ์ฐํ ๊ตฌ์กฐ
API Gateway
| ํญ๋ชฉ | ๊ฐ |
|---|---|
| API ๋๋ฉ์ธ | api.dev.growbin.app |
| Gateway | istio-system/eco2-gateway |
| ์ธ์ฆ ๋ฐฉ์ | Cookie (s_access) โ Header (Authorization: Bearer) ๋ณํ |
VirtualService ๋ผ์ฐํ
| ๊ฒฝ๋ก | ์๋น์ค | Namespace |
|---|---|---|
/api/v1/chat | chat-api | chat |
/api/v1/auth | auth-api | auth |
/api/v1/scan | scan-api | scan |
/api/v1/character | character-api | character |
/api/v1/location | location-api | location |
/api/v1/users | users-api | users |
/api/v1/images | images-api | images |
/api/v1/info | info-api | info |
/api/v1/sse | sse-gateway | sse-consumer |
EnvoyFilter (์ธ์ฆ ์ฒ๋ฆฌ)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Cookie โ Header ๋ณํ (cookie-to-header) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Client Request โ
โ โโ Cookie: s_access=<JWT> โ
โ โโ Cookie: s_refresh=<JWT> โ
โ โ
โ โ EnvoyFilter (Lua Script) โ
โ โ
โ Backend Request โ
โ โโ Authorization: Bearer <JWT> โ
โ โโ X-Refresh-Token: Bearer <JWT> โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
API ํ ์คํธ (ํด๋ฌ์คํฐ ์ธ๋ถ)
# JWT ํ ํฐ์ผ๋ก ์ธ์ฆ๋ ์์ฒญ
TOKEN="<JWT_TOKEN>"
curl -X POST "https://api.dev.growbin.app/api/v1/chat" \
-H "Content-Type: application/json" \
-H "Cookie: s_access=$TOKEN" \
-d '{"message":"์๋
ํ์ธ์!"}'
# Canary ๋ฒ์ ํ
์คํธ (x-canary ํค๋)
curl -X POST "https://api.dev.growbin.app/api/v1/chat" \
-H "Content-Type: application/json" \
-H "Cookie: s_access=$TOKEN" \
-H "x-canary: true" \
-d '{"message":"์๋
ํ์ธ์!"}'
Quick Reference
ํด๋ฌ์คํฐ ์ ์ (SSH)
# ๋ง์คํฐ ๋
ธ๋ ์ ์
./scripts/utilities/connect-ssh.sh master
# ์์ปค ๋
ธ๋ ์ ์
./scripts/utilities/connect-ssh.sh worker-1
./scripts/utilities/connect-ssh.sh worker-2
# ์คํ ๋ฆฌ์ง ๋
ธ๋ ์ ์
./scripts/utilities/connect-ssh.sh storage
# ์๊ฒฉ ๋ช
๋ น ์คํ (๋น์ธํฐ๋ํฐ๋ธ)
ssh -i ~/.ssh/sesacthon.pem -o StrictHostKeyChecking=no ubuntu@<IP> "kubectl get nodes"
์๊ฒฉ ํด๋ฌ์คํฐ ์ ๊ฒ (Claude Code์ฉ)
๋ก์ปฌ์์ VPN ์์ด ํด๋ฌ์คํฐ์ ์ ์ํด์ผ ํ ๋ ์ฌ์ฉํ๋ ์ ์ฐจ.
# 1. ๋ง์คํฐ ๋
ธ๋ IP ์กฐํ
MASTER_IP=$(aws ec2 describe-instances \
--filters "Name=tag:Name,Values=k8s-master" "Name=instance-state-name,Values=running" \
--query "Reservations[].Instances[].PublicIpAddress" \
--output text --region ap-northeast-2)
# 2. SSH ๋ํผ ํจ์ (ํธ์์ฉ)
k8s() {
ssh -i ~/.ssh/sesacthon.pem -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
ubuntu@$MASTER_IP "$@"
}
# 3. ํด๋ฌ์คํฐ ์ํ ํ์ธ
k8s "kubectl get nodes"
k8s "kubectl get pods -n <namespace> -l app=<app-name> -o wide"
# 4. ์ปจํ
์ด๋๋ณ ์ํ ํ์ธ
k8s "kubectl get pod -n <ns> -l app=<app> -o jsonpath='{range .items[*].status.containerStatuses[*]}{.name}: {.state}{\"\\n\"}{end}'"
# 5. ๋ก๊ทธ ํ์ธ
k8s "kubectl logs -n <ns> deploy/<deploy-name> -c <container> --tail=50"
k8s "kubectl logs -n <ns> deploy/<deploy-name> -c <container> --previous --tail=50"
# 6. ์ด๋ฒคํธ ํ์ธ
k8s "kubectl get events -n <ns> --sort-by='.lastTimestamp' | tail -20"
CI โ ํด๋ฌ์คํฐ ๋ฐ์ ํ๋ก์ฐ
PR ๋จธ์ง ํ ์ ์ด๋ฏธ์ง๋ฅผ ํด๋ฌ์คํฐ์ ๋ฐ์ํ๋ ์ ์ฒด ์ ์ฐจ.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Image Update Flow (kubectl ๋ฐฉ์) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ 1. PR โ develop ๋จธ์ง โ
โ โโโถ GitHub Actions CI ํธ๋ฆฌ๊ฑฐ โ
โ โ
โ 2. CI ๋ก๊ทธ ํ์ธ ๋ฐ ์
๋ฐ์ดํธ ๋์ ํ์
โ
โ โโโถ gh run list --limit 5 โ
โ โโโถ gh run view <run-id> --log โ
โ โโโถ ๋น๋๋ ์ฑ ๋ชฉ๋ก ํ์ธ (chat-api, chat-worker ๋ฑ) โ
โ โ
โ 3. ArgoCD Application ๋ผ๋ฒจ๋ก Hard Refresh ํธ๋ฆฌ๊ฑฐ โ
โ โโโถ kubectl label application -n argocd <app> \ โ
โ argocd.argoproj.io/refresh=hard --overwrite โ
โ โ
โ 4. Deployment ์ญ์ (Self-Heal ํธ๋ฆฌ๊ฑฐ) โ
โ โโโถ kubectl delete deploy <name> -n <namespace> โ
โ โ
โ 5. Pod ์ฌ์์ฑ ํ์ธ โ
โ โโโถ kubectl rollout status deploy/<name> -n <ns> --timeout=120s โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Step 1-2: CI ๋ก๊ทธ ํ์ธ (๋ก์ปฌ์์)
# ์ต๊ทผ CI ์คํ ๋ชฉ๋ก ํ์ธ
gh run list --limit 5
# ํน์ ์คํ์ ์์ธ ์ ๋ณด ๋ฐ ๋น๋๋ ์ฑ ํ์ธ
gh run view <run-id>
# ๋ก๊ทธ์์ ๋น๋๋ ์ด๋ฏธ์ง ํ์ธ
gh run view <run-id> --log | grep -E "Successfully built|Pushing|docker.io/mng990"
# jobs ํ์ธ (์ด๋ค ์ฑ์ด ๋น๋๋์๋์ง)
gh run view <run-id> --json jobs --jq '.jobs[] | select(.conclusion=="success") | .name'
Step 3-5: ํด๋ฌ์คํฐ ๋ฐ์ (๋ง์คํฐ ๋ ธ๋์์)
# SSH ์ ์
ssh -i ~/.ssh/sesacthon.pem ubuntu@13.209.44.249
# ArgoCD Application ๋ผ๋ฒจ๋ก Hard Refresh (๋น๋๋ ์ฑ๋ง)
kubectl label application -n argocd dev-api-chat argocd.argoproj.io/refresh=hard --overwrite
kubectl label application -n argocd dev-chat-worker argocd.argoproj.io/refresh=hard --overwrite
# Deployment ์ญ์ (Self-Heal๋ก ์ ์ด๋ฏธ์ง Pull)
kubectl delete deploy chat-api -n chat
kubectl delete deploy chat-worker -n chat
# Pod ์ฌ์์ฑ ๋๊ธฐ
kubectl rollout status deploy/chat-api -n chat --timeout=120s
kubectl rollout status deploy/chat-worker -n chat --timeout=120s
# ์ ์ด๋ฏธ์ง digest ํ์ธ
kubectl get pods -n chat -o jsonpath='{range .items[*]}{.metadata.name}: {.status.containerStatuses[0].imageID}{"\n"}{end}'
ArgoCD Application ์ด๋ฆ ๊ท์น
| ์ฑ | ArgoCD Application | Namespace |
|---|---|---|
| chat-api | dev-api-chat | chat |
| chat-worker | dev-chat-worker | chat |
| scan-api | dev-api-scan | scan |
| scan-worker | dev-scan-worker | scan |
| auth-api | dev-api-auth | auth |
| character-api | dev-api-character | character |
| location-api | dev-api-location | location |
์ Deployment๋ฅผ ์ญ์ ํ๋๊ฐ?
- ์ด๋ฏธ์ง ํ๊ทธ๊ฐ
latest์ด๋ฏ๋ก digest๊ฐ ๋ฐ๋์ด๋ ํ๊ทธ๋ ๋์ผ - ArgoCD๋ ๋งค๋ํ์คํธ ๊ธฐ์ค์ด๋ผ ์ด๋ฏธ์ง ํ๊ทธ๋ง ๋ณด๋ฉด ๋ณ๊ฒฝ ์์
- Deployment ์ญ์ โ Self-Heal ํ์ฑํ ์ ArgoCD๊ฐ ์ฌ์์ฑ โ ์ ์ด๋ฏธ์ง Pull
Pod ์ํ ํ์ธ
# Pod ๋ชฉ๋ก (์ํ ํฌํจ)
kubectl get pods -n eco2
# Pod ์์ธ ์ ๋ณด (์ด๋ฒคํธ ํฌํจ)
kubectl describe pod <pod-name> -n eco2
# Pod ๋ก๊ทธ
kubectl logs <pod-name> -n eco2 --tail=100 -f
# ์ด์ ์ปจํ
์ด๋ ๋ก๊ทธ (์ฌ์์๋ ๊ฒฝ์ฐ)
kubectl logs <pod-name> -n eco2 --previous
์ผ๋ฐ์ ์ธ ๋ฌธ์ ์ง๋จ
# CrashLoopBackOff
kubectl logs <pod-name> -n eco2 --previous
kubectl describe pod <pod-name> -n eco2 | grep -A 10 "Events:"
# ImagePullBackOff
kubectl describe pod <pod-name> -n eco2 | grep -A 5 "Image:"
# Pending ์ํ
kubectl describe pod <pod-name> -n eco2 | grep -A 10 "Events:"
kubectl get events -n eco2 --sort-by='.lastTimestamp'
์ค์๊ฐ ๋๋ฒ๊น
# Pod ๋ด๋ถ ์ ์ ์
kubectl exec -it <pod-name> -n eco2 -- /bin/sh
# ํน์ ์ปจํ
์ด๋ ์ ์ (multi-container)
kubectl exec -it <pod-name> -c <container-name> -n eco2 -- /bin/sh
# ์์ ๋๋ฒ๊ทธ ์ปจํ
์ด๋
kubectl debug -it <pod-name> -n eco2 --image=busybox
Ecoยฒ ๋ผ๋ฒจ ์ ์ฑ
ํต์ฌ ๋ผ๋ฒจ
| ๋ผ๋ฒจ | ๊ฐ | ์ฉ๋ |
|---|---|---|
app | ์๋น์ค๋ช | Pod selector |
domain | auth, chat, scan, character, location | ์๋น์ค ๋๋ฉ์ธ |
tier | business-logic, worker, integration, data | ์ํคํ ์ฒ ๊ณ์ธต |
version | v1, v2 | Canary/Istio ๋ผ์ฐํ |
environment | dev, prod | ํ๊ฒฝ ๊ตฌ๋ถ |
๋ผ๋ฒจ ๊ธฐ๋ฐ ์กฐํ (์์ฃผ ์ฌ์ฉ)
# ๊ณ์ธต๋ณ ์กฐํ
kubectl get pods -l tier=business-logic -A # API ์๋น์ค
kubectl get pods -l tier=worker -A # ์์ปค
kubectl get pods -l tier=integration -A # Event Router, SSE
kubectl get pods -l tier=data -A # Redis, PostgreSQL
# ๋๋ฉ์ธ๋ณ ์กฐํ
kubectl get pods -l domain=chat -A # Chat ๊ด๋ จ ์ ์ฒด
kubectl get pods -l domain=scan -A # Scan ๊ด๋ จ ์ ์ฒด
kubectl get pods -l domain=character -A # Character ์๋น์ค
# Canary ๋ฐฐํฌ ํ์ธ
kubectl get pods -l version=v2 -A # Canary ๋ฒ์ ๋ง
# ํ๊ฒฝ๋ณ ์กฐํ
kubectl get pods -l environment=dev -A
kubectl get pods -l environment=prod -A
Ecoยฒ ์ปดํฌ๋ํธ
| ์ปดํฌ๋ํธ | Namespace | tier | domain |
|---|---|---|---|
| chat-api | chat | business-logic | chat |
| chat-worker | chat | worker | chat |
| event-router | event-router | integration | event-router |
| sse-gateway | sse-consumer | integration | sse |
| character-api | character | business-logic | character |
| location-api | location | business-logic | location |
| scan-api | scan | business-logic | scan |
| scan-worker | scan | worker | scan |
| auth-api | auth | business-logic | auth |
Reference Files
๋๋ฒ๊น
- Pod ํธ๋ฌ๋ธ์ํ : See pod-troubleshooting.md
- ๋ก๊ทธ ๋ถ์: See log-analysis.md
- ๋คํธ์ํฌ ์ง๋จ: See network-diagnosis.md
- ๋ผ๋ฒจ ์ ์ฑ : See label-policies.md
์ธํ๋ผ/๋ฐฐํฌ
- ํด๋ฌ์คํฐ ๊ตฌ์กฐ: See cluster-architecture.md
- GitOps/ArgoCD: See gitops-argocd.md
- Operator/CRD/CR: See operators-crd.md
- Helm ๋ฐฐํฌ: See helm-deployment.md
์์ฃผ ์ฌ์ฉํ๋ ๋ช ๋ น์ด
# ์ ์ฒด ๋ฆฌ์์ค ์ํ
kubectl get all -n eco2
# ์ต๊ทผ ์ด๋ฒคํธ
kubectl get events -n eco2 --sort-by='.lastTimestamp' | tail -20
# ๋ฆฌ์์ค ์ฌ์ฉ๋
kubectl top pods -n eco2
# ConfigMap/Secret ํ์ธ
kubectl get configmap -n eco2
kubectl get secret -n eco2
Score
Total Score
60/100
Based on repository quality metrics
โSKILL.md
SKILL.mdใใกใคใซใๅซใพใใฆใใ
+20
โLICENSE
ใฉใคใปใณในใ่จญๅฎใใใฆใใ
+10
โ่ชฌๆๆ
100ๆๅญไปฅไธใฎ่ชฌๆใใใ
0/10
โไบบๆฐ
GitHub Stars 100ไปฅไธ
0/15
โๆ่ฟใฎๆดปๅ
3ใถๆไปฅๅ ใซๆดๆฐใใใ
0/10
โใใฉใผใฏ
10ๅไปฅไธใใฉใผใฏใใใฆใใ
0/5
โIssue็ฎก็
ใชใผใใณIssueใ50ๆชๆบ
+5
โ่จ่ช
ใใญใฐใฉใใณใฐ่จ่ชใ่จญๅฎใใใฆใใ
+5
โใฟใฐ
1ใคไปฅไธใฎใฟใฐใ่จญๅฎใใใฆใใ
0/5
Reviews
๐ฌ
Reviews coming soon