2. kubectl debug 명령어로 실행 중인 Pod에 디버깅 컨테이너를 추가할 때 사용하는 플래그는?
A. --attach B. --copy-to C. --ephemeral D. --sidecar
정답 보기
정답: B. --copy-to
설명:--copy-to 플래그를 사용하면 기존 Pod의 복사본을 생성하고 디버깅 컨테이너나 수정된 설정을 추가할 수 있습니다. --share-processes 플래그와 함께 사용하면 프로세스 네임스페이스를 공유할 수 있습니다.
주요 옵션:
--copy-to: Pod 복사본 생성
--share-processes: 프로세스 네임스페이스 공유
--target: 타겟 컨테이너 지정 (ephemeral container용)
3. 노드가 NotReady 상태일 때 가장 먼저 확인해야 할 것은?
A. Pod 로그 B. kubelet 상태 및 로그 C. etcd 상태 D. CoreDNS 로그
정답 보기
정답: B. kubelet 상태 및 로그
설명: 노드가 NotReady 상태가 되는 가장 일반적인 원인은 kubelet 문제입니다. kubelet이 API 서버와 통신하지 못하면 노드 상태가 NotReady로 변경됩니다.
NotReady 원인 체크리스트:
kubelet 프로세스 상태
네트워크 연결 (API 서버 접근성)
디스크 공간 부족
메모리 부족 (OOM)
컨테이너 런타임 상태
4. PromQL에서 최근 5분간 CPU 사용률이 80%를 초과한 Pod를 찾는 쿼리는?
A. cpu_usage > 80 B. rate(container_cpu_usage_seconds_total[5m]) > 0.8 C. sum(rate(container_cpu_usage_seconds_total[5m])) by (pod) / sum(kube_pod_container_resource_limits{resource="cpu"}) by (pod) > 0.8 D. container_cpu_percent > 80
정답 보기
정답: C. sum(rate(container_cpu_usage_seconds_total[5m])) by (pod) / sum(kube_pod_container_resource_limits{resource="cpu"}) by (pod) > 0.8
설명: CPU 사용률은 실제 사용량을 limit으로 나눈 비율입니다. rate() 함수로 초당 CPU 사용량을 계산하고, limit으로 나누어 백분율을 구합니다.
5. EKS에서 노드 간 네트워크 문제를 디버깅할 때 사용하는 도구로 적합하지 않은 것은?
A. tcpdump B. wireshark C. kubectl exec으로 ping/curl 테스트 D. etcdctl
정답 보기
정답: D. etcdctl
설명: etcdctl은 etcd 데이터베이스를 관리하는 도구로, 네트워크 디버깅과는 관련이 없습니다. EKS에서는 etcd가 AWS에 의해 관리되므로 직접 접근할 수도 없습니다.
네트워크 디버깅 도구:
6. 인시던트 대응에서 MTTD(Mean Time To Detect)를 줄이기 위한 가장 효과적인 방법은?
A. 수동 모니터링 강화 B. 알림 임계값을 매우 낮게 설정 C. 적절한 알림 규칙과 자동화된 모니터링 시스템 구축 D. 로그 보관 기간 연장
정답 보기
정답: C. 적절한 알림 규칙과 자동화된 모니터링 시스템 구축
설명: MTTD를 줄이려면 적절한 임계값의 알림 규칙과 자동화된 모니터링이 필요합니다. 너무 민감한 알림은 알림 피로(Alert Fatigue)를 유발합니다.
MTTD 최적화 전략:
SLO 기반 알림 설정
Multi-window burn rate 알림
알림 우선순위 분류
On-call 로테이션 및 에스컬레이션
7. kubectl debug로 노드에 직접 디버깅 Pod를 생성하는 명령어는?
A. kubectl debug node/<node-name> -it --image=busybox B. kubectl exec node/<node-name> -- sh C. kubectl attach node/<node-name> D. kubectl run debug --node=<node-name>
정답 보기
정답: A. kubectl debug node/<node-name> -it --image=busybox
설명: Kubernetes 1.20+에서 kubectl debug node/ 명령어를 사용하면 노드에 privileged Pod를 생성하여 호스트 파일시스템과 네트워크에 접근할 수 있습니다.
주의사항:
노드 디버깅 Pod는 privileged 모드로 실행됨
호스트 네임스페이스에 접근 가능
프로덕션 환경에서는 RBAC으로 접근 제한 필요
8. 분산 추적(Distributed Tracing)에서 Span의 의미는?
A. 전체 요청의 처리 시간 B. 단일 작업 단위의 시간 측정 C. 서비스 간 네트워크 지연 D. 로그 메시지의 타임스탬프
정답 보기
정답: B. 단일 작업 단위의 시간 측정
설명: Span은 분산 시스템에서 하나의 작업 단위를 나타내며, 시작 시간, 종료 시간, 메타데이터를 포함합니다. 여러 Span이 모여 하나의 Trace를 구성합니다.
분산 추적 개념:
Trace: 전체 요청 흐름을 나타내는 Span들의 집합
Span: 단일 작업 단위 (예: HTTP 요청, DB 쿼리)
Parent-Child 관계: Span 간의 호출 관계
Baggage: Span 간 전파되는 컨텍스트 정보
9. EKS에서 CoreDNS 문제를 디버깅할 때 가장 유용한 명령어는?
A. kubectl logs -n kube-system -l k8s-app=kube-dns B. kubectl describe service kubernetes C. aws eks describe-cluster D. kubectl get endpoints
정답 보기
정답: A. kubectl logs -n kube-system -l k8s-app=kube-dns
설명: CoreDNS Pod의 로그를 확인하면 DNS 쿼리 처리 상태, 오류, 타임아웃 등을 파악할 수 있습니다.
CoreDNS 일반적인 문제:
Pod 리소스 부족 (CPU/Memory)
ConfigMap 설정 오류
업스트림 DNS 연결 문제
클러스터 IP 서비스 연결 문제
10. kubectl을 사용하여 Pod의 리소스 사용량을 실시간으로 확인하는 명령어는?
A. kubectl describe pod B. kubectl top pods C. kubectl get pods -o wide D. kubectl logs
정답 보기
정답: B. kubectl top pods
설명:kubectl top 명령어는 Metrics Server가 수집한 리소스 사용량 데이터를 표시합니다. CPU와 메모리 사용량을 실시간으로 확인할 수 있습니다.
사전 요구사항:
Metrics Server 설치 필요
kubectl top은 실시간 스냅샷만 제공 (히스토리 없음)
장기 모니터링은 Prometheus + Grafana 사용
단답형 문제
1. EKS 컨트롤 플레인 로그를 CloudWatch Logs에서 확인할 때 사용하는 로그 그룹 이름 패턴은 무엇인가요?
정답 보기
정답:/aws/eks/<cluster-name>/cluster
설명: EKS 컨트롤 플레인 로그는 자동으로 이 로그 그룹으로 전송됩니다.
2. Kubernetes에서 Ephemeral Container를 활성화하는 데 필요한 feature gate 이름은 무엇인가요?
정답 보기
정답:EphemeralContainers (Kubernetes 1.25+에서는 기본 활성화)
설명: Kubernetes 1.23부터 beta, 1.25부터 GA(Generally Available)로 기본 활성화되어 있습니다. EKS 1.25 이상에서는 별도 설정 없이 사용 가능합니다.
3. PromQL에서 rate() 함수와 irate() 함수의 차이점은 무엇인가요?
정답 보기
정답:
rate(): 지정된 시간 범위 전체의 평균 변화율 계산 (smooth)
irate(): 가장 최근 두 데이터 포인트만 사용하여 순간 변화율 계산 (volatile)
# 기존 Pod 복사본에 디버그 컨테이너 추가
kubectl debug myapp-pod --copy-to=myapp-debug --container=debugger --image=busybox -- sh
# 프로세스 네임스페이스 공유
kubectl debug myapp-pod --copy-to=myapp-debug --share-processes --container=debugger --image=busybox
# Ephemeral 컨테이너로 직접 디버깅 (Pod 복사 없이)
kubectl debug -it myapp-pod --image=busybox --target=myapp-container
# 노드 상태 확인
kubectl describe node <node-name>
# 노드에 SSH 접속 후 kubelet 상태 확인
systemctl status kubelet
# kubelet 로그 확인
journalctl -u kubelet -f
# kubelet 재시작
sudo systemctl restart kubelet
# CPU 사용률 (limit 대비)
sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) by (pod, namespace)
/
sum(kube_pod_container_resource_limits{resource="cpu"}) by (pod, namespace)
* 100 > 80
# 메모리 사용률
sum(container_memory_working_set_bytes{container!=""}) by (pod, namespace)
/
sum(kube_pod_container_resource_limits{resource="memory"}) by (pod, namespace)
* 100 > 80
# 특정 네임스페이스의 CPU 사용량 Top 10
topk(10, sum(rate(container_cpu_usage_seconds_total{namespace="production"}[5m])) by (pod))
# tcpdump로 패킷 캡처
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- tcpdump -i eth0
# 노드 간 연결 테스트
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- ping <other-node-ip>
# Pod 내에서 네트워크 테스트
kubectl exec -it <pod-name> -- curl -v http://service-name
# DNS 테스트
kubectl exec -it <pod-name> -- nslookup kubernetes.default.svc.cluster.local
# CoreDNS 로그 확인
kubectl logs -n kube-system -l k8s-app=kube-dns -f
# CoreDNS Pod 상태 확인
kubectl get pods -n kube-system -l k8s-app=kube-dns
# CoreDNS ConfigMap 확인
kubectl get configmap coredns -n kube-system -o yaml
# DNS 테스트 Pod 생성
kubectl run dns-test --image=busybox:1.28 --rm -it --restart=Never -- nslookup kubernetes.default
# DNS 쿼리 디버깅
kubectl exec -it <pod-name> -- nslookup -debug kubernetes.default.svc.cluster.local
# 모든 네임스페이스의 Pod 리소스 사용량
kubectl top pods -A
# 특정 네임스페이스의 Pod
kubectl top pods -n production
# 컨테이너별 리소스 사용량
kubectl top pods --containers
# 노드 리소스 사용량
kubectl top nodes
# CPU 기준 정렬
kubectl top pods --sort-by=cpu
# 메모리 기준 정렬
kubectl top pods --sort-by=memory
# CloudWatch Logs Insights 쿼리 예시
# 로그 그룹: /aws/eks/my-cluster/cluster
# API 서버 에러 로그 검색
fields @timestamp, @message
| filter @logStream like /kube-apiserver/
| filter @message like /error|Error|ERROR/
| sort @timestamp desc
| limit 50
# 감사 로그에서 특정 사용자 활동 검색
fields @timestamp, @message
| filter @logStream like /kube-apiserver-audit/
| filter @message like /"user":.*"admin"/
| sort @timestamp desc
# Ephemeral Container 추가
kubectl debug -it <pod-name> --image=busybox --target=<container-name>
# Ephemeral Container 확인
kubectl get pod <pod-name> -o jsonpath='{.spec.ephemeralContainers}'
# Pod에 추가된 Ephemeral Container 목록
kubectl describe pod <pod-name> | grep -A 10 "Ephemeral Containers"
# rate() - 5분간 평균 요청률 (알림, 대시보드에 적합)
rate(http_requests_total[5m])
# irate() - 순간 요청률 (급격한 변화 감지에 적합)
irate(http_requests_total[5m])
# CPU 사용률 - rate() 권장
rate(container_cpu_usage_seconds_total[5m])
# 스파이크 감지 - irate() 권장
irate(http_requests_total[1m]) > 1000
# 노드 디버깅 Pod 생성
kubectl debug node/<node-name> -it --image=busybox
# Pod 내에서 호스트 파일시스템 접근
ls /host
cat /host/etc/kubernetes/kubelet/kubelet-config.json
# 호스트 환경으로 chroot
chroot /host
# chroot 후 호스트 명령어 실행
systemctl status kubelet
journalctl -u kubelet -n 100
MTTR = MTTD + MTTI + MTTFix
MTTD 개선:
- 효과적인 모니터링 및 알림
- SLO 기반 알림 설정
MTTI 개선:
- 런북(Runbook) 작성
- 자동화된 진단 도구
MTTFix 개선:
- 자동 복구 메커니즘
- 롤백 자동화
- GitOps 기반 배포
# 최근 5분간 재시작 횟수가 2회 이상인 컨테이너
increase(kube_pod_container_status_restarts_total{namespace="production"}[5m]) >= 2
# 재시작 횟수와 함께 Pod 이름 표시
sum by (pod, container) (
increase(kube_pod_container_status_restarts_total{namespace="production"}[5m])
) >= 2
# 전체 재시작 횟수 (누적)
kube_pod_container_status_restarts_total{namespace="production"} > 5
# 최근 1시간 동안 가장 많이 재시작된 Pod Top 10
topk(10,
increase(kube_pod_container_status_restarts_total{namespace="production"}[1h])
)
# P99 응답 시간 확인
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket{service="api-gateway"}[5m])) by (le, endpoint)
)
# 응답 시간 분포 확인 (히트맵용)
sum(rate(http_request_duration_seconds_bucket{service="api-gateway"}[1m])) by (le)
# 느린 요청 비율
sum(rate(http_request_duration_seconds_count{service="api-gateway"}[5m]))
-
sum(rate(http_request_duration_seconds_bucket{service="api-gateway",le="0.5"}[5m]))
# Jaeger 쿼리 전략
# 1. 느린 트레이스 검색 (>2초)
service=api-gateway minDuration=2s
# 2. 에러가 포함된 트레이스
service=api-gateway tags={"error":"true"}
# 3. 특정 엔드포인트의 트레이스
service=api-gateway operation="GET /api/products"
# Trace ID로 관련 로그 검색
kubectl logs -l app=api-gateway | grep "trace_id=abc123"
# CloudWatch Logs Insights
fields @timestamp, @message
| filter @message like /trace_id=abc123/
| sort @timestamp asc
# Pod CPU Throttling 확인
rate(container_cpu_cfs_throttled_seconds_total[5m])
# 네트워크 지연
rate(container_network_receive_bytes_total[5m])
# GC 영향 분석 (Java)
rate(jvm_gc_pause_seconds_sum[5m])
# Grafana 대시보드 구성
panels:
- title: "Request Latency (P50, P95, P99)"
query: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
- title: "Request Rate by Status"
query: sum(rate(http_requests_total[5m])) by (status_code)
- title: "Slow Requests Heatmap"
query: sum(increase(http_request_duration_seconds_bucket[1m])) by (le)
- title: "Downstream Service Latency"
query: histogram_quantile(0.99, sum(rate(downstream_request_duration_seconds_bucket[5m])) by (le, service))
- title: "Pod Resource Usage"
queries:
- container_cpu_usage_seconds_total
- container_memory_working_set_bytes
# 1. 노드 이벤트 히스토리 확인
kubectl get events --field-selector involvedObject.kind=Node --sort-by='.lastTimestamp'
# 2. 노드 상태 상세 확인
kubectl describe node <node-name> | grep -A 20 "Conditions:"
# 3. CloudWatch에서 노드 메트릭 확인
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name StatusCheckFailed \
--dimensions Name=InstanceId,Value=<instance-id> \
--start-time $(date -d '24 hours ago' -u +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 300 \
--statistics Sum
# 노드에 디버깅 Pod 배포
kubectl debug node/<node-name> -it --image=amazonlinux:2 -- bash
# chroot로 호스트 환경 접근
chroot /host
# 시스템 로그 확인
journalctl -u kubelet --since "24 hours ago" | grep -i "error\|fail\|timeout"
dmesg | tail -100
# 메모리/CPU 상태 확인
free -h
vmstat 1 5
cat /proc/pressure/memory
cat /proc/pressure/cpu
# API 서버 연결 확인
curl -k https://kubernetes.default.svc.cluster.local/healthz
# VPC CNI 상태 확인
kubectl logs -n kube-system -l k8s-app=aws-node --tail=100
# ENI 및 IP 할당 상태
aws ec2 describe-network-interfaces \
--filters Name=attachment.instance-id,Values=<instance-id>
# 3. 노드 자동 복구 설정 (Karpenter)
# Karpenter는 NotReady 노드를 자동으로 교체
# 4. kubelet 설정 최적화
# /etc/kubernetes/kubelet/kubelet-config.json
{
"evictionHard": {
"memory.available": "500Mi",
"nodefs.available": "10%",
"imagefs.available": "15%"
},
"evictionSoft": {
"memory.available": "1Gi",
"nodefs.available": "15%"
},
"evictionSoftGracePeriod": {
"memory.available": "1m",
"nodefs.available": "1m"
}
}
## 인시던트 요약
- 발생 시간: 2024-01-15 14:30 KST
- 영향 범위: 노드 3대, Pod 45개 영향
- 해결 시간: 2024-01-15 15:15 KST (MTTR: 45분)
## 타임라인
- 14:30 - 알림 발생: NodeNotReady
- 14:35 - 초기 분석 시작
- 14:50 - 근본 원인 식별: 메모리 압박으로 인한 kubelet OOM
- 15:00 - 노드 드레인 및 재시작
- 15:15 - 정상화 확인
## 근본 원인
메모리 누수가 있는 애플리케이션으로 인해 노드 메모리 고갈
## 재발 방지 대책
1. [완료] 문제 애플리케이션 메모리 limit 설정
2. [진행중] 노드 메모리 압박 알림 임계값 조정 (90% -> 80%)
3. [계획] Node Problem Detector 배포