[Kubernetes] 4. 기본 개념 (4편) - Kubectl 활용

JIWON·2025년 7월 1일

Kubernetes

목록 보기
4/32
post-thumbnail

kubectl 활용: 조회, 디버깅, 매니페스트 전략

kubectl 을 사용하여 클러스터의 리소스를 효과적으로 조회하고, 문제가 발생했을 때 디버깅하며, 리소스를 체계적으로 관리하기 위한 매니페스트 설계 전략(레이블, 어노테이션)에 대해 정리한다.

1. 리소스 정보 조회 및 모니터링

1) 기본 정보 조회: kubectl get

kubectl get은 가장 기본적이면서도 자주 사용하는 리소스 조회 명령어이다.

  • 클러스터의 주요 리소스 전체 가져오기: kubectl get all

  • 특정 종류의 리소스 전체 목록 가져오기: kubectl get 리소스종류 (예: kubectl get pods)

  • 특정 이름을 가진 리소스 정보 가져오기: kubectl get 리소스종류 리소스이름 (예: kubectl get pod sample-pod)

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

  • 노드 목록 표시: kubectl get nodes

2) 출력 형식 제어: -o (--output) 옵션

--output 또는 -o 옵션을 사용하면 kubectl get 의 출력 결과를 JSON, YAML 등 다양한 형식으로 제어할 수 있다.

  • 자세히 표시 (-o wide): IP, 노드(Node) 등 추가적인 정보를 함께 표시한다.
kubectl get pods -o wide

  • YAML 형식으로 표시 (-o yaml): 리소스의 전체 Spec을 YAML 형식으로 출력한다. 특정 리소스의 전체 설정을 확인할 때 유용하다.
kubectl get pods sample-pod -o yaml
  • 사용자 정의 열 (-o custom-columns): 원하는 정보만 선택하여 새로운 테이블 형식으로 출력한다.
kubectl get pods -o custom-columns="NAME:{.metadata.name}, NodeIP:{.status.hostIP}"

  • JSON Path 형식 (-o jsonpath): 특정 필드의 값만 정확히 추출한다. 셸 스크립트에서 특정 값을 변수로 지정할 때 자주 사용된다.
# 파드 이름만 추출
kubectl get pods sample-pod -o jsonpath="{.metadata.name}"
# 결과: sample-pod

# 배열 데이터에서 특정 컨테이너의 이미지 이름만 필터링하여 추출
kubectl get pods sample-pod -o jsonpath="{.spec.containers[?(@.name=='nginx-container')].image}"
# 결과: nginx:1.16
  • Go Template 형식 (-o go-template): 반복문이나 조건문 같은 제어 구문을 사용하여 가장 유연하게 출력 형식을 만들 수 있다.
kubectl get pods -o go-template="{{range .items}}{{.metadata.name}} : {{range .spec.containers}}{{.image}}{{end}} {{end}}"
# 결과:
# sample-pod: 1.17

3) 상세 정보 및 이벤트 확인 : describe

kubectl describe는 리소스의 상태, 설정, 그리고 가장 중요한 이벤트(Events) 로그를 사람이 읽기 좋은 형태로 제공한다. 파드가 실행되지 않는 등 문제 해결에 필수적이다.

kubectl describe pod <pod-name>

4) 실시간 모니터링 : --watch

--watch 또는 -w 옵션을 사용하면 리소스 상태가 변경될 때마다 결과를 계속해서 출력하여 실시간 모니터링이 가능하다.

kubectl get pods sample-pods --watch

5) 사용 가능한 리소스 목록 조회 : kubectl api-resources

현재 클러스터에서 사용 가능한 모든 API 리소스의 종류와 단축어, API 그룹 등을 목록으로 보여준다.

kubectl api-resources

kubectl get all로 가져오지 못하는 정보 가져오기:

kubeclt get all은 모든 리소스를 보여주지 않는다. 네임스페이스에 속한 모든 리소스를 조회하려면 다음 명령어를 사용할 수 있다.

kubectl get $(kubectl api-resources --namespaced=true --verbs=list -o name | tr '\n' ',' | sed -e 's/,$//g')

6) 리소스 사용량 확인: kubectl top

kubectl top 명령어는 노드나 파드의 CPU, 메모리 사용량을 확인할 수 있게 해준다. (참고: Minikube 등 일부 환경에서는 Metrics Server 애드온이 설치되어 있어야 정상적으로 동작한다. )

  • 노드의 리소스 사용량 확인
kubectl top node
  • 파드의 리소스 사용량 확인
# default 네임스페이스가 아닌 경우 -n 옵션으로 지정
kubectl -n kube-system top pod
  • 컨테이너별 리소스 사용량 확인
