Cluster Operations: Monitoring & Troubleshooting

성윤·2026년 2월 15일

[☸️Kubernetes]

목록 보기
6/13
post-thumbnail

들어가며 👋

지난 포스팅에서는 파드의 무중단 롤링 업데이트부터 generateName을 활용한 동적 할당, 그리고 wait--prune을 이용한 꼼꼼한 생명주기 제어 방법에 대해 알아보았습니다.

배포를 무사히 마쳤다면, 이제는 "시스템이 잘 돌아가고 있는지 감시하고, 에러가 터졌을 때 빠르게 원인을 찾아내는" 운영(Operation) 단계로 넘어갈 차례입니다.

이번 포스팅에서는 실제 쿠버네티스 환경에서 가장 많이 타이핑하게 될 필수 모니터링 명령어와 트러블슈팅의 핵심인 로그 확인, 쉘 접속, 포트포워딩 기법에 대해 정리해 보겠습니다. 🚀


1. 리소스 종류 및 상세 정보 조회 (api-resources & get) 📋

클러스터에 어떤 리소스들이 있는지, 현재 상태는 어떤지 파악하는 것은 운영의 기본이라고 할 수 있습니다.


1) 사용 가능한 리소스 종류 확인

쿠버네티스에는 파드, 서비스 외에도 수많은 리소스가 존재합니다. 해당 리소스가 네임스페이스에 속하는지(Namespaced) 아니면 클러스터 전체에 적용되는지 파악할 수 있습니다.

  • 모든 리소스 종류 표시: kubectl api-resources
  • 네임스페이스 수준의 리소스만 확인: kubectl api-resources --namespaced=true
  • 클러스터 수준의 리소스만 확인: kubectl api-resources --namespaced=false


2) 리소스 정보 가져오기 및 출력 포맷팅 (-o)

명령어를 조합하여 특정 조건의 리소스를 찾거나, 원하는 형태로 데이터를 추출할 수 있습니다.

  • 기본 및 필터링 조회:

    • 리소스 전체 가져오기: kubectl get all

    • 특정 리소스 정보만 가져오기: kubectl get [리소스종류]

    • 하나의 리소스만 가져오기: kubectl get [리소스종류] [리소스이름]

    • 특정 레이블을 가진 리소스 가져오기: kubectl get [리소스종류] [label이름]=[label값]

    • 노드 목록 표시: kubectl get nodes


  • 다양한 출력 포맷 활용하기 (-o):

    자세히 보기를 원할 때는 -o 옵션 뒤에 JSON, YAML, Custom Columns, JSON Path, Go Template 등의 형식을 지정할 수 있습니다.


  # pod 정보를 yaml 형식으로 모든 명세서 보기
  kubectl get pods -o yaml sample-pod

  # Custom-columns: 특정 컬럼의 값을 내 입맛대로 변경해서 출력
  # (.metadata.name을 'NAME'으로, .status.hostIP를 'NodeIP'로 출력)
  kubectl get pods -o custom-columns="NAME:{.metadata.name}, NodeIP:{.status.hostIP}"

  # JSON Path: 텍스트 파싱을 위해 특정 속성의 값 하나만 출력
  kubectl get pods sample-pod -o jsonpath="{.metadata.name}"

💡 실무 팁: -o yaml

에러가 난 파드의 현재 상태나 전체 설정을 그대로 확인하고 싶을 때는 kubectl get pod [이름] -o yaml을 쳐서 확인하는 것이 가장 정확하고 확실한 방법입니다.


3) 파드 상세 정보와 이벤트 확인 (describe) 🕵️‍♂️

get 명령어로 상태를 확인했는데 파드가 Pending (대기중)이거나, CrashLoopBackOff, ImagePullBackOff 등의 에러 상태에 빠져있다면 당황을 하게 됩니다.

여기서 문제는 파드가 제대로 뜨지도 않은 상태라 logs 명령어를 쳐도 아무것도 안나온 다는 것이죠.

이럴 때 원인을 파악하기 위해 반드시 쳐야 하는 명령어가 바로 describe입니다.


# 특정 파드의 상세 정보와 생성 과정(Events) 확인
kubectl describe pod sample-pod

