레이블과 셀렉터
레이블과 셀렉터 (Labels and Selectors)
레이블(labels)은 파드 같은 객체에 붙이는 키/값 쌍이에요. 레이블은 사용자에게 의미 있고 관련 있는 객체의 식별 속성을 지정하는 데 쓰이며, 코어 시스템에 직접적인 의미를 부여하지는 않아요. 레이블은 객체를 정리하고 부분 집합을 선택하는 데 사용할 수 있어요.
레이블은 객체 생성 시점에 붙일 수 있고, 이후 언제든 추가하거나 수정할 수 있어요. 각 객체는 정의된 키/값 레이블 집합을 가질 수 있어요. 각 키는 주어진 객체에 대해 고유해야 해요.
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
레이블은 효율적인 쿼리(query)와 감시(watch)를 가능하게 해 주며, UIs와 CLIs에서 사용하기에 이상적이에요. 식별하지 않는 정보는 어노테이션(annotations)으로 기록해야 해요.
출처: 문서
본문
동기 (Motivation)
레이블을 사용하면 클라이언트가 이러한 매핑을 저장할 필요 없이, 사용자가 자신의 조직 구조를 느슨하게 결합된 방식으로 시스템 객체에 매핑할 수 있어요.
서비스 배포와 배치(batch) 처리 파이프라인은 종종 다차원 엔티티예요 (예: 여러 파티션이나 배포, 여러 릴리스 트랙, 여러 티어, 티어당 여러 마이크로서비스). 관리에는 종종 횡단(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"
이들은 흔히 사용되는 레이블의 예시이며, 자유롭게 자신만의 규칙을 개발할 수 있어요. 레이블 키는 주어진 객체에 대해 고유해야 한다는 점을 기억하세요.
구문과 문자 집합 (Syntax and character set)
레이블은 키/값 쌍이에요. 유효한 레이블 키는 두 부분으로 구성돼요: 선택적 접두사(prefix)와 이름(name)으로, 슬래시(/)로 구분돼요. 이름 부분은 필수이며 63자 이하여야 하고, 영숫자([a-z0-9A-Z])로 시작하고 끝나야 하며, 그 사이에 대시(-), 밑줄(_), 점(.), 영숫자가 올 수 있어요. 접두사는 선택적이에요. 지정한다면 접두사는 DNS 서브도메인이어야 해요: 점(.)으로 구분된 일련의 DNS 레이블로, 총 253자를 초과할 수 없고 슬래시(/)가 뒤따라야 해요.
접두사가 생략되면 레이블 키는 사용자에게 사적인 것으로 간주돼요. 최종 사용자 객체에 레이블을 추가하는 자동화된 시스템 컴포넌트(예: kube-scheduler, kube-controller-manager, kube-apiserver, kubectl, 또는 다른 서드파티 자동화)는 접두사를 지정해야 해요.
kubernetes.io/와 k8s.io/ 접두사는 쿠버네티스 코어 컴포넌트를 위해 예약되어 있어요.
유효한 레이블 값:
- 63자 이하여야 함(비어 있을 수 있음),
- 비어 있지 않은 한 영숫자(
[a-z0-9A-Z])로 시작하고 끝나야 함, - 그 사이에 대시(
-), 밑줄(_), 점(.), 영숫자를 포함할 수 있음.
예를 들어, environment: production과 app: nginx라는 두 레이블을 가진 파드의 매니페스트는 다음과 같아요.
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)
이름(name)과 UID와 달리, 레이블은 고유성을 제공하지 않아요. 일반적으로 많은 객체가 같은 레이블을 가질 것으로 기대해요.
레이블 셀렉터(label selector)를 통해 클라이언트/사용자는 객체 집합을 식별할 수 있어요. 레이블 셀렉터는 쿠버네티스의 핵심 그룹화 원시 요소(primitive)예요.
API는 현재 두 가지 유형의 셀렉터를 지원해요: 등식 기반(equality-based)과 집합 기반(set-based). 레이블 셀렉터는 쉼표로 구분된 여러 요구 사항으로 만들 수 있어요. 여러 요구 사항의 경우 모두 충족되어야 하므로 쉼표 구분자는 논리적 AND(&&) 연산자 역할을 해요.
빈 셀렉터나 지정되지 않은 셀렉터의 의미는 컨텍스트에 따라 달라지며, 셀렉터를 사용하는 API 유형은 그 유효성과 의미를 문서화해야 해요.
등식 기반 요구 사항 (Equality-based requirement)
등식 또는 부등식 기반 요구 사항은 레이블 키와 값으로 필터링할 수 있게 해줘요. 일치하는 객체는 지정된 모든 레이블 제약을 충족해야 하지만, 추가 레이블을 가질 수도 있어요. 세 가지 연산자가 허용돼요: =, ==, !=. 처음 두 개는 등식(동의어)을 나타내고, 마지막 것은 부등식을 나타내요. 예를 들어:
environment = production
tier != frontend
전자는 environment와 같은 키와 production과 같은 값을 가진 모든 리소스를 선택해요. 후자는 tier와 같은 키와 frontend와 다른 값을 가진 모든 리소스, 그리고 tier 키를 가진 레이블이 없는 모든 리소스를 선택해요. 쉼표 연산자를 사용해 production에서 frontend를 제외한 리소스를 필터링할 수 있어요: environment=production,tier!=frontend
등식 기반 레이블 요구 사항의 사용 시나리오 중 하나는 파드가 노드 선택 기준을 지정하는 것이에요. 예를 들어, 아래 예시 파드는 accelerator 레이블이 존재하고 nvidia-tesla-p100으로 설정된 노드를 선택해요.
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "registry.k8s.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
집합 기반 요구 사항 (Set-based requirement)
집합 기반 레이블 요구 사항은 값 집합에 따라 키를 필터링할 수 있게 해줘요. 세 가지 종류의 연산자가 지원돼요: in, notin, 그리고 exists(키 식별자만). 예를 들어:
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- 첫 번째 예시는
environment와 같은 키와production또는qa와 같은 값을 가진 모든 리소스를 선택해요. - 두 번째 예시는
tier와 같은 키와frontend와backend외의 값을 가진 모든 리소스, 그리고tier키를 가진 레이블이 없는 모든 리소스를 선택해요. - 세 번째 예시는
partition키를 가진 레이블을 포함한 모든 리소스를 선택해요; 값은 검사되지 않아요. - 네 번째 예시는
partition키를 가진 레이블이 없는 모든 리소스를 선택해요; 값은 검사되지 않아요.
마찬가지로 쉼표 구분자는 AND 연산자로 작동해요. 따라서 partition 키(값과 무관)를 가진 그리고 qa와 다른 environment 값을 가진 리소스를 필터링하는 것은 partition,environment notin (qa)로 달성할 수 있어요. 집합 기반 레이블 셀렉터는 environment=production가 environment in (production)와 동등하므로 등식의 일반적인 형태예요; !=와 notin도 마찬가지예요.
집합 기반 요구 사항은 등식 기반 요구 사항과 혼합할 수 있어요. 예를 들어: partition in (customerA, customerB),environment!=qa.
API
LIST와 WATCH 필터링
list와 watch 연산의 경우 레이블 셀렉터를 지정해 반환되는 객체 집합을 필터링할 수 있어요; 쿼리 파라미터를 사용해 필터를 지정해요. (쿠버네티스의 watch에 대해 자세히 배우려면 변경의 효율적인 감지(efficient detection of changes)를 읽어보세요.) 두 요구 사항 모두 허용돼요 (URL 쿼리 문자열에 나타나는 대로 제시돼요):
- 등식 기반 요구 사항:
?labelSelector=environment%3Dproduction,tier%3Dfrontend - 집합 기반 요구 사항:
?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29
두 레이블 셀렉터 스타일 모두 REST 클라이언트를 통해 리소스를 list하거나 watch하는 데 사용할 수 있어요. 예를 들어, kubectl로 apiserver를 대상으로 하고 등식 기반을 사용한다면 다음과 같이 쓸 수 있어요:
kubectl get pods -l environment=production,tier=frontend
또는 집합 기반 요구 사항을 사용해:
kubectl get pods -l 'environment in (production),tier in (frontend)'
이미 언급했듯이 집합 기반 요구 사항은 더 표현력이 풍부해요. 예를 들어 값에 OR 연산자를 구현할 수 있어요:
kubectl get pods -l 'environment in (production, qa)'
또는 notin 연산자를 통해 부정 일치를 제한해:
kubectl get pods -l 'environment,environment notin (frontend)'
API 객체의 집합 참조 (Set references in API objects)
서비스(services)와 레플리케이션 컨트롤러(replicationcontrollers) 같은 일부 쿠버네티스 객체도 레이블 셀렉터를 사용해 파드 같은 다른 리소스 집합을 지정해요.
Service와 ReplicationController
service가 대상으로 하는 파드 집합은 레이블 셀렉터로 정의돼요. 마찬가지로 replicationcontroller가 관리해야 하는 파드 집단도 레이블 셀렉터로 정의돼요.
두 객체 모두에 대한 레이블 셀렉터는 maps를 사용해 json이나 yaml 파일에 정의되며, 등식 기반 요구 사항 셀렉터만 지원돼요:
"selector": {
"component" : "redis",
}
또는
selector:
component: redis
이 셀렉터는(각각 json 또는 yaml 형식으로) component=redis 또는 component in (redis)와 동등해요.
집합 기반 요구 사항을 지원하는 리소스
Job, Deployment, ReplicaSet, DaemonSet 같은 새로운 리소스는 집합 기반 요구 사항도 지원해요.
selector:
matchLabels:
component: redis
matchExpressions:
- { key: tier, operator: In, values: [cache] }
- { key: environment, operator: NotIn, values: [dev] }
matchLabels는 {key,value} 쌍의 맵이에요. matchLabels 맵의 단일 {key,value}는 matchExpressions의 한 요소와 동등하며, 그 key 필드는 "key", 연산자는 "In", values 배열은 "value"만 포함해요. matchExpressions는 파드 셀렉터 요구 사항의 목록이에요. 유효한 연산자는 In, NotIn, Exists, DoesNotExist예요. In과 NotIn의 경우 values 집합은 비어 있지 않아야 해요. matchLabels와 matchExpressions 모두의 모든 요구 사항은 AND로 결합돼요 — 일치하려면 모두 충족되어야 해요.
노드 집합 선택하기
레이블에 대한 선택의 한 사용 사례는 파드가 스케줄링될 수 있는 노드 집합을 제한하는 것이에요. 자세한 내용은 노드 선택 문서를 참조하세요.
레이블을 효과적으로 사용하기
단일 레이블을 어떤 리소스에든 적용할 수 있지만, 이것이 항상 모범 사례는 아니에요. 리소스 집합을 서로 구분하기 위해 여러 레이블을 사용해야 하는 많은 시나리오가 있어요.
예를 들어, 다른 애플리케이션은 app 레이블에 다른 값을 사용하지만, guestbook 예시 같은 다중 티어 애플리케이션은 각 티어를 추가로 구분할 필요가 있어요.
다음 예시에서 app 레이블은 수동 쿼리와 간단한 CLI 사용의 편의를 위해 포함됐어요. app.kubernetes.io/name 레이블은 권장되는 쿠버네티스 레이블 규칙을 따르며 도구와 자동화에 더 적합해요.
프론트엔드는 다음 레이블을 가질 수 있어요:
labels:
app: guestbook
app.kubernetes.io/name: guestbook
tier: frontend
Redis 마스터와 레플리카는 다른 tier 레이블을 가지며, 어쩌면 추가 role 레이블도 가질 수 있어요:
labels:
app: guestbook
app.kubernetes.io/name: guestbook
tier: backend
role: master
그리고
labels:
app: guestbook
app.kubernetes.io/name: guestbook
tier: backend
role: replica
레이블은 레이블이 지정한 어떤 차원을 따라서도 리소스를 슬라이스하고 다이싱할 수 있게 해줘요:
kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-replica-2q2yf 1/1 Running 0 1m guestbook backend replica
guestbook-redis-replica-qgazl 1/1 Running 0 1m guestbook backend replica
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
my-nginx-o0ef1 1/1 Running 0 29m nginx <none> <none>
kubectl get pods -lapp=guestbook,role=replica
NAME READY STATUS RESTARTS AGE
guestbook-redis-replica-2q2yf 1/1 Running 0 3m
guestbook-redis-replica-qgazl 1/1 Running 0 3m
레이블 업데이트하기
때로는 새 리소스를 만들기 전에 기존 파드와 다른 리소스의 레이블을 다시 지정하고 싶을 수 있어요. 이는 kubectl label로 할 수 있어요. 예를 들어 모든 NGINX 파드를 frontend 티어로 레이블 지정하려면 다음을 실행해요:
kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled
이것은 먼저 "app=nginx" 레이블이 있는 모든 파드를 필터링한 다음, "tier=fe"로 레이블을 붙여요. 레이블을 붙인 파드를 보려면 다음을 실행해요:
kubectl get pods -l app=nginx -L tier
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe
이것은 "app=nginx" 파드를 모두 출력하고, 파드의 티어(-L 또는 --label-columns로 지정됨)의 추가 레이블 열을 포함해요.
자세한 내용은 kubectl label을 참조하세요.
더 알아보기 (Learn more)
- 노드에 레이블을 추가하는 방법 배우기
- 잘 알려진 레이블, 어노테이션, 테인트 찾기
- 권장 레이블(Recommended labels) 보기
- 네임스페이스 레이블로 파드 보안 표준(Pod Security Standards) 적용하기
- 파드 레이블용 컨트롤러 작성에 관한 블로그 읽기