Pod의 효과적인 할당을 위한 기술 전략과 작동 방식 및 다양한 방법들에 대해 소개합니다.필요에 따라 특정 노드에서만 실행하거나 특정 노드에서 실행하는 것에 우선 순위를 두도록 제한할 수 있습니다. 스케쥴러가 자동으로 적절한 배치를 수행하므로 일반적으로 이러한 제한들은 필요하지 않지만, 더 세밀한 제어가 필요한 경우가 프로덕션에서 발생할 수 있습니다.
이번 실습에서는 이러한 요구 조건에 맞추어 Pod에 대한 할당을 중점적으로 다룹니다.
NodeSelector
1.소개.
NodeSelector는 가장 간단한 노드 선택 방법입니다. NodeSelector는 PodSpec 필드에서 선택이 가능하며, Key-value 페어로 지정하게 됩니다. Pod가 Node에 실행 될 수 있으려면, Node에 표시된 Key-Value 형태의 Lable이 존재해야 합니다. 이것은 다중으로 지정할 수도 있습니다.
정상적으로 배포되었는지 확인합니다. 앞서 지정한 worker node로 배포되어야 합니다.
kubectl get nodes --show-labels | grep disktype
kubectl -n nodeselector get pods -o wide
아래는 출력 결과 예시입니다.
$ kubectl get nodes --show-labels | grep disktype
ip-10-11-16-31.ap-northeast-2.compute.internal Ready <none> 120m v1.16.12-eks-904af05 alpha.eksctl.io/cluster-name=eksworkshop,alpha.eksctl.io/instance-id=i-0ca4ddf4adea01038,alpha.eksctl.io/nodegroup-name=ng1-public,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m5.xlarge,beta.kubernetes.io/os=linux,disktype=ssd,failure-domain.beta.kubernetes.io/region=ap-northeast-2,failure-domain.beta.kubernetes.io/zone=ap-northeast-2a,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-10-11-16-31.ap-northeast-2.compute.internal,kubernetes.io/os=linux,nodegroup-type=frontend-workloads
$ kubectl -n nodeselector get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 4m18s 10.11.28.19 ip-10-11-16-31.ap-northeast-2.compute.internal <none> <none>
Affinity 와 Anti-Affinity
1.소개.
nodeSelector 는 파드를 특정 label이 있는 노드로 배하는 매우 간단한 방법을 제공합니. 하지만 Affinity/Anti-Affinity 기능은 조금 더 유연하게 파드를 노드에 배치하는 방법을 제공합니다. 주요 개선 사항은 다음과 같습니다 .
Affinity/Anti-Affinity 언어가 더 다양하게 표현할 수 있습니다 . 언어는 논리 연산자인 AND 연산으로 작성된 정확한 매칭 항목 이외에 더 많은 매칭 규칙을 제공합니다 .
규칙이 엄격한 요구 사항이 아니라 "required-hard affinity / preferred - soft affinity" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없더라도, 파드가 계속 유연하게 스케줄 되도록 합니다.
노드 자체에 label을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 label을 제한할 수 있습니다. 이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있습니다 .
Affinity 기능은 "노드 Affinity" 와 "파드 Affinity/Anti-Affinity" 두 종류의 Affinity로 구성됩니다. "노드 Affinity" 는 기존 nodeSelector 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있습다.), "파드 Affinity/Anti-Affinity" 위에서 나열된 세번째 항목에 설명된 대로 노드 label이 아닌 파드 label에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가집니다 .
2.Node Affinity
앞서 소개한 nodeSelector 와 유사합니다. 노드 label을 기반으로 다양한 조건들을 명시할 수 있다는 점에서 차이가 있습니다.
현재 requiredDuringSchedulingIgnoredDuringExecution 와 preferredDuringSchedulingIgnoredDuringExecution 로 부르는 두 가지 종류의 노드 어피니티가 있습니다 .
requiredDuringSchedulingIgnoredDuringExecution 파드가 노드에 스케줄 되도록 반드시 규칙을 만해야 하는 것(nodeSelector 와 같으나 보다 상세 구문을 사용해서)을 지정하고, preferredDuringSchedulingIgnoredDuringExecution 는 스케줄러가 시도하려고는 하지만, preferences 를 지정한다는 점에서 이를 각각 "엄격함(hard)" 과 "유연함(soft)" 으로 생각할 수 있습니다.
이름의 "IgnoredDuringExecution" 부분은 nodeSelector 작동 방식과 유사하게 노드의 레이블이 런타임 중에 변경되어 파드의 Affinity 규칙이 더 이상 충족되지 않아도 파드가 여전히 그 노드에서 동작한다는 의미입니다 .
향후에는 referredDuringSchedulingIgnoredDuringExecution 와 같은 requiredDuringSchedulingIgnoredDuringExecution 를 제공할 계획입니다 .
따라서 requiredDuringSchedulingIgnoredDuringExecution 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이 될 수 있고, preferredDuringSchedulingIgnoredDuringExecution 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고 하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 있을 것이다.
아래와 같이 pod 배포를 위한 새로운 매니페스트 파일을 작성합니다.
Node Affinity는 다음과 같은 구문의 의미를 가지고 있습니다.
required - 반드시 포함되어야 함.
preferred - 우선하지만 필수는 아님.
Ingnored - Runtime 중에 Node Label 변경시 무시
DuringScheduling 뒤에 오는 required - Runtime 중에 NodeLabel 변경시 즉시 재기동.
해당 Affinity의 NodeAffinity는 node의 label의 Key=azname, value=ap-northeast-2a,ap-northeast-2b가 있는 곳에만 배치하겠다는 의미입니다. 또한 해당 기준을 충족하는 노드 중에서 Key=another-node-label-key value=another-node-label-value를 선호합니다.
예제에서 operator:In 연산자를 사용하였습니다. In, NotIn, Exists, DoesNotExist, Gt, Lt 등 다양한 연산자를 사용할 수 있습니다. nodeAffinity에 대한 아래 몇가지 내용을 알아 둘 필요가 있습니다.
2개 이상의 matchExpressions가 선언되어 있는 경우에는 , 모든 조건이 만족해야 Pod가 배포됩니다. 또한 matchExpressions 내부의 선언된 조건이 여러개 있는 경우에도 모든 조건을 만족해야 Pod가 배포됩니다.
key는 고유의 값 한개를 선언하지만, value는 예제 처럼 여러개를 선언할 수 있습니다. (value는 하나의 조건만 만족해도 됩니다.)
Web-Server를 배포할 때 label이 web-store입니다. 그런데 podAntiAffinity가 web-store이므로, web-server가 없는 노드에 배포될 것입니다. 하지만 만약 Node가 많다면, Redis-Cache에 없는 노드에 설치될 수도 있기 때문에, podAffinity가 app이므로 Redis-Cache에 있는 노드에만 설치됩니다.
이와 같은 배포전략은 여러개의 앱을 요구 조건에 따라 특정 노드에 묶어서 배포할 때, 매우 효과적이며 강력한 배포전략 기술입니다.