라벨과 셀렉터
라벨과 셀렉터 (Labels and Selectors)
라벨(Label) 은 Pod 같은 객체에 붙이는 키/값(key/value) 쌍이에요. 라벨은 사용자에게 의미 있고 관련 있는 객체의 식별 속성을 지정하는 용도로 쓰이며, 핵심 시스템에 직접적인 의미를 주지는 않아요. 라벨로 객체를 조직화하고 객체의 부분집합을 선택할 수 있어요. 라벨은 생성 시점에 붙일 수도 있고 나중에 언제든 추가·수정할 수 있어요. 각 객체는 키/값 라벨 집합을 가질 수 있고, 주어진 객체에 대해 각 키는 유일해야 해요.
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
라벨은 효율적인 쿼리와 watch를 가능하게 하고 UI/CLI에 이상적이에요. 식별 목적이 아닌 정보는 annotations으로 기록해야 해요.
동기 (Motivation)
라벨은 사용자가 자신의 조직 구조를 시스템 객체에 느슨하게 결합(loosely coupled)시켜 매핑할 수 있게 해요. 서비스 배포와 배치 처리 파이프라인은 종종 다차원 엔터티예요 (예: 여러 파티션/배포, 여러 릴리스 트랙, 여러 티어, 티어당 여러 마이크로서비스). 관리에는 종종 교차 절단(cross-cutting) 작업이 필요한데, 이는 엄격한 계층 표현(특히 인프라가 아니라 사용자가 결정한 경직된 계층)의 캡슐화를 깨요.
일반적으로 쓰이는 라벨 예:
"release" : "stable","release" : "canary""environment" : "dev","environment" : "qa","environment" : "production""tier" : "frontend","tier" : "backend","tier" : "cache""partition" : "customerA","partition" : "customerB""track" : "daily","track" : "weekly"
문법과 문자 집합
유효한 라벨 키는 두 부분(maybe prefix와 name)으로 나뉘며, 슬래시(/)로 구분해요. name 부분은 필수이고 63자 이하여야 하며, 영숫자([a-z0-9A-Z])로 시작·끝나야 하고 그 사이에 대시(-), 밑줄(_), 점(.), 영숫자를 포함할 수 있어요. prefix는 선택이며, 지정하면 DNS 하위 도메인이어야 해요 (총 253자 이하, 점으로 구분, 뒤에 /).
prefix를 생략하면 라벨 키는 사용자에게 비공개(private)인 것으로 간주돼요. 최종 사용자 객체에 라벨을 추가하는 자동화된 시스템 컴포넌트(kube-scheduler, kube-controller-manager, kubectl 등)는 prefix를 명시해야 해요. kubernetes.io/와 k8s.io/ prefix는 Kubernetes 핵심 컴포넌트용으로 예약돼 있어요.
유효한 라벨 값:
- 63자 이하여야 함 (비어 있을 수 있음),
- 비어 있지 않으면 영숫자로 시작·끝나야 함,
- 그 사이에 대시, 밑줄, 점, 영숫자를 포함할 수 있음.
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
라벨 셀렉터 (Label selectors)
이름과 UID와 달리 라벨은 유일성을 제공하지 않아요. 라벨 셀렉터를 통해 클라이언트/사용자가 객체의 집합을 식별할 수 있어요. 라벨 셀렉터는 Kubernetes의 핵심 그룹화 프리미티브예요.
API는 두 가지 셀렉터 유형을 지원해요: equality 기반과 set 기반. 라벨 셀렉터는 콤마로 구분된 여러 요구사항(requirement) 으로 만들 수 있어요. 여러 요구사항이 있으면 모두 충족해야 하므로, 콤마는 논리 AND (&&) 연산자로 동작해요.
주의: equality 기반과 set 기반 모두 논리 OR (
||) 연산자가 없어요. 필터 구문을 그에 맞게 구성하세요.
Equality 기반 요구사항
=, ==, != 연산자를 지원해요. 처음 둘은 동일함(동의어), 마지막은 다름(inequality)을 나타내요.
environment = production
tier != frontend
첫째는 environment 키가 production 값인 모든 리소스를 선택하고, 둘째는 tier 키가 frontend가 아닌 모든 리소스와 tier 키 라벨이 없는 모든 리소스를 선택해요.
Set 기반 요구사항
in, notin, exists(키 식별자만) 연산자를 지원해요.
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
environment in (production, qa):environment가production또는qa인 리소스tier notin (frontend, backend):tier가frontend/backend가 아닌 리소스와tier키가 없는 리소스partition:partition키 라벨을 가진 모든 리소스 (값 무관)!partition:partition키 라벨이 없는 모든 리소스
Set 기반과 equality 기반을 섞을 수도 있어요 (예: partition in (customerA, customerB),environment!=qa).
API
LIST와 WATCH 필터링
list와 watch 작업에서 쿼리 파라미터로 라벨 셀렉터를 지정할 수 있어요.
kubectl get pods -l environment=production,tier=frontend
kubectl get pods -l 'environment in (production),tier in (frontend)'
kubectl get pods -l 'environment in (production, qa)'
kubectl get pods -l 'environment,environment notin (frontend)'
API 객체의 셀렉터 참조
service와 replicationcontroller처럼 일부 객체는 자체 리소스 집합(Pod 등)을 지정하기 위해 라벨 셀렉터를 사용해요. 이들은 equality 기반만 지원하지만, Job, Deployment, ReplicaSet, DaemonSet 같은 최신 리소스는 set 기반 요구사항도 지원해요.
selector:
matchLabels:
component: redis
matchExpressions:
- { key: tier, operator: In, values: [cache] }
- { key: environment, operator: NotIn, values: [dev] }
matchLabels와 matchExpressions의 모든 요구사항은 AND로 결합돼요. 유효한 연산자는 In, NotIn, Exists, DoesNotExist예요.
라벨 업데이트
kubectl label로 기존 리소스에 라벨을 다시 붙일 수 있어요.
kubectl label pods -l app=nginx tier=fe
kubectl get pods -l app=nginx -L tier