kubectl -n kube-system top pod --containers

2. 파드 디버깅 및 상호작용

애플리케이션이 정상적으로 동작하는지 확인하거나 문제가 발생했을 때 원인을 파악하려면, 실행 중인 컨테이너에 직접 접속하여 상태를 확인해야 할 때가 많다. kubectl 은 컨테이너와 상호작용할 수 있는 여러 디버깅 명령어를 제공한다.

1) 컨테이너 내부에서 명령어 실행: kubectl exec

kubectl exec 명령어는 실행 중인 컨테이너 안으로 들어가 명령어를 실행할 수 있게 해준다. -it 옵션을 함께 사용하면 상호작용이 가능한 셸(shell) 환경에 접속할 수 있다.

  • 컨테이너 내부 셸 접속:
kubectl exec -it sample-pod -- /bin/bash
  • 특정 컨테이너 지정 (-c 옵션):
    하나의 파드에 여러 컨테이너가 있을 때, -c 옵션으로 명령어를 실행할 컨테이너를 지정한다.
kubectl exec -it sample-pod -c nginx-container -- /bin/ls
  • 인수를 전달하여 명령어 실행
kubectl exec -it sample-pod -- /bin/bash -c "ls -all --classify | grep lib"

2) 파드 로그 확인하기: kubectl logs

kubectl logs 명령어는 파드 내 컨테이너의 표준 출력(stdout) 및 표준 에러(stderr) 로그를 확인하는 데 사용된다.

  • 기본 로그 확인:
kubectl logs 파드이름
  • 특정 컨테이너 로그 확인:
kubectl logs 파드이름 -c 컨테이너이름
  • 실시간 로그 스트리밍 (-f):
    -f 또는 --follow 옵션을 사용하면 새로운 로그가 발생할 때마다 실시간으로 출력된다.
kubectl logs -f <pod-name>
  • 최근 로그 필터링:
    --since (시간), --tail (줄 수) 옵션을 조합하여 원하는 로그만 볼 수 있다.
# 최근 1시간 이내의 로그 중 마지막 10건을 타임스탬프와 함께 출력
kubectl logs --since=1h --tail=10 --timestamps=true 파드이름
  • 레이블로 여러 파드 로그 확인:
    --selector 옵션을 사용하여 특정 레이블을 가진 모든 파드의 로그를 한 번에 볼 수 있다.
kubectl logs --selector app=myapp

3) 로컬에서 파드에 접근하기: kubectl port-forward

kubectl port-forward는 개발자의 로컬 머신 포트와 파드의 포트를 연결하여, 마치 로컬에서 실행 중인 것처럼 애플리케이션에 직접 접근할 수 있게 해주는 명령어이다.

# 로컬 8080 포트를 sample-pod의 80 포트로 연결
kubectl port-forward pod/sample-pod 8080:80

이제 로컬 브라우저에서 http://localhost:8080 으로 파드에 접근할 수 있다.

4) 로컬과 컨테이너 간 파일 복사: kubectl cp

kubectl cp 명령어는 로컬 머신과 파드 내 컨테이너 간에 파일을 복사할 수 있게 해준다.

kubectl cp <소스 경로> <타겟 경로>
  • 파드에서 로컬로 파일 복사하기
# sample-pod의 /etc/hostname 파일을 현재 로컬 디렉터리로 복사
kubectl cp sample-pod:etc/hostname ./hostname
  • 로컬에서 파드로 파일 복사하기
# 로컬의 hostname 파일을 sample-pod의 /tmp/newfile 경로로 복사
kubectl cp hostname sample-pod:/tmp/newfile

3. 매니페스트 관리 전략: 메타데이터

1) 어노테이션 (Annotation)

어노테이션은 metadata.annotations 필드를 통해 설정할 수 있는 메타데이터이다. 어노테이션 자체는 어떤 동작을 유발하지 않으며, 특정 시스템 구성 요소가 이 값을 읽어 정해진 처리를 수행할 때 의미를 가진다. 리소스에 대한 단순 메모나, 값에 수치를 사용할 경우 큰따옴표로 묶어줘야 한다. 매니페스트에 작성할 수 도 있지만 kubectl에서 직접 부여하는 것도 가능하다.

어노테이션 용도

  • 시스템 구성 요소를 위한 데이터 저장: 특정 컨트롤러나 운영자가 참고할 데이터를 저장한다.

  • 시스템 구성 요소의 자동 부여: 시스템이 리소스를 업데이트할 때 필요한 정보를 자동으로 부여한다.

  • 모든 환경에서 사용할 수 없는 설정: 특정 환경에서만 유효한 설정을 정의한다.

  • 정식 통합 전 기능 설정: 알파 또는 베타 버전의 기능을 임시로 설정할 때 사용한다.

