6.3.2 오브젝트 상태 상세 확인

앞서 kubectl get 명령어를 통해 클러스터 내 오브젝트들의 목록을 확인하고 기본적인 정보를 얻는 방법을 배웠습니다. 하지만 때로는 이러한 요약 정보만으로는 충분하지 않을 때가 있습니다. 특정 파드가 왜 제대로 실행되지 않는지, 디플로이먼트가 원하는 상태로 수렴하지 못하는 이유는 무엇인지 등 문제의 원인을 파악하고 해결하기 위해서는 오브젝트의 상태를 더욱 깊이 있게 들여다볼 필요가 있습니다. 이번 섹션에서는 kubectl이 제공하는 몇 가지 강력한 명령어들을 통해 오브젝트의 상태를 상세하게 확인하고, 문제 해결의 중요한 단서를 찾는 방법을 자세히 알아보겠습니다. 마치 탐정이 사건 현장에서 증거를 수집하듯, 이 명령어들을 통해 우리는 쿠버네티스 오브젝트의 내부를 속속들이 파헤칠 수 있습니다.

6.3.2.1 오브젝트의 모든 것을 보여주는: kubectl describe <resource> <name>

kubectl describe 명령어는 특정 오브젝트에 대한 매우 상세하고 사람이 읽기 쉬운 형태의 정보를 보여줍니다. kubectl get -o yaml이나 kubectl get -o json 명령어가 오브젝트의 전체 명세와 상태를 기계가 처리하기 좋은 형식으로 보여준다면, describe는 이를 좀 더 구조화되고 가독성 높게 정리하여 출력합니다. 특히, 오브젝트의 현재 상태, 최근 발생한 이벤트(Events), 그리고 관련된 다른 오브젝트들의 정보까지 한눈에 파악할 수 있어 문제 해결 과정에서 가장 먼저 사용해 보아야 할 명령어 중 하나입니다.

  • 사용법:kubectl describe <resource-type> <resource-name> (예: kubectl describe pod my-app-pod-xyz) 형태로 사용합니다. 특정 네임스페이스의 오브젝트를 조회하려면 -n <namespace-name> 옵션을 함께 사용할 수 있습니다.
  • 출력 정보의 구성:describe 명령어의 출력 내용은 오브젝트의 종류에 따라 다소 차이가 있지만, 일반적으로 다음과 같은 주요 정보들을 포함합니다.
    • 기본 정보(Name, Namespace, Labels, Annotations 등): 오브젝트의 이름, 소속된 네임스페이스, 설정된 레이블과 어노테이션 등 기본적인 메타데이터를 보여줍니다.
    • 현재 상태(Status): 오브젝트의 현재 단계(Phase), IP 주소(파드의 경우), 컨디션(Conditions), 포트 정보(서비스의 경우), 복제본 수(디플로이먼트나 레플리카셋의 경우) 등 현재 오브젝트가 어떤 상태에 있는지 알려주는 핵심 정보들이 포함됩니다.
    • 명세(Spec) 요약: 오브젝트의 spec 필드에 정의된 주요 설정값들을 요약하여 보여줍니다. 예를 들어, 파드의 경우 어떤 컨테이너들이 실행 중인지, 각 컨테이너의 이미지, 포트, 마운트된 볼륨, 리소스 요청/제한량, 환경 변수 등이 표시됩니다. 디플로이먼트의 경우 롤링 업데이트 전략, 레플리카셋 정보 등이 나타납니다.
    • 최근 이벤트(Events): describe 명령어의 가장 강력한 기능 중 하나입니다. 해당 오브젝트와 관련하여 최근에 발생한 이벤트들의 목록을 시간순으로 보여줍니다. 이벤트는 오브젝트의 생명주기 동안 발생하는 다양한 상황(예: 스케줄링 성공/실패, 이미지 풀링 시작/성공/실패, 컨테이너 생성/시작/종료, 프로브 실패, 볼륨 마운트 성공/실패 등)을 기록합니다. 이러한 이벤트 메시지는 문제가 발생했을 때 그 원인을 추적하는 데 결정적인 단서를 제공하는 경우가 많습니다. 예를 들어, 파드가 Pending 상태에서 더 이상 진행되지 않는다면, describe pod <pod-name>의 이벤트 섹션에서 “FailedScheduling” 이벤트와 함께 그 이유(예: “Insufficient cpu”, “No nodes available to schedule pods”)를 확인할 수 있습니다.
    • 관련 오브젝트 정보(Controlled By, Endpoints 등): 디플로이먼트의 경우 어떤 레플리카셋에 의해 관리되는지, 서비스의 경우 어떤 엔드포인트(파드 IP와 포트)에 연결되어 있는지 등 관련된 다른 오브젝트들의 정보를 함께 보여주어 전체적인 맥락을 이해하는 데 도움을 줍니다.
  • 활용 사례:
    • 파드가 Pending, CrashLoopBackOff, ImagePullBackOff, Error 등 비정상 상태일 때: describe pod <pod-name>을 실행하여 이벤트와 컨테이너 상태를 확인합니다.
      클립보드에 복사
    • 디플로이먼트 업데이트가 실패하거나 멈췄을 때: describe deployment <deployment-name>을 실행하여 롤링 업데이트 상태, 관련 레플리카셋 및 파드 상태, 이벤트를 확인합니다.
    • 서비스가 정상적으로 동작하지 않을 때: describe service <service-name>을 실행하여 엔드포인트가 올바르게 설정되어 있는지, 셀렉터가 의도한 파드들과 매칭되는지 확인합니다.
    • 노드에 문제가 발생했을 때: describe node <node-name>을 실행하여 노드의 컨디션, 할당된 리소스, 시스템 정보, 이벤트를 확인합니다.

