Skip to main content

쿠버네티스의 셀렉터

❓ 문득 아래와 같은 데몬셋을 선언하기 위해 쿠버네티스 공식문서를 참고하여 야믈 파일을 작성하던 도중 왜 .spec.selector.matchLabels 셀렉터와 .spec.template.metadata.labels 템플릿 레이블을 같이 선언하는지 궁금하여 본 내용을 작성하였다.

데몬셋

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
# 셀렉터
selector:
matchLabels:
name: fluentd
# 템플릿 레이블
template:
metadata:
labels:
name: fluentd

spec:
containers:
- name: fluentd
image: fluentd
volumeMounts:
- mountPath: /var/lib/docker/containers
name: dockercontainerdir
- mountPath: /var/log
name: varlogdir

volumes:
- name: dockercontainerdir
hostPath:
path: /var/lib/docker/containers
- name: varlogdir
hostPath:
path: /var/log

만약 .spec.selector를 명시하면, 이것은 .spec.template.metadata.labels와 일치해야 한다.

일치하지 않는 구성은 API에 의해 거부된다. 또한 일반적으로 다른 데몬셋이나 레플리카셋과 같은 다른 컨트롤러를 통해 직접적으로 레이블이 셀렉터와 일치하는 다른 파드를 생성하지 않아야 한다. 그렇지 않으면 데몬셋 컨트롤러는 해당 파드가 생성된 것으로 생각한다. 쿠버네티스는 이런 일을 하는 것을 막지 못한다. 사용자가 이와 같은 일을 하게 되는 한 가지 경우는 테스트를 목적으로 한 노드에서 다른 값을 가지는 파드들을 수동으로 생성하는 것이다.


파드 셀렉터

.spec.selector 필드는 레이블 셀렉터이다. 앞서 논의한 것처럼 이 레이블은 소유될 가능성이 있는 파드를 식별하는데 사용된다.


ReplicaSet

레플리카셋에서 .spec.template.metadata.labelsspec.selector과 일치해야 하며 그렇지 않으면 API에 의해 거부된다. 2개의 레플리카셋이 동일한 .spec.selector 필드를 지정한 반면, 다른 .spec.template.metada.labels.spec.template.spec 필드를 명시한 경우, 각 레플리카셋은 다른 레플리카셋이 생성한 파드를 무시한다.


Deployment

.spec.selector 필드는 디플로이먼트가 관리할 파드를 찾는 방법을 정의하며 .spec.selector.matchLabels 필드는 {key,value}의 쌍으로 매핑되어 있다. matchLabels에 매핑된 단일 {key,value}은 matchExpressions의 요소에 해당하며, 키 필드는 "key"에 그리고 연산자는 "in"에 대응되며 값 배열은 "value"만 포함한다. 매칭을 위해서는 matchLabels와 matchExpressions의 모든 요건이 충족되어야 한다.


StatefulSet

스테이트풀셋의 .spec.selector 필드는 .spec.template.metadata.labels 레이블과 일치하도록 설정해야 한다. 쿠버네티스 1.8 이전에서는 생략시에 .spec.selector 필드가 기본 설정되었다. 1.8과 이후 버전에서는 파드 셀렉터를 명시하지 않으면 스테이트풀셋 생성시 유효한 검증 오류가 발생하는 결과가 나오게 된다.

스테이트풀셋

스테이트풀셋은 애플리케이션의 스테이트풀을 관리하는데 사용하는 워크로드 API 오브젝트이다. 파드 집합의 디플로이먼트와 스케일링을 관리하며, 파드들의 순서 및 고유성을 보장한다. 디플로이먼트와 유사하게, 스테이트풀셋은 동일한 컨테이너 스펙을 기반으로 둔 파드들을 관리한다. 디플로이먼트와는 다르게, 스테이트풀셋은 각 파드의 독자성을 유지한다. 이 파드들은 동일한 스펙으로 생성되었지만, 서로 교체는 불가능하다. 다시 말해, 각각은 재스케줄링 간에도 지속적으로 유지되는 식별자를 가진다.

스테이트풀셋은 다음 중 하나 또는 이상이 필요한 애플리케이션에 유용하다.

  • 안정된, 고유한 네트워크 식별자
  • 안정된, 지속성을 갖는 스토리지
  • 순차적인, 정상 배포와 스케일링
  • 순차적인, 자동 롤링 업데이트

쿠버네티스에서 마이크로서비스 구조로 동작하는 애플리케이션은 대부분 상태를 갖지 않는 경우(Stateless)가 많습니다. 그러한 경우에는 디플로이먼트, 레플리카셋을 통해 쉽게 애플리케이션을 배포할 수 있습니다.

하지만, 레플리케이션 컨트롤러나 레플리카셋을 제공하는 파드는 각 별도의 볼륨을 사용할 수 있는 방법을 제공해주지 않아 모두 같은 볼륨으로 같은 상태를 가질 수 밖에 없습니다. 또한 데이터베이스처럼 상태를 갖는(Stateful) 애플리케이션을 쿠버네티스에서 실행하는 것은 매우 복잡한 일입니다. 왜냐하면 파드 내부의 데이터를 어떻게 관리해야 할지, 상태를 갖는 파드에는 어떻게 접근할 수 있을지 등을 꼼꼼히 고려해야 하기 때문입니다.

쿠버네티스가 이에 대한 해결책을 완벽하게 제공하는 것은 아니지만, 스테이트풀셋이라는 쿠버네티스 오브젝트를 통해 어느정도 해결할 수 있도록 제공하고 있습니다. 즉, 파드마다 각각 다른 스토리지를 사용해 각각 다른 상태를 유지하기 위해서는 스테이트풀셋(StatefulSet) 리소스를 사용하면 됩니다. 또한 목적에 따라 해당 파드에 연결하기 위한 Headless Service를 달아주면 됩니다.


서비스

파드 셀렉터가 없을 경우 엔드포인트 오브젝트가 자동으로 생성되지 않아 직접 엔드포인트 오브젝트를 선언해야 한다.