Kubernetes Scheduler (Affinity)
[Kubernetes Scheduler 관련 글 목록]
Kubernetes Scheduler (Pod를 원하는 Worker Node에 배포하기)
Kubernetes Scheduler (nodeSelector)
Kubernetes Scheduler (Taint & Toleration)
Kubernetes Scheduler (Affinity)
Kube-Scheduler의 다양한 기능을 사용해서 관리자가 직접
특정 Worker Node에 Pod 가 생성되도록 설정할 수 도 있음
대표적으로
nodeSelector
Taint & Toleration
Affinity
3가지 방법이 있는데
이 글에서는 Affinity에 대해서 알아보겠음.
[목차]
Affinity란?
Node Affinity 실습
Pod Affinity 실습
Affinity의 Operator 설명
Preferred Affinity 의 weight 설명
[환경]
Master Node server
OS = CentOS 7
리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64
docker version : 1.13.1
api verison : 1.26
Worker Node server 1
OS = CentOS 7
리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64
docker version : 1.13.1
api verison : 1.26
Worker Node server 2
OS = CentOS 7
리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64
docker version : 1.13.1
api verison : 1.26
Kubernetes version
1.18
Affinity란?
Pod가 특정 Worker Node에 배치되도록 하는 정책.
Node를 기준으로 Scheduling 하는 Node Affinity와
Pod를 기준으로 Scheduling 하는 Pod Affinity가 있음.
Node Affinity
새로운 Pod가 특정 Worker Node로 배포되도록 Scheduling 해주는 설정.
Node Affinity는 선호도를 설정할 수 있는 기능으로
Required Node Affinity와 Preferred Node Affinity 2가지로 구분됨.
가장 처음 설명드렸던 nodeSelector는 Required Node Affinity와 동일한 원리.
만약 nodeSelector 도 설정되어있고
Node Affinity 도 설정되어있다면
두 조건을 모두 만족해야 Pod 가 배포됨.
nodeSelector와 차이점을 있다면
Affinity는 operator 설정이 가능함
[ operator 설정]
in, Exists, Gt, Lt, NotIn, DoesNotExist, 설정이 올 수 있음
Required Node Affinity
반드시 규칙을 만족.
Pod를 모든 조건이 맞는 Worker Node에만 배포되도록 하는 설정.
설정 : requiredDuringSchedulingIgnoredDuringExecution (강제)
Preferred Node Affinity
우선순위 설정 가능.
가급적 규칙을 만족하는것이 좋음. 규칙을 꼭 만족하지 않아도 됨.
Pod를 모든 조건이 맞는 Worker Node에만 배포되도록 하는 설정.
설정 : preferredDuringSchedulingIgnoredDuringExecution (반강제)
Pod Affinity
새로운 Pod가 기존에 배포되어서 실행 중인 Pod를 참고해서
Worker Node로 배포되도록 Scheduling 해주는 설정.
동일한 다수의 Pods가
네트워크와 같은 리소스 효율을 위해 동일한 Worker Node 에서 동작하는것이 효율적일 수도 있고
HA구성을 해야하는 경우와 같이 반드시 서로 다른 Worker Node 배포되어야하는 경우가 있음.
그에 따라
Pod Affinity와 Pod AnitAffinity로 구분되어지는데
동일한 Pods가 같은 Worker Node에서 실행되어야한다면 Pod Affinity를 사용하고
동일한 Pods가 다른 Worker Node에서 실행되어야한다면 Pod AntiAffinity를 사용해야함.
Pod Affinity 또한 선호도를 설정할 수 있는 기능으로
Required Pod Affinity와 Preferred Pod Affinity 2가지로 구분됨.
Required Pod Affinity
반드시 규칙을 만족.
Pod를 모든 조건이 맞는 Worker Node에만 배포되도록 하는 설정.
설정 : requiredDuringSchedulingIgnoredDuringExecution (강제)
Preferred Pod Affinity
우선순위 설정 가능.
가급적 규칙을 만족하는것이 좋음. 규칙을 꼭 만족하지 않아도 됨.
Pod를 모든 조건이 맞는 Worker Node에만 배포되도록 하는 설정.
설정 : preferredDuringSchedulingIgnoredDuringExecution (반강제)
일반적으로 실제 환경에서는 Pod의 replicaset을
균등하게 분산하는 것보다 충분한 개수의 replicaset를 확보하는 것이 더 중요하므로
Hard Pod Affinity보다 Soft Pod Affinity를 사용하는것을 추천한다고 함.
Pod AntiAffinity
주로 HA구성을 할 때 처럼
동일한 Pods가 서로 다른 Worker Node에서 실행되야할 때 사용하는 설정.
Node Affinity 실습
0. 목표
[ Required Node Affinity Test를 위해 ]
Worker Node One과 Two 모두
requiredkey: iksoonvalue Label을 추가해서
Worker Node One, Two 이외의
Worker Node 에는 Pod가 배포되지 않도록함
[ Preferred Node Affinity Test를 위해 ]
Worker Node One 에는
preferredkey1: iksoonvalue1 Label을 추가하고
weight : 10으로 부여,
Worker Node Two 에는
preferredkey2: iksoonvalue2 Label을 추가하고
weight : 20으로 부여해서
우선순위가 더 높은
Worker Node Two에 Pod가 배포되는지 확인.
1. Worker Node 의 Label 확인
Kubernetes Cluster를 구성하고 있는 모든 Node에 미리 추가되어있는
Default Label 을 확인.
[명령어]
kubectl get nodes --show-labels
[확인 결과]
각 Node 의 CPU 종류, OS 종류, host name 이 Label로 설정되어있고
MasterNode는 추가로
"node-role.kubernetes.io/master="
Labels이 있어서 Worker Node 와 구분되어 있음.
Node Selector의 경우에 이러한 기존의 Labels를 지정해서 사용할 수 있지만
리서치에서는 Labels 을 직접 추가해서
추가한 Label을 인식해서 Pod를 생성해보겠음.
2. Worker Node 의 Label 추가
Worker Node one, two 에
requiredkey: iksoonvalue Label 추가.
Worker Node one에
preferredkey1: iksoonvalue1 Label 추가
Worker Node Two에
preferredkey2: iksoonvalue2 Label 추가
[명령어]
kubectl label nodes [Node name] [key]=[value]
예)
kubectl label nodes kube.workerone.node requiredkey=iksoonvalue preferredkey1=iksoonvalue1
kubectl label nodes kube.workertwo.node requiredkey=iksoonvalue preferredkey2=iksoonvalue2
3. Node Affinity를 사용해서 특정 Worker Node에 Pod 배포
한가지 Pod에 다수의 Node Affinity를 적용할 수 있음.
아래의 예제 deployment.yaml은
Required Node Affinity 설정 1개와
Preferred Node Affinity 설정 1개로
총 2개의 Node Affinity가 설정되어있음.
[예제 deployment.yaml ]
apiVersion: apps/v1 kind: Deployment metadata: name: iksoon-deployment-test labels: app: iksoon-test spec: replicas: 1 selector: matchLabels: app: iksoon-pod template: metadata: labels: app: iksoon-pod spec: containers: - name: iksoon-tomcat image: peksoon/iksoon_tomcat:1.0.6 ports: - containerPort: 8080 affinity: # affinity 사용 nodeAffinity: # 종류는 Node Affinity로 설정 # Label이 매칭 되는 Worker Node 에만 Pod 배포 가능. requiredDuringSchedulingIgnoredDuringExecution: # Required Node Affinity로 설정 nodeSelectorTerms: - matchExpressions: # 특정 Worker Node에 설정되어있는 Label과 # 해당 설정의 Label이 매칭되는 Worker Node에 Pod를 생성 # Label set-based selector 문법 사용 - key: requiredkey values: iksoonvalue operator: In # in, Exists, Gt, Lt, NotIn, DoesNotExist, 설정이 올 수 있음 # 우선순위가 더 높은 Worker Node Two에 Pod가 배포되는지 확인. preferredDuringSchedulingIgnoredDuringExecution: # Preferred Node Affinity로 설정 - weight: 10 preference: matchExpressions: - key: preferredkey1 values: iksoonvalue1 operator: In preferredDuringSchedulingIgnoredDuringExecution: - weight: 20 preference: matchExpressions: - key: preferredkey2 values: iksoonvalue2 operator: In |
[결과]
deployment를 생성하면
Worker Node two에 Pod가 생성되어있는것을 확인할 수 있음
[ 이유 ]
Required Node Affinity 설정 : Worker Node One, Two 에 생성 가능 조건을 충족했음.
preferred Node Affinity 설정 : Worker Node One보다 two의 weight가 더 커서 two에 생성됨.
4. Worker Node 의 Label 삭제
[명령어]
kubectl label nodes [Node name] [key]-
예)
kubectl label nodes kube.workerone.node requiredkey- preferredkey1-
kubectl label nodes kube.workertwo.node requiredkey- preferredkey2-
Pod Affinity 실습
0. 목표
[ Required Pod Anit Affinity Test를 위해 ]
2개의 Worker Node가 존재 할 경우
Deployment 에서 replicaset 을 3로 설정하여
3개의 Tomcat Pod를
Required Pod Anit Affinity로 서로 다른 Worker Node에
배포되도록 했을 때 결과가 어떻게 나오는지 확인.
[ Preferred Pod Anti Affinity Test를 위해 ]
2개의 Worker Node가 존재 할 경우
Deployment 에서 replicaset 을 3로 설정하여
3개의 Mysql Pod를
Required Pod Anit Affinity로 서로 다른 Worker Node에
배포되도록 했을 때 결과가 어떻게 나오는지 확인.
[ Preferred Pod Affinity Test를 위해 ]
Myql 은 생성했었던 Tomcat Pod 가 있는 위치에만 생성되도록 설정.
1. podAntiAffinity 설정된 Tomcat Pod생성
[ 예제 deployment.yaml ]
apiVersion: apps/v1 kind: Deployment metadata: name: iksoon-deployment-affinity labels: app: iksoon-tomcat spec: replicas: 3 # 3개의 Pod가 생성. selector: matchLabels: app: iksoon-tomcat-pod template: metadata: labels: app: iksoon-tomcat-pod # 생성되는 Pod 의 Label은 app=iksoon-tomcat-pod로 설정 spec: containers: - name: iksoon-tomcat image: peksoon/iksoon_tomcat:1.0.6 ports: - containerPort: 8080 affinity: # affinity 사용 # Anit Affinity로 서로 다른 Worker Node에 배포되도록 설정 podAntiAffinity: # 종류는 Pod Anti Affinity로 설정 requiredDuringSchedulingIgnoredDuringExecution: # Required Pod Anti Affinity로 설정 - labelSelector: matchExpressions: - key: app # podAntiAffinity를 적용할 Pod의 Key를 넣어줌. # 해당 deployment로 생성될 Pod들이 서로 다른 Worker Node 에 생성되야하므로 # Deployment에서 생성되는 Pod의 Label을 넣어줌 values: # 마찬가지로 적용할 Pod의 value를 넣어줌 - iksoon-tomcat-pod operator: In # 아래에서 자세히 설명 topologyKey: kubernetes.io/hostname # Pod Anti Affinity를 적용할 Worker Node 찾음. # topologyKey는 Worker Node Label의 Key를 확인해서 # 설정된 Key가 Worker Node에 존재하면 Pod Anti Affinity가 적용됨. # 해당 key의 value값은 확인하지 않음. |
[ 생성 결과 ]
PodAntiAffinity 설정으로 인해
Pod 가 서로 다른 Worker Node 에 생성되는것을 확인할 수 있음
replicaset을 3으로 설정해서 총 3개의 Pod가 생성되었는데
Worker node가 2개이므로
각각 Worker Node one, two 에서 하나씩 생성되었고
나머지 하나는 생성될 worker node 가 없어서 pending 상태가 됨.
2. podAntiAffinity 와 podAffinity설정된 Mysql Pod생성
[ 예제 deployment.yaml ]
apiVersion: apps/v1 kind: Deployment metadata: name: iksoon-deployment-mysql labels: app: iksoon-mysql spec: replicas: 3 # 3개의 Pod가 생성. selector: matchLabels: app: iksoon-mysql-pod template: metadata: labels: app: iksoon-mysql-pod # 생성되는 Pod 의 Label은 app=iksoon-mysql-pod로 설정 spec: containers: - name: iksoon-mysql image: peksoon/iksoon_mysql:1.0.2 ports: - containerPort: 3306 affinity: # Anit Affinity로 서로 다른 Worker Node에 배포되도록 설정 podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app values: - iksoon-mysql-pod operator: In topologyKey: kubernetes.io/hostname # 상위에서 생성했던 tomcat pod가 있는 worker Node에만 mysql이 생성되도록 설정 podAffinity: # 이전에 생성했던 requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app # 상위에서 생성했던 tomcat pod 의 Label 값을 넣어줌 values: - iksoon-tomcat-pod # 상위에서 생성했던 tomcat pod 의 Label 값을 넣어줌 operator: In topologyKey: kubernetes.io/hostname |
[ 생성 결과 ]
PodAntiAffinity 설정으로 인해
Pod 가 서로 다른 Worker Node 에 생성되는것을 확인할 수 있음
replicaset을 3으로 설정해서 총 3개의 Pod가 생성되었는데
Worker node가 2개이므로
각각 Worker Node one, two 에서 하나씩 생성되었고
나머지 하나는 생성될 worker node 가 없어서 pending 상태가 됨.
PodAffinity 설정으로 인해
tomcat pod 가 동작 중인 worker Node 에만
mysql Pod가 배포됨.
3. tomcat Pod가 없는 상태에서 podAffinity설정된 Mysql Pod생성
[결과]
PodAffinity 설정으로 인해
tomcat pod가 생성되어있는 Worker Node가 없음으로
어떠한 Worker Node 에도
Mysql Pod 가 생성이 안됨.
Affinity의 Operator 설명
Operator는
Key / Value 를 어떠한 원리로 매칭 시킬것인가에 대한 설정으로
in, NotIn, Exists, DoesNotExist, Gt, Lt 설정이 올 수 있음
operator: In
설정 중 1개라도 일치하면 매칭.
가장 많이 사용되는 operatoer 설정.
반드시 values 설정이 있어야함.
[ Operator 예제 ]
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: requiredkey operator: In values: - iksoonvalue1 - iksoonvalue2 - iksoonvalue3 |
상위 예제 yaml을 보면
values에 3개의 value가 있는데
In으로 설정하면
3개의 values 값 중 하나라도 매칭이 되면
Worker Node에 배포가 가능함.
[ 예시 ]
Worker Node 에 requiredkey=iksoonvalue1 Label만 있어도
정상 배포 됨.
operator: NotIn
설정 중 1개라도 일치하면 매칭 안됨.
Anti Affinity 설정으로 사용됨.
반드시 values 설정이 있어야함.
[ Operator 설명 예제 ]
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: requiredkey operator: In values: - iksoonvalue1 - iksoonvalue2 - iksoonvalue3 |
상위 예제 yaml을 보면
values에 3개의 value가 있는데
NotIn으로 설정하면
3개의 values 값 중 하나라도 매칭이 되면
Worker Node에 배포가 가능함.
[ 예시 ]
Worker Node 에 requiredkey=iksoonvalue1 Label만 있어도
배포가 안됨.
operator: Exists
명시한 모든 설정이 일치하면 매칭. (하나라도 없다면 매칭 안됨)
반드시 values 설정이 없어야함.
[ Operator 설명 예제 ]
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: requiredkey key: preferredkey1 key: preferredkey2 operator: Exists |
key 값만 일치하면 매칭됨.
value 값 상관 없음.
상위 예제를 보면 key만 있고 values는 없음
말그대로 동일한 Key만 존재하면 매칭됨.
상위 예제 yaml을 보면
3개의 key 값이 있는데
해당 3개의 key와 매칭되는 Label을 가진
worker node 에 배포가 됨.
1개라도 매칭이 안되면 배포 안됨.
(참고)
만약 " valuse: " 설정이 있는 상태에서 Exists Ehsms DoesNotExist를 사용하면
Forbidden: may not be specified when 'operator' is 'Exists' or 'DoesNotExists' 오류가 발생함.
operator: DoesNotExist
모든 설정이 일치하면 매칭 안됨. (하나라도 틀리면 매칭됨.)
반드시 values 설정이 없어야함.
[ Operator 설명 예제 ]
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: requiredkey key: preferredkey1 key: preferredkey2 operator: DoesNotExists |
key 값만가지고 판단함.
value 값 상관 없음.
상위 예제를 보면 key만 있고 values는 없음
말그대로 동일한 Key만 존재하면 매칭되지 않음.
상위 예제 yaml을 보면
3개의 key 값이 있는데
해당 3개의 key와 매칭되는 Label을 가진
worker node 에는 배포가 안됨
1개라도 매칭이 안되면 배포 됨.
operator: Gt
Greater than
반드시 value 가 하나 있어야하고
value는 정수값만 올 수 있음.
먼저 worker Node one 에
gtkey=200 Label 을 추가하고 진행.
[ Operator 설명 예제 ]
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: gtkey values: ["100"] # Worker Node에 설정되어있는 gtKey value가 100보다 크면 생성 operator: Gt |
[Gt 특징]
해당 key Label이 있는 Worker Node에만 배포가 가능.
Worker Node에 설정되어있는 value가 affinity에 설정되어 있는 values보다 크면 배포.
Worker Node에 설정되어있는 value와 affinity에 설정되어 있는 values가 같으면 배포 안됨.
Key당 1개의 values 값만 비교 가능.
values 값이 많다면 가장 마지막 값으로 판단함. (이전 values값은 무시)
[ 예시 ]
Worker Node Label 설정이 gtkey=200 환경에서
affinity values 설정이
100 이면 Running.
200 이면 Pending.
300 이면 Pending.
100, 300 이면 Pending.
300, 100 이면 Running.
operator: Lt
Less than
반드시 value 가 하나 있어야하고
value는 정수값만 올 수 있음.
먼저 worker Node one 에
gtkey=200 Label 을 추가하고 진행.
[ Operator 설명 예제 ]
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: gtkey values: ["300"] # Worker Node에 설정되어있는 gtKey value가 300보다 작으면 생성 operator: Lt |
[Gt 특징]
해당 key Label이 있는 Worker Node에만 배포가 가능.
Worker Node에 설정되어있는 value가 affinity에 설정되어 있는 values보다 작으면 배포.
Worker Node에 설정되어있는 value와 affinity에 설정되어 있는 values가 같으면 배포 안됨.
Key당 1개의 values 값만 비교 가능.
values 값이 많다면 가장 마지막 값으로 판단함. (이전 values값은 무시)
[ 예시 ]
Worker Node Label 설정이 gtkey=200 환경에서
affinity values 설정이
100 이면 Pending.
200 이면 Pending.
300 이면 Running.
100, 300 이면 Running.
300, 100 이면 Pending.
Preferred Affinity 의 weight 설명
1 ~ 100 사이의 값으로 설정 가능.
Worker Node 의 Preferred Affinity weight 값을 합해서
값이 높은 Worker Node를 가장 1순위로 선정해서
Pod를 배포함.
상황 예제
Worker Node One
Label 설정이
key1: value1
가 되어있고
Worker Node Two
Label 설정이
key2: value2
가 되어있고
Worker Node Three에
Label 설정이
key1: value1
key2: value2
로 설정되어있음.
preferred Affinity 설정이 되어있는 Pod에서
key1: value1 에
weight를 10을 설정하고
Key2: value2에
weight를 20을 설정했다면
해당 Pod 배포 시 우선 순위는
Worker Node Three weight 총합 = 30으로 1순위
Worker Node Two weight 총합 = 20으로 2순위
Worker Node one weight 총합 = 10으로 3순위
가 되어
Worker Node Three에 배포됨.
만약
어떠한 Worker Node에도
Label 설정이 안되어있다면
우선 순위가 동등하게 랜덤으로 배정됨.
제 글을 복사할 시 출처를 명시해주세요.
글에 오타, 오류가 있다면 댓글로 알려주세요! 바로 수정하겠습니다!
참고
[Affinity]
https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/
https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
https://kublr.com/blog/implementing-advanced-scheduling-techniques-with-kubernetes/
https://bcho.tistory.com/1346?category=731548
'Kubernetes > Scheduler' 카테고리의 다른 글
kubernetes PriorityClass ( Priority & Preemption ) (0) | 2020.10.11 |
---|---|
Kubernetes Scheduler (Taint & Toleration) (0) | 2020.10.11 |
Kubernetes Scheduler (nodeSelector) (0) | 2020.10.11 |
Kubernetes Scheduler (Pod를 원하는 Worker Node에 배포하기) (0) | 2020.10.11 |