이 명령어를 치면 파드의 IP, 할당된 노드, 레이블, 컨테이너 정보 등 모든 상세 명세가 나옵니다.


하지만 여기서 가장 중요한 부분은 맨 아래에 출력되는 Events 항목입니다.

# (출력 예시 - 맨 아래 Events 부분)
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  24s                default-scheduler  Successfully assigned default/sample-pod to node-1
  Normal   Pulling    23s                kubelet            Pulling image "nginx:latest"
  Warning  Failed     10s (x3 over 22s)  kubelet            Failed to pull image "nginx:latetst": rpc error: code = NotFound

💡실무 팁: 트러블슈팅의 시작은 Events 확인부터!

위 예시처럼 Events 탭을 보면 이미지 이름에 오타가 나서(latetst) 이미지를 당겨오지 못했다는 것을 단번에 알 수 있습니다.

문제가 생겼을 때는 가장 먼저 describe의 Events를 확인하는 습관을 들이는 것이 좋습니다.


2. 클러스터 리소스 사용량 모니터링 (top) 📊

현재 노드나 파드가 CPU와 메모리를 얼마나 차지하고 있는지 확인하려면 top 명령어를 사용합니다.

단, 이 명령어는 Metric Server가 클러스터에 설치되어 있어야만 동작합니다.


1) Metrics Server 설치 및 확인

# Metrics Server 설치 (공식 GitHub 매니페스트 적용)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# kube-system 네임스페이스에 metrics-server 파드가 잘 떴는지 확인
kubectl -n kube-system get pods

2) 리소스 사용량 측정

  • 노드의 리소스 사용량 확인: kubectl top node
  • 파드의 리소스 사용량 확인: kubectl -n kube-system top pod
  • 컨테이너 단위 사용량 상세 확인: kubectl -n kube-system top pod --containers

💡 실무 팁: Metrics Server의 한계와 Prometheus

kubectl top 명령어는 "지금 이 순간"의 실시간 리소스 사용량만 보여줍니다. 과거의 사용량 기록이나 그래프 추이를 보려면, 실무에서는 프로메테우스(Prometheus)와 그라파나(Grafana)를 연동하여 모니터링 시스템을 구축하는 것이 표준입니다.


3. 파드 내부 진입 및 파일 복사 (exec & cp) 💻

컨테이너 내부에 직접 들어가서 구조를 뜯어보거나, 로컬과 컨테이너 간에 파일을 주고받아야 할 때 사용합니다.


1) 컨테이너에 명령 수행 (exec)

# 단일 컨테이너 파드에 쉘 접속 및 명령어 실행
kubectl exec -it sample-pod -- /bin/ls

# 여러 컨테이너가 묶인 파드의 경우, 특정 컨테이너(-c)를 지정하여 실행
kubectl exec -it sample-pod -c nginx-container -- /bin/ls

2) 파일 복사 (cp)

로컬 컴퓨터의 파일을 컨테이너 내부로 밀어 넣거나, 반대로 컨테이너 안의 파일을 로컬로 가져올 때 사용합니다.

# 명령어 구조
kubectl cp [소스] [타겟]

4. 로컬에서 클러스터 내부로 직접 연결 (port-forward) 🌐

Service나 Ingress를 외부에 완전히 노출하지 않은 상태에서, 내 PC(로컬)에서 클러스터 내부 리소스로 직접 트래픽을 꽂아 테스트하고 싶을 때 사용합니다.

# 구조: 외부포트(내 PC) : 내부포트(클러스터 리소스)
kubectl port-forward [리소스종류]/[리소스이름] 외부포트:내부포트
  • 파드(Pod): 해당 파드로 트래픽을 직접 포워딩합니다.
  • 레플리카셋/디플로이먼트: 설정된 파드 중 임의의 하나로 트래픽을 포워딩합니다.
  • 서비스(Service): 서비스에 연결된 파드 중 임의의 하나로 트래픽을 포워딩합니다 (로드밸런싱되지 않습니다).

