Kubernetes의 Node Scheduling
- Pod를 생성할 경우, 생성할 Pod가 어떤 노드에 할당되어야 할지 유저가 지정하거나 쿠버네티스에서 자동적으로 할당가능 또는 운영자가 특정 노드를 사용하지 못하도록 관리 가능
- 이를 Scheduling이라고 부르며 쿠버네티스는 다양한 기능으로 이러한 Scheduling을 지원
Node Scheduling을 지원하는 다양한 기능
1. 특정 Node를 선택하는 방법
- NodeName
- Pod를 생성하면서 특정 Node를 지정 Scheduler와 상관없이 Node에 할당됨
- 명시적으로 사용할 수 있어 좋아보이지만, 실사용에서는 Node의 이름이 계속해서 변경되기 때문에 자주 사용하지는 않음
- NodeSelector
- Node의 Label(Key, Value)을 지정하여 해당 Node에 할당됨
- 같은 Label을 가진 Node 중에서는 Scheduler에 의해 자원이 많은 Node에 할당
- 매칭이 되는 Label(Node)가 없다면 어떠한 Node에도 할당이 안됨
- NodeAffinity
- NodeSelector를 보완하여 사용할 수 있는 기능
- Node Affinity는 matchExpressions와 Required, Preferred의 옵션을 이용하여 복잡/세부적인 조건 구성 가능
- Node Affinity의 2가지 옵션
- Required : 해당 조건에 반드시 부합하는 Node에만 할당
- Preferred : Required에 비해 유연한 선택이 가능
- 해당 조건에 부합하지 않더라도 preferred Weight(가중치)에 의해 결정
- Preferred Weight : Preferred 옵션에서 조건에 따른 가중치를 부여함
2. Pod간 집중/분산
- Node가 아닌 Pod를 기준으로 할당하는 방법
- Pod Affinity
- 같은 PV 호스트패스를 사용한다면 Master Pod가 최초 할당된 Node에 Slave도 함께 생성
- 다수의 Pod가 네트워크와 같은 리소스 효율을 위해 동일한 Node에 동작하는 것이 효율적일 때 사용
- Anti-Affinity
- Master와 Slave를 서로 다른 Node에 생성
- Pod들이 같이 있으면 해당 Node가 다운될 때, 서비스가 다운될 수도 있는 경우에 사용
3. 특정 Node에 대해 할당 제한
- Toleration/Taint
- 일반적인 경우에는 Node할당을 컨트롤하여, 해당 Node에는 Pod 생성이 되지 않게 함
- Pod가 해당 Node를 직접 지정해도 할당 불가능
- Toleration옵션이 있어야만 할당가능
- GPU와 같이 특별한 하드웨어 옵션을 가진 Node를 이용하는 특정 Pod 배치에 유용하게 사용가능
- Taint / Toleration의 옵션
실습
1. Node Affinity
console에서 각 Node에 Label 설정
# kubectl label nodes "node name" "key=value"
kubectl label nodes k8s-node1 kr=az-1
kubectl label nodes k8s-node2 us=az-1
Match Expressions를 설정하여 Pod 생성
apiVersion: v1
kind: Pod
metadata:
name: pod-match-expressions1
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- {key: kr, operator: Exists}
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
생성된 Pod확인
kr label을 지정한 Node 1에 Pod가 생성됨
key : ch를 지정한 Required 옵션의 Pod 생성
apiVersion: v1
kind: Pod
metadata:
name: pod-required
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- {key: ch, operator: Exists}
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
Pod 생성 확인
시간이 지나도 Pod가 생성되지 않음
Key : ch로 지정했는데 이러한 Key를 가진 Node는 존재하지 않기 때문
Required 옵션은 해당 조건에 부합하는 Node가 존재해야만 할당가능
key : ch를 지정한 Preferred옵션의 Pod 생성
apiVersion: v1
kind: Pod
metadata:
name: pod-preferred
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- {key: ch, operator: Exists}
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
Pod 생성 확인
Required와 다르게 Preferred옵션은 해당 조건에 맞는 Node가 존재하지 않아도 자원의 여유가 큰 Node에 할당
2. Pod Affinity
console에 Node에 Label을 설정
kubectl label nodes k8s-node1 a-team=1
kubectl label nodes k8s-node2 a-team=2
web Pod를 생성
a-team-1에 할당되도록 Node Selector를 이용
apiVersion: v1
kind: Pod
metadata:
name: web1
labels:
type: web1
spec:
nodeSelector:
a-team: '1'
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
Pod 생성 확인
a-team : 1의 label을 가지는 Node1에 생성됨
Affinity Pod인 server1 Pod 생성
Affinity속성의 Pod Affinity를 이용
Topology key를 a-team으로 설정
web1 Pod와 같은 Node에 생성해야하므로 MatchExpresion을 이용
apiVersion: v1
kind: Pod
metadata:
name: server1
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: a-team
labelSelector:
matchExpressions:
- {key: type, operator: In, values: [web1]}
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
생성된 Pod확인
web1와 같은 Node인 Node1에 생성됨
3. Anti-Affinity
Pod Affinity와 동일한 Node Label을 이용하여 진행
kubectl label nodes k8s-node1 a-team=1
kubectl label nodes k8s-node2 a-team=2
Master Pod생성
a-team : 1의 Label을 가지는 Node에 할당되도록 생성
apiVersion: v1
kind: Pod
metadata:
name: master
labels:
type: master
spec:
nodeSelector:
a-team: '1'
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
생성된 Pod 확인
a-team : 1의 label을 가지는 Node1에 생성됨
slave Pod 생성
PodAntiAffinity 속성을 이용하여 생성
topologyKey를 a-team으로 설정
Master와 다른 Node에 생성해야하므로 Master에 대한 MatchExpression을 설정
apiVersion: v1
kind: Pod
metadata:
name: slave
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: a-team
labelSelector:
matchExpressions:
- {key: type, operator: In, values: [master]}
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
4. Taint / Toleration
하나의 Node에 label 설정
kubectl label nodes k8s-node1 gpu=no1
특정 Node에 Taint 설정
kubectl taint nodes k8s-node1 hw=gpu:NoSchedule
Toleraion옵션을 활용하여 Pod 생성
Taint에 지정한 값과 동일하게 Toleration을 설정
apiVersion: v1
kind: Pod
metadata:
name: pod-with-toleration
spec:
nodeSelector:
gpu: no1
tolerations:
- effect: NoSchedule
key: hw
operator: Equal
value: gpu
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
생성된 Pod 확인
지정한 Node1(Taint) 로 Pod가 생성되는 것을 확인
Pod 생성
Toleration 옵션없이 gpu : no1인 Node를 지정하여 생성
apiVersion: v1
kind: Pod
metadata:
name: pod-without-toleration
spec:
nodeSelector:
gpu: no1
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
생성된 Pod 확인
Taint가 있는 Node1에 Toleration으로 조건을 부합하지 못했기 때문에 생성 실패
Toleration옵션에 NoExecute를 설정하여 Pod1 생성
TolerationSec : 30으로 지정
apiVersion: v1
kind: Pod
metadata:
name: pod1-with-no-execute
spec:
tolerations:
- effect: NoExecute
key: out-of-disk
operator: Exists
tolerationSeconds: 30
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
일반적인 Pod2 생성
apiVersion: v1
kind: Pod
metadata:
name: pod2-without-no-execute
spec:
containers:
- name: container
image: kubetm/app
terminationGracePeriodSeconds: 0
생성된 Pod1,2 확인
Pod 1와 2 모두 Node1의 Taint에 대해 부합하지 않기 때문에 Node2에 생성됨
Node 1, Node 2에 Taint 수정 및 설정
Node 1의 Taint옵션인 NoSchedule을 제거
-> 해당 Taint를 가지지 않아도 할당 가능
Node 2의 Taint에 NoExecute를 설정
-> NoExecute 옵션을 설정하여 key와 value에 부합하지 않은 기존 Pod를 제거
kubectl taint nodes k8s-node1 hw=gpu:NoSchedule-
kubectl taint nodes k8s-node2 out-of-disk=True:NoExecute
두 Pod 모두 Node2에서 삭제되고 Node1에 재생성됨
단, TolerationSec : 30을 설정한 Pod1의 경우 Node1에서 30초 뒤에 삭제됨
'CICD' 카테고리의 다른 글
[Kubernetes] Dynamic Provioning, RelcaimPoicy(Volume) (0) | 2022.01.22 |
---|---|
[Kubernetes] Headless, Endpoint, ExternalName(Service) (1) | 2022.01.22 |
[Kubernetes] QoS classes(Pod) (0) | 2022.01.16 |
[Kubernetes] ReadinessProbe, LivenessProbe(Pod) (0) | 2022.01.16 |
[Kubernetes] Lifecycle(Pod) (0) | 2022.01.16 |
댓글