고급 kubectl get 기술: 레이블과 JSONPath로 출력 필터링하기

레이블 선택자, JSONPath 및 사용자 정의 열을 사용하여 kubectl get 출력을 필터링하고 Kubernetes 문제 해결을 더욱 효율적으로 수행합니다.

고급 kubectl get 기술: 레이블과 JSONPath로 출력 필터링하기

kubectl get은 필요한 정확한 리소스와 필드로 출력을 좁힐 수 있을 때 훨씬 더 유용해집니다. 바쁜 네임스페이스에서 포드의 벽과 이름, 노드, 이미지에 초점을 맞춘 목록의 차이는 장애 상황에서 몇 분을 절약할 수 있습니다.

이 가이드는 레이블 선택자와 JSONPath 출력을 결합하는 방법을 보여줍니다. 또한 custom-columns 또는 jq가 모든 것을 하나의 JSONPath 표현식에 강제로 넣는 것보다 더 적합한 경우를 살펴봅니다.

Kubernetes 레이블 이해: 리소스 선택의 기초

고급 필터링에 들어가기 전에 Kubernetes 레이블을 이해하는 것이 중요합니다. 레이블은 Kubernetes 객체(예: 포드, 서비스, 디플로이먼트 등)에 첨부된 키-값 쌍으로, 리소스를 식별하고 구성하는 데 사용됩니다. 클라이언트와 사용자가 객체의 하위 집합을 선택하는 데 사용할 수 있는 메타데이터입니다.

레이블은 주석(annotation)과 구별됩니다. 레이블은 사용자가 객체를 쿼리하고 선택하는 데 의미 있고 관련 있는 식별 특성을 위한 반면, 주석은 식별하지 않는 메타데이터를 위한 것입니다. 좋은 레이블 관행은 효과적인 리소스 관리와 고급 kubectl get 작업에 필수적입니다.

리소스에 현재 할당된 레이블을 보려면 --show-labels 플래그를 사용할 수 있습니다:

kubectl get pods --show-labels

이렇게 하면 출력에 LABELS 열이 추가되어 각 포드와 연결된 모든 레이블이 표시됩니다.

kubectl get -l을 사용한 고급 레이블 선택자

-l 또는 --selector 플래그는 레이블을 기반으로 kubectl get 출력을 필터링하는 주요 도구입니다. 리소스가 출력에 포함되기 위해 충족해야 하는 레이블 요구 사항 집합을 지정할 수 있습니다. 선택자는 간단한 키-값 쌍 또는 더 복잡한 집합 기반 표현식일 수 있습니다.

기본 레이블 선택

정확히 일치

특정 레이블이 정확한 값을 가진 리소스를 선택하려면 key=value 구문을 사용합니다.

# 'app' 레이블이 'nginx'로 설정된 모든 포드 가져오기
kubectl get pods -l app=nginx

# 'default' 네임스페이스에서 'tier' 레이블이 'frontend'로 설정된 모든 서비스 가져오기
kubectl get services -n default -l tier=frontend

불일치

특정 레이블이 특정 값으로 설정되지 않은 리소스를 선택하려면 key!=value 구문을 사용합니다.

# 'app' 레이블이 'nginx'가 아닌 모든 포드 가져오기
kubectl get pods -l app!=nginx

존재 (키만)

값에 관계없이 특정 레이블이 있는 리소스를 선택하려면 key만 지정합니다.

# 값에 관계없이 'environment' 레이블이 있는 모든 포드 가져오기
kubectl get pods -l environment

부재 (키만)

특정 레이블이 없는 리소스를 선택하려면 key 앞에 !를 붙입니다.

# 'component' 레이블이 없는 모든 포드 가져오기
kubectl get pods -l !component

여러 레이블 선택자 결합 (AND 논리)

여러 레이블 선택자를 쉼표로 구분하여 결합할 수 있습니다. 이는 AND 관계를 의미하며, 리소스가 포함되려면 모든 지정된 레이블 조건을 충족해야 합니다.

# 'app=nginx' AND 'env=production'인 포드 가져오기
kubectl get pods -l app=nginx,env=production

# 'tier=backend'이고 'version' 레이블이 없는 디플로이먼트 가져오기
kubectl get deployments -l tier=backend,!version

집합 기반 레이블 선택자

Kubernetes는 또한 더 강력한 집합 기반 레이블 선택자를 지원하며, 이는 단일 레이블에 대해 여러 가능한 값을 다룰 때 특히 유용합니다.

key in (value1, value2, ...)

레이블 값이 지정된 값 목록 중 하나인 리소스를 선택합니다.

# 'app' 레이블이 'nginx' 또는 'redis'인 포드 가져오기
kubectl get pods -l 'app in (nginx,redis)'

# 'kube-system' 네임스페이스에서 'k8s-app' 레이블이 'kube-dns' 또는 'kubernetes-dashboard'인 서비스 가져오기
kubectl get services -n kube-system -l 'k8s-app in (kube-dns,kubernetes-dashboard)'

key notin (value1, value2, ...)