⚠️ 주의할 점
port-forward는 개발 중 디버깅과 임시 테스트를 위한 도구입니다. 운영 환경에서 외부 트래픽을 받을 목적으로 사용해서는 절대 안 되며, 터미널 창을 닫으면 연결도 즉시 끊어집니다.


5. 문제 해결의 꽃: 로그 확인 (logs) 📝

유지 보수를 할 때 중요하며, 장애 발생 시 원인 파악을 위해 가장 먼저 쳐봐야 하는 명령어가 바로 로그입니다.

  • 파드의 로그 확인: kubectl logs [파드이름]
  • 다중 컨테이너 파드의 특정 컨테이너 로그 확인: kubectl logs [파드이름] -c [컨테이너이름]

[로그 분석 시 유용한 필수 옵션들]

  • 실시간 로그 스트리밍: -f
  • 특정 시간 이내의 로그 출력: --since=[숫자단위] (예: 1시간 이내 --since=1h)
  • 로그 발생 시간 같이 출력: --timestamp=true
  • 마지막 몇 개만 깔끔하게 출력: --tail=[개수]
  • 특정 레이블의 모든 파드 로그 동시 출력: --selector [레이블]

💡 실무 팁: 죽어버린 이전 컨테이너의 로그 보기 (--previous / -p)
파드가 자꾸 재시작 중(CrashLoopBackOff)일 때 그냥 logs를 치면, 막 새로 떠서 아직 에러를 뱉지 않은 빈 화면만 나오는 경우가 있습니다. 이때 "죽어버린 직전 컨테이너가 마지막으로 뱉은 단말마(로그)"를 보려면 --previous 옵션을 꼭 함께 사용해 보세요!


🚨 실전 장애 해결 시나리오 (Troubleshooting Flow)

실제 작업 환경에서 장애가 발생했을 때 어떤 흐름대로 트러블슈팅을 진행을 할까요.?

궁금해서 위에서 배운 명령어들을 실제 장애 상황에서 어떤 순서로 조합해서 쓰는지 찾아보고 하나의 흐름으로 정리해보았습니다.

1) 상태 감지 (get -w)

배포 후 kubectl get pods -w를 켜두고 파드 상태가 실시간으로 변하는 것을 지켜봅니다. (-w 옵션은 실시간으로 작동되는 것을 보여줍니다.)

여기서 파드 하나가 Error 상태를 내며 작동을 멈췄다고 가정을 해보겠습니다.


2) 원인 추적 1단계: 스케쥴링/환경 문제 파악 (describe)

kubectl describe pod [에러난 파드]를 쳐서 맨 밑의 Events를 확인합니다.

CPU나 메모리 자원이 부족해서 노드에 할당을 못 받은 건지(Pending), 이미지 이름이 틀린 건지 등 인프라 단의 문제를 먼저 체크합니다.


3) 원인 추적 2단계: 애플리케이션 에러 파악 (logs)

인프라 설정에 문제가 없다면, 내부 애플리케이션 로직 문제입니다.

kubectl logs -f --previous [파드 이름]을 쳐서 직전에 죽어버린 컨테이너가 뱉은 에러 로그(Exception)를 확인합니다.


4) 원인 추적 3단계: 내부 환경 직접 확인 (exec)

로그만으로 부족하다면 kubectl exec -it [파드 이름] -- /bin/sh로 직접 들어갑니다.

내부 라우팅 테이블이나 DNS 질의가 잘 되는지, 특정 포트가 열려있는지 등 네트워크와 환경 변수 상태를 직접 체크하며 문제를 좁혀나갑니다.


마치며 ✍️

오늘은 모니터링과 트러블슈팅의 핵심 명령어(get -o, describe, top, exec, port-forward, logs, cp)들을 정리해 보았습니다.

아무리 완벽하게 설계된 아키텍처라도 에러는 무조건 발생하기 마련입니다. 오늘 배운 트러블슈팅 도구들을 적재적소에 조합하면 문제의 원인을 짚어내는 시간을 획기적으로 줄일 수 있을 것입니다.

다음 포스팅에서는 본격적으로 쿠버네티스 클러스터에서의 핵심 API 중 하나인 Workload API에 대해 알아보도록 하겠습니다.

0개의 댓글