Pod를 새롭게 생성하면 Master Node(Control plane)의 Scheduler가 pod를 실행시킬 node를 선택하고 배치한다.
그럼 이 Scheduler는 어떤 기준으로 pod를 실행시킬 node를 결정하는 것일까?
cluster내의 node들은 모두 같은 사양을 가질수도 있지만, 각기 다른 스펙의 사양을 가질 수도 있다. 워크로드 또한 리소스 자원을 많이 요구하는 것이 있고, 비교적 적은 양을 요구하는 것이 있다.
각 node들의 리소스를 효율적으로 사용하기 위해서는 다양한 제약 조건과 요구사항 등을 고려하여 pod를 배치해야한다.
특정 워크로드가 적합한 노드에서 실행되도록 할 수 있다.
이번 글에서는 Label과 Selector, 추가로 Annotation에 대해 알아보도록 한다.
Label
쿠버네티스 object들에 붙이는 key-vaule 쌍의 메타데이터 값이다. AWS에서의 tag와 같이 Label은 object들을 식별하고 분류/그룹화하기 위해 사용된다.
Label은 object에 하나 이상 붙일 수 있으며, 동일한 namespace에서 여러 object에 대해 같은 label을 붙일 수 있다.
또한 object에 붙은 label key값은 고유해야 한다.
이러한 Label은 앞서 워크로드 리소스(Deployment, ReplicaSet)를 생성했을 당시에 이미 작성을 했었다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
replicas: 3
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example # 생성되는 pod들에 대해 app=example 라벨을 지정
spec:
containers:
- name: nginx
image: nginx:latest
Deployment로써 3개의 replica pod를 유지하는 ReplicaSet에서 각 pod들에 app=example이라는 라벨을 부여한 것을 알 수 있다.
label 관련 kubectl 커맨드는 아래와 같다.
# pod 검색 시 label까지 표기
kubectl get pods --show-labels
# pod에 label 추가
kubectl label pods [pod명] key=value
# namespace 안의 모든 pod에 label 추가
kubectl label pods --all key=value
# pod에 달린 label 수정
kubectl label pods [pod명] key=value1 --overwrite
# pod의 특정 label 삭제
kubectl label pods [pod명] key-
Selector
Label을 사용하여 특정 object를 선택하는 메커니즘이다. Selector를 통해 특정 Label이 적용된 object들을 필터링할 수 있고, 그 object들을 대상으로 작업을 수행할 수 있다.
예를 들어, 앞서 설명한 Deployment configuration에서 3개의 replica pod에 app=example이라는 label을 지정하고, 이들을 하나의 ReplicaSet으로 묶는 selector 구문이 있는 것을 볼 수 있다.
...
spec:
replicas: 3
selector:
matchLabels: # app=example이라는 Label로 필터링
app: example
template:
metadata:
labels:
app: example
spec:
...
이러한 Selector는 크게 Equality-based와 Set-based, 2가지 방식이 존재한다.
- Equality-based : =, ==, != 연산자 만을 통해 특정 Key-Value 쌍과 일치하는 object를 선택하는 방법
- Set-based : in, notin, exists 연산자를 통해 특정 Key가 주어진 값 집합 중 하나와 일치하는 object를 선택하는 방법
설명을 위해 다음과 같이 pod들이 존재한 상황을 가정해본다.
아래 Equality-based는 label이 env=prod이고 tier=frontend인 object를 가져온다.
kubectl get pods -l 'env=prod, tier=frontend'
그리고 아래 Set-based는 env라벨의 값이 dev이거나 stg인 object를 가져온다.
kubectl get pods -l 'env in (dev, stg)'
exists 연산자의 경우, label의 key 값만 확인하여 해당 key 이름의 label을 가진 모든 object를 가져온다.
kubectl get pods -l 'bu'
selector를 configuration file에서 선언하는 경우는 다음과 같이 작성한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
matchExpressions:
- key: env
operator: in
values:
- production
- staging # env가 production 또는 staging인 Pod만 선택
- key: version
operator: notin
values:
- v3 # version이 v3가 아닌 Pod만 선택
matchLabels로 해당 key-value와 일치하는 label이 달린 object를 선택할 수 있고 (Equality-based), matchExpressions로 key와 value가 operator 연산에 해당하는 label이 달린 object를 선택할 수 있다. (Set-based)
Annotation
Label과 마찬가지로 key-value 쌍의 값을 가지나, 식별 정보를 갖지 않아 Selector를 사용할 수 없는 field이다.
(annotations are not used to identify and select objects)
Label과는 다르게 긴 값을 입력할 수 있어 주로 object 리소스의 detail이나 설명 등을 기록하기 위한 용도로 이용한다.
또한 kubernetes에 특정 정보를 전달하기 위한 목적으로도 사용한다.
annotation 관련 kubectl 커맨드는 아래와 같다.
# pod에 Annotation 추가
kubectl annotate pods [pod명] descripion='test nginx'
# namespace의 모든 pod에 annotation 추가
kubectl annotate pods --all memo='namespace for testing'
# pod의 Annotation 내용 변경
kubectl annotate pods [pod명] description='test apache' --overwrite
# pod의 Annotation 삭제
kubectl annotate pods description-