2) 레이블(Label)

레이블은 metadata.labels 필드에 설정하며, 리소스를 식별하고 그룹화하기 위한 핵심 메타데이터이다. 개발자나 시스템이 특정 조건을 만족하는 리소스 집합을 선택하는 데 사용된다.

레이블 용도

  • 개발자 사용: 개발자는 레이블을 통해 수많은 리소스를 효율적으로 필터링하고 관리할 수 있다. 예를 들어, env: devapp: C 레이블을 동시에 가진 리소스만 조회하는 것이 가능하다.

  • 시스템 사용: 쿠버네티스 시스템은 레이블을 기준으로 동작을 제어한다.

    • ReplicaSet: 레이블 셀렉터(Selector)를 이용해 특정 레이블이 부여된 파드의 수를 계산하고, 설정된 레플리카 수와 일치하도록 파드를 생성하거나 삭제한다.

    • Service (LoadBalancer): 레이블을 기준으로 요청을 전달할 목적지 파드를 결정한다

3) 어노테이션과 레이블의 차이점

어노테이션과 레이블은 모두 리소스에 Key-Value 형식의 메타데이터를 추가하지만, 용도가 명확히 다르다.

레이블 (Label):

  • 식별 및 그룹화 용도. (예: app: nginx, env: prod)

  • 리소스를 선택(Select)하는 데 사용된다. (예: Service가 요청을 보낼 파드를 선택)

  • kubectl get pods -l env=prod 처럼 필터링에 사용된다.

어노테이션 (Annotation):

  • 비식별용 메타데이터. 시스템 도구나 사용자 참고용 정보를 저장한다.

  • 빌드 버전, 릴리스 정보, 설정 설명 등 리소스 식별과 관련 없는 모든 정보를 기록한다.

  • 레이블처럼 리소스를 선택하는 데 사용할 수 없다.

4) 어노테이션 실습

YAML 파일로 어노테이션 생성

sample-annotations.yaml 파일을 작성하여 어노테이션을 포함한 파드를 생성한다.

  • sample-annotations.yaml 파일을 작성
# sample-annotations.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-annotations
  annotations:
    annotation1: val1
    annotation2: "200"
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
  • 파드 생성
# 리소스 생성
kubectl apply -f sample-annotations.yaml
# 결과: pod/sample-annotations created

명령어로 어노테이션 추가 및 수정

kubectl annotate 명령어를 사용하여 리소스 생성 후에 어노테이션을 추가하거나 수정할 수 있다.

# 리소스 생성 후 어노테이션 부여
kubectl annotate pods sample-annotations annotations3=val3
# 결과: pod/sample-annotations annotated

# 어노테이션 덮어쓰기 (--overwrite 옵션 사용)
kubectl annotate pods sample-annotations annotations3=val3-new --overwrite
# 결과: pod/sample-annotations annotated

어노테이션 확인 및 삭제

kubectl describe 명령어로 부여된 어노테이션을 확인하고, 키 이름 뒤에 - 를 붙여 삭제한다.

# 어노테이션 확인
kubectl describe pod sample-annotations

출력결과:

Name:             sample-annotations
Namespace:        default
Priority:         0
Service Account:  default
Node:             worker1/192.168.56.101
Start Time:       Tue, 01 Jul 2025 05:43:57 +0000
Labels:           <none>
Annotations:      annotation1: val1
                  annotation2: 200
                  annotations3: val3-new
...

어노테이션 삭제 :

# 어노테이션 삭제
kubectl annotate pods sample-annotations annotations3-

5) 레이블 실습

YAML 파일로 레이블 생성

sample-label.yaml 파일을 작성하여 레이블을 포함한 파드를 생성한다.

  • sample-label.yaml 파일을 작성
# sample-label.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-label
  labels:
    label1: val1
    label2: val2
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
  • 레이블을 포함한 파드 생성
# 리소스 생성
kubectl apply -f sample-label.yaml
# 결과: pod/sample-label created

명령어로 레이블 추가 및 수정

kubectl label 명령어를 사용하여 레이블을 추가하거나 수정한다.

# 리소스 생성 후 레이블 부여
kubectl label pods sample-label label3=val3
# 결과: pod/sample-label labeled

# 레이블 덮어쓰기 (--overwrite 옵션 사용)
kubectl label pods sample-label label3=val3-new --overwrite
# 결과: pod/sample-label labeled

레이블 확인 및 삭제