kubectl describe는 마치 의사가 환자를 진찰하듯, 오브젝트의 다양한 측면을 종합적으로 살펴보고 문제의 근본 원인을 진단하는 데 매우 효과적인 도구입니다. 문제가 발생하면 가장 먼저 이 명령어를 떠올리시기 바랍니다.

6.3.2.2 컨테이너 내부의 목소리 듣기: kubectl logs <pod-name> [-c container-name]

애플리케이션이 예상대로 동작하지 않을 때, 가장 먼저 확인해야 할 것 중 하나는 바로 애플리케이션 로그입니다. 컨테이너화된 애플리케이션은 일반적으로 표준 출력(stdout)과 표준 에러(stderr) 스트림으로 로그를 출력하며, 쿠버네티스는 이 로그들을 수집하여 접근할 수 있도록 지원합니다. kubectl logs 명령어는 특정 파드 내의 컨테이너가 생성한 로그를 실시간으로 또는 과거 로그를 조회할 수 있게 해주는 매우 유용한 도구입니다.

  • 기본 사용법:kubectl logs <pod-name>: 지정된 파드 내의 (단일 컨테이너인 경우) 컨테이너가 출력한 로그를 보여줍니다.만약 파드 내에 여러 개의 컨테이너가 실행 중이라면(예: 사이드카 패턴), -c <container-name> (또는 –container <container-name>) 옵션을 사용하여 로그를 조회할 특정 컨테이너를 지정해야 합니다. 예를 들어, kubectl logs my-multi-container-pod -c main-app-container와 같이 사용합니다.
  • 주요 옵션:
    • f (또는 –follow): 실시간으로 로그 스트리밍을 시작합니다. 즉, 새로운 로그가 생성될 때마다 터미널에 계속해서 출력됩니다. 디버깅 시 애플리케이션의 현재 동작을 실시간으로 모니터링하는 데 매우 유용합니다. (Ctrl+C를 눌러 종료)
    • p (또는 –previous): 만약 컨테이너가 재시작된 이력이 있다면, 이 옵션을 사용하여 이전 컨테이너 인스턴스가 종료되기 전에 생성했던 로그를 조회할 수 있습니다. CrashLoopBackOff 상태의 파드 문제를 분석할 때 매우 유용합니다.
    • -tail <lines>: 로그의 마지막 N줄만 보여줍니다. 예를 들어, –tail 100은 최근 100줄의 로그만 출력합니다. 전체 로그가 너무 길 때 유용합니다.
    • -since <duration>: 특정 시간 이후의 로그만 보여줍니다. 예를 들어, –since 1h는 지난 1시간 동안의 로그를, –since 10m는 지난 10분 동안의 로그를 보여줍니다. (시간 형식은 s, m, h 등을 사용합니다.)
    • -since-time <timestamp>: RFC3339 형식의 특정 타임스탬프 이후의 로그를 보여줍니다. (예: ‘2023-10-27T10:00:00Z’)
    • -timestamps=true: 각 로그 라인 앞에 타임스탬프를 함께 출력합니다.
    • -limit-bytes <bytes>: 로그 출력 크기를 바이트 단위로 제한합니다.
  • 로그 저장 위치 및 관리:kubelet은 각 컨테이너의 표준 출력/에러 스트림을 잡아내어 워커 노드의 특정 파일(보통 /var/log/pods/… 또는 /var/log/containers/… 경로 아래 JSON 형식)에 저장합니다. kubectl logs 명령어는 이 파일들의 내용을 읽어와 보여주는 것입니다. 로그 파일의 크기나 보관 기간은 kubelet 설정(예: containerLogMaxSize, containerLogMaxFiles)에 따라 제한될 수 있으며, 노드의 디스크 공간을 절약하기 위해 오래된 로그는 자동으로 삭제(rotate)됩니다. 따라서, 장기간 로그 보관이나 중앙 집중식 로그 분석이 필요하다면, 앞서 애드온 섹션에서 언급했던 EFK(Elasticsearch, Fluentd, Kibana) 스택이나 Loki와 같은 별도의 클러스터 로깅 솔루션을 구축하는 것이 좋습니다.
    클립보드에 복사

kubectl logs는 애플리케이션 내부에서 무슨 일이 일어나고 있는지 직접 들여다볼 수 있는 창과 같습니다. 오류 메시지, 경고, 디버깅 정보 등 애플리케이션이 남긴 흔적을 통해 문제의 원인을 파악하고 해결책을 찾는 데 결정적인 도움을 받을 수 있습니다.

