개인적으로 공부한 내용을 작성한 게시글입니다. 잘못된 내용이 있을 수 있습니다.
틀린 부분을 알려주시면 바로 고치겠습니다.감사합니다.
쿠버네티스 리소스의 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/