Kubernetes를 운영하다보면, 특정 워커에는 배포가 되지 않도록 하고 싶은 경우가 있다.
예를 들어, 딥러닝 어플리케이션들이 배포되는 클러스터에 일부 워커에만 GPU가 붙어있을 때 GPU가 필요 없는 어플리케이션들은 해당 워커들에 배포가 되지 않도록 막고 싶은 경우이다.
Taint는 일반적으로 Label을 형성하는 것이다.
Toleration은 용인이라는 뜻으로 Pod에 설정한다.
-> 즉, Taint와 Toleration은 함께 이해하고 사용해야 한다.
위의 그림을 보면, 앞 2개의 Node에 taint로 설정 값을 준 것을 알 수 있다.
이렇게 되면, 일반적으로 Pod 생성시에는 해당 앞의 2개의 Node에는 배치될 수 없다.
하지만, 만약 Pod 생성 조건으로 Node에 Taint 값 positon=low과 동일한 toleration값을 주면 앞의 2개의 Node에도 배치가 가능하게 된다.
Taint는 Label 및 Annotation과 비슷하게 Key=Value 형식을 가지지만 추가적으로 effect라는 파라미터를 가질 수 있다.
예시 Key=Value:Effect
kubectl taint nodes [노드이름] app=backend:NoSchedule
kubectl taint nodes [노드이름] app=backend:NoExecute
kubectl taint nodes [노드이름] app=backend:PreferNoSchedule
Toleration은 Pod spec의 'tolerations' 필드에 명시된다.
모든 종류의 Taint를 용인하는 경우
tolerations:
- operator: Exists
tolerations:
- key: app
operator: Exists
tolerations:
- key: app
operator: Exists
effect: NoExecute
tolerations:
- key: app
operator: Equal
value: backend
effect: NoSchedule
시나리오 별 Pod 스케쥴링을 진행해보자.
Taint와 Tolerations는 Pod의 spec에 직접 정의되며, 해당 Pod를 생성 또는 업데이트 할 때 적용된다.
Node Affinity는 Pod가 특정 Node에 예약되도록 지정하는 규칙을 정의한다.
기존 Pod 수정하고 싶지 않고, Node에 Taint 만 추가해서 특정 Node 에 특정 Pod의 배포를 거부하고 싶은 경우
kubectl taint nodes ptty-nodepool-w-2rpr app=backend:NoSchedule
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에 Node가 속한 AZ를 지정하는 label을 주고, Node affinity rules를 통해 우선순위를 지정하고 싶은 경우
해결 방안 : Node Affinity에 'preferredDuringSchedulingIgnoredDuringExecution' 필드를 지정
그럼 이제 실습 해보자.
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는 Pod의 스케줄링을 특정 노드 혹은 노드 그룹에 지정하는데 사용된다.
Node Affinity는 일치 조건을 기반으로 작동한다.
예시) 클러스터에 많은 노드가 있는 경우, Pod 스케줄링 시 노드는 2^3개의 그룹으로 분할된다. 이 그룹은 노드의 라벨을 기반으로 구성된다. (만약 라벨이 n개라면 2^n개의 그룹으로 분할된다)