kubectl describe 로 레이블을 확인하고, 키 이름 뒤에 - 를 붙여 삭제한다.

# 레이블 확인
kubectl describe pod sample-label

출력결과:

Name:             sample-label
Namespace:        default
Priority:         0
Service Account:  default
Node:             worker2/192.168.56.102
Start Time:       Tue, 01 Jul 2025 05:55:29 +0000
Labels:           label1=val1
                  label2=val2
                  label3=val3-new

레이블 삭제

kubectl label pods sample-label label3-
# 결과: pod/sample-label labeled

레이블을 이용한 리소스 필터링

-l 또는 --selector 옵션을 사용하여 특정 레이블을 가진 리소스를 조회할 수 있다.

# label1=val1 과 label2 레이블을 가진 파드 표시
kubectl get pods -l label1=val1,label2

# 모든 파드 목록과 함께 레이블 정보 표시
kubectl get pods --show-labels

6) 권장 레이블 키 이름

쿠버네티스 생태계의 여러 도구와 호환성을 높이기 위해 다음과 같은 표준 레이블 키를 사용하는 것이 권장된다.

  • app.kubernetes.io/name: 애플리케이션 이름

  • app.kubernetes.io/version: 애플리케이션 버전

  • app.kubernetes.io/component: 애플리케이션 내 구성 요소

  • app.kubernetes.io/part-of: 애플리케이션이 속한 전체 시스템 이름

  • app.kubernetes.io/instance: 인스턴스를 식별하는 고유 이름

  • app.kubernetes.io/managed-by: 애플리케이션을 관리하는 도구

어노테이션과 레이블은 쿠버네티스 리소스를 체계적으로 관리하기 위한 필수적인 메타데이터이다. 어노테이션은 도구가 참고하는 '주석'의 역할을 하고, 레이블은 리소스를 그룹화하고 선택하는 '꼬리표' 역할을 한다. 이 둘의 차이점을 명확히 이해하고 용도에 맞게 사용하면 복잡한 쿠버네티스 환경에서도 리소스를 효과적으로 제어하고 자동화할 수 있다.


4. 매니페스트 파일 설계 전략

1) 하나의 매니페스트 파일에 여러 리소스를 정의

하나의 YAML 파일 안에 --- 구분자를 사용하여 여러 리소스 정의를 포함할 수 있다.

  • 장점:

    • 강한 결합도: Deployment와 Service처럼 강하게 연관된 리소스들을 하나의 파일로 묶어 관리가 단순해진다.

    • 정확한 실행 순서: 파일에 정의된 순서대로 리소스가 적용되어 예측 가능성을 높인다.

  • 단점 및 주의사항:

    • 에러 전파: 파일 앞부분 리소스에 오류가 있으면, 그 뒤에 정의된 리소스는 적용되지 않는다.
    • 재사용성 감소: 공통 ConfigMap 등은 별도 파일로 분리하는 것이 재사용에 유리하다.

Deployment와 Service를 한 파일에 정의

# sample-multi-resource-manifest.yaml 파일

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order1-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.16
---
apiVersion: v1
kind: Service
metadata:
  name: order2-service
spec:
  type: LoadBalancer
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 8080
      targetPort: 80
  selector:
    app: sample-app
  • 매니페스트 적용
# 위 파일 하나만 적용하면 Deployment와 Service가 모두 생성됨
kubectl apply -f sample-multi-resource-manifest.yaml

# 출력:
# deployment.apps/order1-deployment created
# service/order2-service created

2) 여러 매니페스트 파일을 동시에 적용

  • 디렉터리 지정: kubectl apply -f <디렉터리 경로> 명령으로 디렉터리 내 모든 매니페스트 파일을 적용한다.

  • 적용 순서: 파일명 오름차순으로 적용된다. 순서 제어가 필요하면 01-configmap.yaml , 02-deployment.yaml 처럼 파일명 앞에 번호를 붙인다.

  • 재귀적 적용 (-R): -R 옵션으로 하위 디렉터리까지 모두 적용할 수 있다.

권장 설계 방침

  • 소규모 시스템: 시스템 전체를 구성하는 모든 마이크로서비스의 매니페스트를 하나의 디렉터리에 통합하여 관리할 수 있다.

  • 대규모 시스템: 시스템이 거대해지면 서브 시스템이나 팀별로 디렉터리를 나누어 관리하는 것이 효율적이다.

  • 마이크로서비스별 관리: 가독성을 높이기 위해 마이크로서비스마다 디렉터리를 만들고 그 안에 리소스 종류별로 파일을 생성할 수도 있다. 다만, 이 경우 적용 순서 제어가 어려워지는 단점이 있다.


0개의 댓글