
개인적으로 공부한 내용을 작성한 게시글입니다. 잘못된 내용이 있을 수 있습니다.
틀린 부분을 알려주시면 바로 고치겠습니다.감사합니다.
쿠버네티스 리소스의 Manifest 파일들을 작성하다보면 많은 labels, matchLabels, selectors 필드들을 볼 수 있다.
이번 포스팅을 통해 이들을 정리해보려고 한다.
Selector
Deployment
우선 Deployment의 Manifest 파일을 살펴보자
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
labels:
app: hello
spec:
selector:
matchLabels:
app: hello
track: stable
matchExpressions:
- {key: tier, operator: In, values: [backend, backend2, backend3]}
replicas: 3
template:
metadata:
labels:
app: hello
tier: backend
track: stable
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-go-gke:1.0"
ports:
- name: http
containerPort: 80
metadata
필드의labels
필드는 Deployment자체의 label 정보를 의미한다.selector
필드의matchLabels
와matchExpressions
필드는 배포할 Pod의 labels를 가리킨다.matchLabels
와matchExpressions
는 각각의 필드에 AND(&&) 연산자가 사용되고,matchLabels
와matchExpressions
끼리도 AND(&&) 연산자가 사용된다.template
필드부터는 사실 Pod의 metadata라고 생각하면 된다. 그래서template
필드의labels
필드는 Deployment의 label 정보가 아닌 Pod의 자체의 label 정보이다.- 그래서 꼭
selector.matchLabels
와template.metadata.labels
는 일치해야 한다! - 라벨을 지정하면 다음 커맨드로 해당 라벨이 존재하는 리소스들을 조회할 수 있다.
$ kubectl get <resource> -l <label>
Service
이제 Service의 Manifest 파일을 살펴보자
apiVersion: v1
kind: Service
metadata:
name: hello
labels:
app: hello
spec:
selector: # matchLabels가 존재하지 않는다.
app: hello
tier: backend
ports:
- protocol: TCP
port: 80
targetPort: http
metadata
필드의labels
필드는 Service의 label 정보를 의미한다.selector
필드는 해당 값의 label을 가진 Pod들을 Service 대상으로 지정한다.matchLabels
필드와matchExpressions
필드가 존재하지 않는다.
위에서 확인할 수 있듯이 matchLabels
, matchExpresisons
필드가 Service에는 존재하지 않는다. 대신 selector
필드만으로도 matchLabels
처럼 동작한다.
사실 Deployment뿐만 아니라 Job, ReplicaSet, 그리고 DaemonSet에서도 matchLabels
, matchExpressions
필드가 있다.
그렇다면 왜 Service만 matchLabels, matchExpressions 필드가 없을까?
내 개인적인 생각은 Job, Deployment, ReplicaSet, DaemonSet은 다양한 Pod들을 생성하거나 직접적으로 제어해야 하기 때문에 matchExpressions
를 사용한다고 생각한다.
반면에, Service는 네트워크 요청을 기존에 존재하고, 동일한 역할을 수행하는 Pod들에 라우팅 하는 것이기 때문에, 라벨을 명확하게 정하는 것이 좀 더 안정적일 것이다.
그래서 matchExpressions
를 삭제하고, selector
만으로 matchLabels
역할을 하도록 한 것이 아닐까 생각한다. (괜히 matchLabels가 존재하면, matchExpressions 기능도 있을 것이라 생각하여 작성할 수 있으므로)
ETC
Equality-based, Set-based Requirement
사실 위의 matchLabels
는 Equality-based requirement(동등 기반 요구)방식, matchExpression
는 Set-based Requirement(집합 기만 요구)이다.
API는 현재 Equality-based, Set-based이라는 두 가지 유형의 selector를 지원한다. label selector는 쉼표로 여러 label을 선택할 수 있는데, 이때 쉼표는 AND(&&) 연산자 역할을 한다. OR(||) 연산자는 존재하지 않는다.
Equality-based requirement
Equality-based 또는 InEquality-based requirements를 통해 label의 keys와 values로 필터링할 수 있다. =, ==, !=
연산자를 이용하여 필터링할 수 있다. =
, ==
은 둘 다 동등함을 의미한다.
Set-based requirement
Set-based label requirements는 values 집합에 따라 keys를 필터링할 수 있다. in, notin 그리고 exists (키 식별자만) 연산자를 이용하여 필터링할 수 있다.
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
partition,environment notin (qa)
- 첫 번째는 key가
environment
일 경우, value가production
또는qa
인 label을 필터링한다. - 두 번째는 key가
tier
일 경우, value가frontend
,backend
가 아닌 label을 필터링한다 - 세 번째는 value를 체크하지 않는다. 오직
partition
인 key가 있는 label을 필터링한다. - 네 번째도 value를 체크하지 않는다. 오직
partition
가 아닌 key가 있는 label을 필터링한다. - 다섯 번째는 key가
partition
또는environment
일 때 value가qa
가 아닌 key가 있는 label을 필터링한다.
따라서, Service 리소스는 Equality-based selector를 사용하는 반면, 나머지 리소스들은 Equality-based selector와 Set-based selector 모두 사용한다는 것을 알 수 있다.
labels 작성 예시
- release : "stable", "canary"
- environment : "dev", "qa", "production"
- tier : "frontend", "backend", "cache"
- partition : "customerA", "customerB"
- track : "daily", "weekly"
REFERENCES
Assigning Pods to Nodes - https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
Labels and Selectors - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/