레이블 값이 지정된 값 목록 중 어느 것도 아닌 리소스를 선택합니다.

# 'env' 레이블이 'dev'도 'test'도 아닌 포드 가져오기
kubectl get pods -l 'env notin (dev,test)'

: 집합 기반 선택자나 특수 문자가 포함된 선택자를 사용할 때는 셸 해석 문제를 방지하기 위해 전체 선택자 표현식을 작은따옴표('...')로 묶으십시오.

레이블 지정 모범 사례

  • 일관성: 명확한 레이블 지정 체계를 수립하고 클러스터 전체에서 이를 고수하십시오. 이렇게 하면 필터링이 예측 가능하고 신뢰할 수 있습니다.
  • 의미 있는 이름: 리소스의 특성을 명확하게 설명하는 레이블을 사용하십시오(예: app, tier, environment, version).
  • 세분성: 레이블은 정확한 선택을 허용할 만큼 구체적이어야 하지만 관리하기 어려울 정도로 세분화되어서는 안 됩니다.
  • 불변성: 자주 변경되는 데이터에 레이블을 사용하지 마십시오. 레이블은 정적 식별 속성에 가장 적합합니다.
  • 공통 레이블: 도구와의 더 나은 상호 운용성을 위해 app.kubernetes.io/name, app.kubernetes.io/instance, app.kubernetes.io/version 등과 같이 널리 채택된 레이블을 사용하십시오.

JSONPath로 사용자 정의 데이터 추출

레이블 선택자는 어떤 리소스를 원하는지 식별하는 데 도움이 되는 반면, JSONPath는 해당 리소스에서 어떤 정보를 추출하고 형식을 지정할 방법을 정의하는 데 도움이 됩니다. kubectl get을 사용하면 리소스 세부 정보를 yaml, json, wide 등 다양한 형식으로 출력할 수 있습니다. -o jsonpath는 간결한 사용자 정의 출력이 필요할 때 유용합니다.

kubectl은 Kubernetes 객체의 JSON 구조를 탐색하기 위한 자체 JSONPath 구현을 가지고 있습니다. 유용한 템플릿 텍스트와 range 루프를 지원하지만 Go 템플릿이나 jq와 동일하지는 않습니다.

JSONPath를 사용하려면 -o jsonpath='<template>'로 출력 형식을 지정합니다.

JSONPath 기본 및 일반적인 사용 사례

먼저, JSONPath 표현식을 작성하기 전에 리소스의 전체 JSON 출력을 보고 구조를 이해하는 것이 도움이 되는 경우가 많습니다:

# 포드의 전체 JSON 구조 가져오기
kubectl get pod <pod-name> -o json

이렇게 하면 JSONPath 쿼리를 작성하기 위한 명확한 맵을 얻을 수 있습니다.

단일 필드 액세스

{.field.subfield}를 사용하여 특정 값에 액세스합니다. 예를 들어, 포드의 이름을 가져오려면:

# 특정 포드의 이름 가져오기
kubectl get pod my-nginx-pod-12345 -o jsonpath='{.metadata.name}'

# 포드가 실행 중인 노드 이름 가져오기
kubectl get pod my-nginx-pod-12345 -o jsonpath='{.spec.nodeName}'

배열 요소 액세스

배열 내의 요소에 액세스하려면 [*]를 사용하여 모든 요소를 반복하거나 [index]를 사용하여 특정 요소에 액세스할 수 있습니다.

# 특정 포드의 모든 컨테이너 이름 가져오기
kubectl get pod my-nginx-pod-12345 -o jsonpath='{.spec.containers[*].name}'

# 특정 포드의 첫 번째 컨테이너 이미지 가져오기
kubectl get pod my-nginx-pod-12345 -o jsonpath='{.spec.containers[0].image}'

리소스 목록 반복 (range 사용)

kubectl get이 여러 리소스(예: 모든 포드)를 반환할 때 출력은 일반적으로 items 배열을 포함하는 객체입니다. 이를 반복하려면 Go 템플릿 range 함수가 필요합니다.

# 모든 포드 이름과 IP를 각각 새 줄에 나열
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'

# 모든 디플로이먼트 이름과 준비된 레플리카 수 나열
kubectl get deployments -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.readyReplicas}{"\n"}{end}'
  • {range .items[*]}: .items 배열의 각 항목에 대한 반복을 시작합니다.
  • {.metadata.name}: 루프 내에서 .는 현재 항목(예: 단일 포드 객체)을 나타냅니다.
  • {"\t"}: 서식 지정을 위해 탭 문자를 삽입합니다.
  • {"\n"}: 새 줄 문자를 삽입합니다.
  • {end}: range 루프를 닫습니다.

조건부 출력: 대신 Go 템플릿 사용

kubectl -o jsonpath는 Go 템플릿 if, with 또는 else 블록을 지원하지 않습니다. 조건부 렌더링이 필요한 경우 -o go-template로 전환하십시오:

