#8 레이블을 이용한 파드의 구성
실제 애플리케이션을 배포할 때 대부분의 사용자는 더 많은 파드를 실행하게 될 것이다.
파드 수가 증가함에 따라 파드를 부분 집합으로 분류할 필요가 있다.
예를 들어 MSA의 경우 배포된 마이크로 서비스의 수는 매우 쉽게 20개를 초과한다. 이러한 구성요소는 복제돼(동일한 구성 요소 여러 복사본이 배포된다.) 여러 버전 혹은 릴리즈가 동시에 실행된다.
이로 인해 시스템에 수백 개의 파드가 생길 수 있다. 파드를 정리하는 메커니즘이 없다면 MSA 안에 있는 파드는 크고 이해하기 어려운 난장판이 된다.
모든 개발자와 시스템 관리자는 어떤 파드가 어떤 것인지 쉽게 알 수 있도록 임의의 기준에 따라 작은 그룹으로 조직하는 방법이 필요하다. 각 파드에 대해 개별적으로 작업을 수행하기보다 특정 그룹에 속한 모든 파드에 관해 한번에 작업하기를 원할 것이다.
이러한 관점에서 labels를 통해 파드와 기타 다른 쿠버네티스 오브젝트의 조직화가 이루어진다.
LABEL 소개
레이블은 파드와 모든 다른 쿠버네티스 리소스를 조직화할 수 있는 단순하면서 강력한 쿠버네티스의 기능이다.
레이블을 리소스에 첨부하는 key-value 쌍으로, 이 쌍은 레이블 셀렉터를 사용해 리소스를 선택할 때 활용된다.
(리소스는 셀렉터에 지정된 레이블을 포함하는지 여부에 따라 필터링된다.)
레이블 키가 해당 리소스 내에서 고유하다면, 하나 이상 원하는 만큼 레이블을 가질 수 있다.
일반적으로 리소스를 생성할 때 레이블을 붙이지만, 나중에 레이블을 추가하거나 수정할 수 있다.
파드를 생성할 때 레이블 지정
레이블 두 개를 가진 파드를 생성해 실제로 레이블이 어떻게 동작하는지 살펴보자.
다음과 같이 kubia-manual-with-labels.yaml을 만든다.
레이블 creation_method=manual과 env=prod를 metadata.labels 섹션에 포함시켰다.
kubectl create를 통해 파드를 생성하고, --show-labels 스위치를 사용해 레이블을 볼 수 있다.
기존 파드의 레이블 수정
기존 파드에 레이블을 추가하거나 수정할 수 있다.
my-app이란 파드의 레이블이 존재하지 않고 수동으로 생성했으니, creation_method=manual이란 레이블을 추가할 수 있다.
만약의 기존 레이블을 수정할 경우에는 --overwrite옵션을 설정하면 된다.
레이블 셀렉터를 이용한 파드 부분집합 나열
리소스를 조회할 때 각 리소스 옆에 부착된 레이블을 같이 표시하는 것은 그리 의미 있는 일은 아니다.
중요한 것은 레이블이 레이블 셀렉터와 함께 사용된다는 점이다.
레이블 셀렉터는 특정 값과 레이블을 갖는지 여부에 따라 리소스를 필터링하는 기준이 된다.
- 특정한 키를 포함하거나 포함하지 않는 레이블
- 특정한 키와 값을 가진 레이블
- 특정한 키를 갖고 있지만, 다른 값을 가진 레이블
만들어 둔 파드에 셀렉터를 사용해보자. 수동으로 생성한 파드를 모두 보려면 다음 명령을 실행한다.
레이블 셀렉터에서 여러 조건 사용
셀렉터는 쉼표로 구분된 여러 기준을 포함하는 것도 가능하다.
셀렉터를 통해 선택하기 위해서는 리소스가 모든 기준을 만족해야 한다. (셀렉터 간 and 조건을 만족시켜야 한다.)
레이블 셀렉터는 파드 목록을 나열하는 것뿐만 아니라, 파드 부분 집합에 작업을 수행할 때도 유용하다.또한 레이블 셀렉터는 kubectl에서만 사용하는 것이 아니고 내부적으로도 사용된다.
레이블과 셀렉터를 이용해 파드 스케줄링 제한
지금까지 생성한 모든 파드는 워커 노드 전체에 걸쳐 무작위로 스케줄링됐다.
쿠버네티스는 모든 노드를 하나의 대규모 배포 플랫폼으로 노출하기 때문에, 파드가 어느 노드에 스케줄링됐느냐는 중요하지 않다.
각 파드는 요청한 만큼에 정확한 컴퓨팅 리소스를 할당받는다. 그리고 다른 파드에서 해당 파드로 접근하는 것은 파드가 스케줄링된 노드에 아무런 영향을 받지 않는다. 그렇기 때문에 쿠버네티스에게 파드를 어디에 스케줄링할지 알려줄 필요는 없다.
하지만 파드를 스케줄링할 위치를 결정할 때 약간이라도 영향을 미치고 싶은 상황이 있다.
예를 들어, 하드웨어 인프라가 동일하지 않은 경우를 들 수 있다.
워커 노드 일부는 HDD를 가지고 있고 나머지에게 SSD를 가지고 있는 경우, 특정 파드를 한 그룹에 나머지 파드는 다른 그룹에 스케줄링되도록 할 수 있다.
또 다른 예는 GPU 가속을 제공하는 노드에만 GPU 계산이 필요한 파드를 스케줄링하는 것을 들 수 있다.
쿠버네티스의 전체적인 아이디어는 그 위에 실행되는 애플리케이션으로부터 실제 인프라를 숨기는 것에 있기에 파드가 어떤 노드에 스케줄링돼야 하는지 구체적으로 지정하고 싶지는 않을 것이다. 그로 인해 애플리케이션이 인프라에 결합되기 때문이다.
그러나 노드 레이블과 셀렉터를 선택하여 필요한 요구사항을 기술하고 쿠버네티스가 만족하는 요구사항을 가진 노드에 스케줄링되도록 할 수 있다.
레이블과 셀렉터를 활용하여 특정 조건을 충족하는 노드에 배포하기
우선 노드에 레이블을 추가한다.
예를 들어 해당 노드가 gpu가속을 지원하면 다음과 같이 레이블을 추가할 수 있다.
kubectl label node 노드명 gpu=true
이후 pod yaml을 다음과 같이 수정한다.
spec.nodeSelector를 추가하고 위와 같은 값을 넣어주면, 스케줄러는 파드를 생성할 때 클러스터 내의 모든 노드들 중 gpu=true라는 label을 가지고 있는 노드 중 하나로 스케줄링한다.
하나의 특정 노드로 배포하기
마찬가지로 각 노드에는 각 노드에는 키를 kubernetes.io으로 하고 값에는 고유 호스트 이름이 설정되어 있는 고유의 레이블이 있기 때문에, 파드를 특정한 노드로 스케줄링하는 것도 가능하다.
그러나 nodeSelector에 실제 호스트 이름을 지정할 경우에 해당 노드가 오프라인 상태인 경우 파드가 스케줄링되지 않을 수 있다. 따라서 하나의 특정 노드로 배포하는 것은 권장되지 않으며 노드의 논리적인 그룹으로 배포하는 것을 생가해야 한다.