6.3.2.3 컨테이너 내부로 직접 들어가기: kubectl exec -it <pod-name> — <command>

때로는 단순히 로그를 보는 것만으로는 부족하고, 실행 중인 컨테이너 내부 환경을 직접 확인하거나 특정 명령어를 실행해보고 싶을 때가 있습니다. 마치 SSH를 통해 원격 서버에 접속하듯이, kubectl exec 명령어는 실행 중인 파드의 특정 컨테이너 내부로 들어가 임의의 명령어를 실행할 수 있게 해주는 강력한 기능을 제공합니다.

  • 기본 사용법:kubectl exec <pod-name> — <command> [args…]: 지정된 파드의 (단일 컨테이너인 경우) 컨테이너 내부에서 <command>를 실행하고 그 결과를 보여줍니다. — 뒤에 실행할 명령어와 인자들을 나열합니다.예를 들어, kubectl exec my-nginx-pod — ls /usr/share/nginx/html은 my-nginx-pod의 컨테이너 내부에서 ls /usr/share/nginx/html 명령을 실행하고 그 결과를 출력합니다.
    클립보드에 복사
  • 인터랙티브 쉘 접속 (-i와 -t 옵션):kubectl exec의 가장 강력한 활용법 중 하나는 바로 컨테이너 내부로 **인터랙티브 쉘(interactive shell)**을 여는 것입니다. 이를 위해서는 -i (또는 –stdin, 표준 입력 활성화) 옵션과 -t (또는 –tty, 가상 터미널 할당) 옵션을 함께 사용합니다.kubectl exec -it <pod-name> — /bin/sh (또는 /bin/bash, 컨테이너 이미지에 설치된 쉘에 따라 다름)이 명령을 실행하면, 마치 해당 컨테이너 내부에 직접 로그인한 것처럼 프롬프트가 나타나고, 여기서 다양한 명령어(예: ls, cat, ps, netstat, 환경 변수 확인, 파일 시스템 탐색 등)를 직접 실행하며 컨테이너의 내부 상태를 실시간으로 조사할 수 있습니다. 디버깅이나 문제 해결 과정에서 매우 유용합니다. (쉘 세션 종료는 exit 명령 사용)
  • 특정 컨테이너 지정 (-c 옵션):파드 내에 여러 컨테이너가 있는 경우, -c <container-name> 옵션을 사용하여 명령을 실행할 대상 컨테이너를 명시해야 합니다.kubectl exec -it my-multi-container-pod -c sidecar-container — /bin/bash
  • 주의사항:
    • kubectl exec를 통해 실행하는 명령어는 해당 컨테이너 이미지에 해당 명령어가 설치되어 있어야만 실행 가능합니다. 예를 들어, 매우 경량화된 alpine 기반 이미지에는 bash 쉘이나 curl, ping과 같은 일반적인 유틸리티가 없을 수도 있습니다. 이 경우, 필요한 도구가 포함된 디버깅용 이미지를 사용하거나, 컨테이너 이미지 빌드 시 필요한 디버깅 도구를 함께 포함시키는 것을 고려해야 합니다.
    • kubectl exec는 강력한 기능인 만큼 보안에 유의해야 합니다. 운영 환경에서는 RBAC을 통해 특정 사용자나 서비스 어카운트가 pods/exec 리소스에 대한 권한을 갖도록 신중하게 제어해야 합니다. 임의의 명령 실행은 잠재적인 보안 위협이 될 수 있기 때문입니다.
    • exec 세션은 일시적인 것이며, 여기서 변경한 내용은 컨테이너가 재시작되면 사라집니다. 영구적인 변경을 원한다면 컨테이너 이미지를 수정하거나 ConfigMap, Secret, PersistentVolume 등을 사용해야 합니다.

kubectl exec는 컨테이너라는 블랙박스의 뚜껑을 열고 그 내부를 직접 탐험할 수 있게 해주는 도구입니다. 파일 시스템 구조 확인, 실행 중인 프로세스 점검, 네트워크 연결 상태 테스트, 환경 변수 검증 등 다양한 디버깅 작업을 수행하는 데 없어서는 안 될 필수 스킬입니다.

지금까지 kubectl describe, kubectl logs, kubectl exec라는 세 가지 강력한 명령어를 통해 쿠버네티스 오브젝트의 상태를 상세하게 확인하고 문제 해결의 실마리를 찾는 방법을 알아보았습니다. 이 명령어들을 숙달하면, 복잡한 쿠버네티스 환경에서 발생하는 다양한 문제 상황에 훨씬 더 자신감 있게 대처할 수 있게 될 것입니다. 마치 숙련된 의사가 청진기, X-레이, MRI 등 다양한 진단 도구를 활용하여 환자의 상태를 정확히 파악하듯, 우리도 이 kubectl 명령어들을 통해 클러스터의 건강 상태를 진단하고 문제점을 해결해 나갈 수 있습니다.