# 포드 이름을 나열하고 podIP가 비어 있으면 N/A 출력
kubectl get pods -o go-template='{{range .items}}{{.metadata.name}}{{"\t"}}{{if .status.podIP}}{{.status.podIP}}{{else}}N/A{{end}}{{"\n"}}{{end}}'

조건부가 아닌 출력의 경우 JSONPath가 더 짧습니다:

kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'

사용자 정의 서식 및 헤더

고정 텍스트를 추가하고 테이블 형식 출력에 대한 헤더를 만들 수 있습니다.

# 포드 이름, 이미지 및 노드에 대한 사용자 정의 출력(헤더 포함)
kubectl get pods -o=jsonpath='{"NAME\tIMAGE\tNODE\n"}{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\t"}{.spec.nodeName}{"\n"}{end}'

경고: kubectl은 자체 JSONPath 구현을 가지고 있습니다. 필드 추출 및 range 루프에 유용하지만 jq와 동일하지 않으며 다른 도구에서 알고 있는 모든 JSONPath 기능을 지원하지는 않습니다.

JSONPath 팁

  • 간단하게 시작: 기본 경로로 시작한 다음 복잡성을 추가하십시오.
  • JSON 검사: 항상 kubectl get <resource> <name> -o json을 사용하여 쿼리하는 정확한 구조를 이해하십시오.
  • 이스케이프 문자: JSONPath 템플릿 문자열 내에서 새 줄(\n) 및 탭(\t)과 같은 특수 문자를 출력에서 리터럴로 렌더링하려면 이스케이프해야 합니다.
  • 템플릿 저장: 복잡하거나 자주 사용하는 JSONPath 표현식의 경우 파일에 저장하고 -o jsonpath-file=/path/to/template.jsonpath를 사용하십시오.

레이블과 JSONPath 결합

진정한 힘은 이 두 기술을 결합하는 데서 나옵니다. 먼저 레이블 선택자를 사용하여 리소스 범위를 좁힌 다음 JSONPath를 적용하여 필터링된 집합에서 특정 데이터를 추출하고 형식을 지정합니다.

# 'app=my-app' 및 'env=production'인 모든 포드의 이름과 컨테이너 이미지 가져오기
kubectl get pods -l 'app=my-app,env=production' -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'

# 'tier' 레이블이 'backend'로 설정된 모든 서비스의 이름과 노드 IP 가져오기
kubectl get services -l tier=backend -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.clusterIP}{"\n"}{end}'

# 특정 노드 'worker-node-1'에서 실행 중인 모든 포드를 찾고 이름과 상태 나열
kubectl get pods --field-selector spec.nodeName=worker-node-1 -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'

참고: 레이블 선택자(-l)는 임의의 키-값 쌍을 위한 것이지만, kubectl은 리소스 필드(예: status.phase=Running, metadata.namespace=default)를 기반으로 필터링하기 위한 --field-selector도 제공합니다. 이는 레이블 및 JSONPath와 결합할 수 있는 또 다른 강력한 필터링 계층을 제공합니다.

문제 해결 및 일반적인 함정

  • JSONPath 구문 오류: 작은 오타라도 템플릿을 손상시킬 수 있습니다. 중괄호, 점 및 배열 액세스를 다시 확인하십시오.
  • 누락된 필드: 특정 리소스에 필드가 없으면 JSONPath는 <no value> 또는 빈 문자열을 출력할 수 있습니다. Go 템플릿 if 또는 with 구문을 사용하여 이를 적절하게 처리하십시오.
  • 셸 이스케이프: JSONPath 표현식 주위의 작은따옴표는 중요합니다. 표현식에 내부 따옴표나 특수 문자가 포함된 경우 추가 셸 이스케이프가 필요할 수 있습니다.
  • Go 템플릿 대 순수 JSONPath: kubectl은 Go 템플릿을 사용하며 범용 JSONPath 엔진이 아닙니다. 고급 필터링(?())과 같은 기능은 일반적으로 jq 또는 다른 전용 JSON 프로세서의 일부이며 kubectl-o jsonpath에서 직접 지원되지 않습니다.
  • items 배열: 레이블 선택자가 일치하는 리소스가 없으면 items가 비어 있고 range 루프가 출력을 생성하지 않습니다.

핵심 요점

레이블 선택자와 JSONPath를 사용한 고급 kubectl get 기술을 마스터하는 것은 모든 Kubernetes 사용자에게 귀중한 기술입니다. 이러한 강력한 필터링 및 서식 지정 옵션은 kubectl get을 단순한 목록 도구에서 정교한 데이터 추출 유틸리티로 변환합니다. 문제가 있는 리소스를 신속하게 찾아내고, 사용자 정의 보고서를 생성하거나, 자동화 스크립트에 정확한 데이터를 제공할 수 있습니다.

레이블을 사용하여 리소스를 선택한 다음 필요한 필드를 제공하는 가장 간단한 출력 형식을 선택하십시오. JSONPath는 간결한 추출에 적합하고, custom-columns는 빠른 테이블에 더 쉬우며, jq 또는 Go 템플릿은 출력에 실제 논리가 필요할 때 더 좋습니다.