Pod Scheduling
Kubernetes를 운영하다보면, 특정 워커에는 배포가 되지 않도록 하고 싶은 경우가 있다.
예를 들어, 딥러닝 어플리케이션들이 배포되는 클러스터에 일부 워커에만 GPU가 붙어있을 때 GPU가 필요 없는 어플리케이션들은 해당 워커들에 배포가 되지 않도록 막고 싶은 경우이다.
Taint 와 Toleration 이 무엇인가?
- Taint는 일반적으로 Label을 형성하는 것이다.
- Node에 Taint를 설정하여 임의의 Pod가 할당되는 것을 방지한다.
- Toleration은 용인이라는 뜻으로 Pod에 설정한다.
- 특정 Taint를 용인할 수 있는 Toleration 설정을 가진 Pod는 해당 Node에 할당 가능하다.
- Taint는 Label 및 Annotation과 비슷하게 Key=Value 형식을 가지지만 추가적으로 effect라는 파라미터를 가질 수 있다.
- 예시 Key=Value:Effect
- Taint가 Node에 설정될 때 어떤 효과를 가지게 될지 설정하는 것이다.
1. NoSchedule
- Taint Node에 Pod의 스케줄링을 허용하지 않는 것을 의미
- 기존에 실행중인 Pod는 영향을 받지 않고 새로운 Pod를 할당받지 않는 것
예시 ) 특정 노드에만 특정한 하드웨어 장비가 있어야 하는 경우나 특정한 네트워크 환경을 가져야하는 경우 사용될 수 있다.
kubectl taint nodes [노드이름] app=backend:NoSchedule
2. NoExecute
- Taint Node에 Pod의 실행을 허용하지 않는 것을 의미
- 해당 Node에 새로운 Pod를 할당하지 않을 뿐만 아니라, 기존에 해당 Node에 배치된 모든 Pod들을 방출시키는 것
예시 ) 노드에 하드웨어 장애가 발생했거나 유지보수를 위해 노드를 오프라인으로 전환해야 하는 경우 사용 될 수 있다.
kubectl taint nodes [노드이름] app=backend:NoExecute
3. PreferNoSchedule
- Taint Node에 Pod의 스케줄링을 선호하지 않는 것을 의미
- 해당 Node에 새로운 Pod를 할당하는 것을 선호하지 않지만, 노드 밖에 스케줄링 될 수 있는 대안이 없을 경우에는 해당 노드에 Pod 할당 가능
- 클러스터 내에서 자원 활용을 최대화하기 위한 방법
kubectl taint nodes [노드이름] app=backend:PreferNoSchedule
위의 모든 예시코드는 taint 값을 app=backend를 예시로 넣었다.
- Taint가 Node에 설정될 때 어떤 효과를 가지게 될지 설정하는 것이다.
- Toleration (용인 규칙)을 사용하여 Pod가 특정 Taint를 용인하도록 설정할 수 있다.
- Effect
- 위의 그림을 보면, 앞 2개의 Node에 taint로 설정 값을 준 것을 알 수 있다.
이렇게 되면, 일반적으로 Pod 생성시에는 해당 앞의 2개의 Node에는 배치될 수 없다.
하지만, 만약 Pod 생성 조건으로 Node에 Taint 값 positon=low과 동일한 toleration값을 주면 앞의 2개의 Node에도 배치가 가능하게 된다. - Toleration은 Pod spec의 'tolerations' 필드에 명시된다.
- 모든 종류의 Taint를 용인하는 경우
tolerations:
- operator: Exists
- 키가 app인 모든 Taint를 용인하는 경우
tolerations:
- key: app
operator: Exists
- 키가 app이고 effect가 NoExercute인 모든 Taint를 용인하는 경우
tolerations:
- key: app
operator: Exists
effect: NoExecute
- app=backend:NoSchedule Taint를 용인하는 경우
tolerations:
- key: app
operator: Equal
value: backend
effect: NoSchedule
Pod Scheduling 실습
시나리오 별 Pod 스케쥴링을 진행해보자.
Taint와 Tolerations
Taint와 Tolerations는 Pod의 spec에 직접 정의되며, 해당 Pod를 생성 또는 업데이트 할 때 적용된다.
- Pod를 생성 또는 업데이트 할때 Pod의 spec에 Tolerations을 추가하면, 해당 Pod는 Tolerations에 지정된 조건에 따라 스케줄링된다.
- Node에 Taint가 존재하더라도, Pod의 Tolerations 설정을 통해 Taint를 용인하는 경우에만 해당 Node에 배포된다.
- 따라서, Pod의 Yaml파일에서 Tolerations를 설정하면 된다.
Node Affinity
Node Affinity는 Pod가 특정 Node에 예약되도록 지정하는 규칙을 정의한다.
- Pod는 자신이 선호하는 Node에 대한 조건을 지정하여 해당 Node에 스케줄링 되도록 할 수 있다.
- Node Affinit는 Pod의 spec에 추가되며, 특정 노드에 대한 선호 조건을 지정한다.
기존 Pod 수정하고 싶지 않고, Node에 Taint 만 추가해서 특정 Node 에 특정 Pod의 배포를 거부하고 싶은 경우
Taint와 Tolerations를 이용하여 실습
- 배포를 거부하고자 하는 Node에 Taint를 추가한다.
kubectl taint nodes ptty-nodepool-w-2rpr app=backend:NoSchedule
- 해당 Taint를 용인하는 Tolerations을 Pod의 spec에 추가해야 한다.
Pod의 YAML파일에서 'spec'섹션 내에 'tolerations'필드를 추가하고, Tolerations를 지정한다.
tolerations:
- key: app
operator: Equal
value: backend
effect: NoSchedule
- 이제 해당 Pod를 배고파거나 업데이트하면, 이제 그 Pod는 'ptty-nodepool-w-2rpr' Node에 배포되지 않고 다른 Node에 배포된다.
- 실제 배포해서 확인해보자.
kubectl apply -f php-apache.yaml
현재 php-apache pod가 ptty-nodepool-w-2q4v node에 배포된 것을 확인 할 수 있다.
Node affinity를 이용해 Pod를 특정 node에 예약하기
각 Node에 Node가 속한 AZ를 지정하는 label을 주고, Node affinity rules를 통해 우선순위를 지정하고 싶은 경우
해결 방안 : Node Affinity에 'preferredDuringSchedulingIgnoredDuringExecution' 필드를 지정
그럼 이제 실습 해보자.
- 노드에 라벨을 지정한다.
kubectl label node <node_name> <label_key>=<label_value> 명령을 사용하여 원하는 기준에 따라 노드에 라벨을 지정합니다. 예를 들어, 가용성 영역으로 노드를 라벨링할 수 있다.
kubectl label node ptty-nodepool-w-2rpr availability-zone=zone1
kubectl label node ptty-nodepool-w-2rpr availability-zone2=zone2
kubectl label node ptty-nodepool-w-2rpr availability-zone3=zone3
'ptty-nodepool-w-2rpr' node에 availiability-zone=zone1으로 라벨을 지정했다.
파드를 생성할 Deployment YAML파일을 만들어 업데이트 한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache2
spec:
selector:
matchLabels:
app: php-apache
replicas: 3
template:
metadata:
labels:
app: php-apache
spec:
containers:
- name: php-apache
image: php:7.4-apache
ports:
- containerPort: 80
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 50
preference:
matchExpressions:
- key: availability-zone
operator: In
values:
- zone1
- weight: 30
preference:
matchExpressions:
- key: availability-zone2
operator: In
values:
- zone2
- weight: 20
preference:
matchExpressions:
- key: availability-zone3
operator: In
values:
- zone3
가중치에 자세히 알고 싶다면 weight 에 들어가서 읽어보자.
Node affinity가 작동하는 방식
Node Affinity는 Pod의 스케줄링을 특정 노드 혹은 노드 그룹에 지정하는데 사용된다.
Node Affinity는 일치 조건을 기반으로 작동한다.
- 필수(Mandatory) : 필수 일치 그룹에 속한 노드는 노드 그룹에만 Pod를 스케줄링한다. 일치하지 않는경우 Pod는 스케줄링되지 않는다.
- 선호(Preferred) : 선호 일치 그룹에 속한 노드 노드 그룹에 우선적으로 Pod를 스케줄링한다. 그러나 일치하지 않는 다른 그룹에서도 스케줄링이 가능하다.
- 필수가 아닌(RequiredDuringSchedulingIgnoredDuringExecution) : 일치 그룹에 속하지 않는 노드 또는 노드 그룹에만 Pod를 스케줄링 한다. 그러나 이미 해당 노드에 실행 중인 Pod는 영향을 받지 않는다.
예시) 클러스터에 많은 노드가 있는 경우, Pod 스케줄링 시 노드는 2^3개의 그룹으로 분할된다. 이 그룹은 노드의 라벨을 기반으로 구성된다. (만약 라벨이 n개라면 2^n개의 그룹으로 분할된다)
'Kubernetes' 카테고리의 다른 글
[CKA] Mock Exam - 1 (0) | 2023.09.06 |
---|---|
[Kubernetes] HPA Monitoring with Prometheus (0) | 2023.08.11 |
[Kubernetes] Pod CPU / Memory resource 최적화하기 (0) | 2023.08.11 |
[Kubernetes] VPA를 사용하여 Pod의 Autoscaling 해보자 (0) | 2023.08.10 |
[Kubernetes] Pod 와 Cluster Nodes 를 Auto scaling (0) | 2023.08.10 |