일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- EC2
- Network
- MAC address
- kubectl
- AWS
- Python
- PostgreSQL
- java
- airflow
- Vision
- log
- kubeadm
- kubernetes
- Packet
- tcp
- aws s3
- OS
- JavaScript
- Trino
- CVAT
- CSV
- docker
- Kafka
- zookeeper
- helm
- Spring
- Operating System
- jvm
- ip
- grafana
- Today
- Total
JUST WRITE
특정 Node에 Pod 스케줄링 본문
특정 Node에 Pod 스케줄링
Kubernetes에 Python으로 짠 Process를 여러 개 구동할 업무가 주어졌습니다.
해당 Process는 법인별로 1~3개씩 구동해야되서 다수의 Process를 구동해야 했습니다.
Kubernetes Cluster에서 자체적으로 Node의 상태에 맞게 Pod을 Node에 배치하게 됩니다.
이번 Python Process가 법인 상황에 따라 많은 Resource를 차지할 수 있는 상황이었습니다.
그래서 해당 Process의 Pod이 Node들에 적절하게 분배될 수 있도록 구성해 보았습니다.
affinity를 이용한 스케줄링
첫 번째 시도한 방식은 affinity를 이용한 방식이었습니다.
affinity는 사전적 의미로 선호도라고 합니다.
Label를 통해서 선호도를 설정하여 Node에 Pod를 배치하는 방식입니다.
affinity의 종류는 아래 4가지입니다.
- NodeAffinity
- NodeAntiAffinity
- PodAffinity
- PodAntiAffinity
NodeAffinity, NodeAntiAffinity는 Node Label에 대해서 Pod을 어떻게 배치할지 결정합니다.
PodAffinity, PodAntiAffinity는 Node에 배치된 Pod들의 Label을 체크하여 Pod이 어디에 배치할지 결정합니다.
아래 예시를 보며 살펴보려 합니다.
...
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- consumer-sedam-master
topologyKey: kubernetes.io/hostname # Node의 hostname 정보 기준으로 Pod 배치
...
위 예시에서는 podAntiAffinity를 사용하고 있습니다.
아래 labelSelector에서 지정한 label이 있는 Pod 없는(anti이기 때문에) Node 쪽으로 배치하려고 합니다.
위 예시를 통해서 하나하나 살펴보려 합니다.
Affinity 정책 강제 옵션
위에 보시면 requiredDuringSchedulingIgnoredDuringExecution이 있습니다.
해당 설정은 아래에서 지정한 affinity를 필수로 지킬지 말지를 설정해 주는 부분입니다.
- requiredDuringSchedulingIgnoredDuringExecution
- preferredDuringSchedulingIgnoredDuringExecution
requeird로 반드시 아래 지정할 Affinity를 지켜서 Pod을 배치하게 됩니다.
만약 required로 세팅하고 Affinity Rule 못 지킬 상황에 Pod이 생성된다면 pending상태로 됩니다.
preferred는 반드시는 아니며 Affinity Rule을 못 지킬 상황이어도 Pod을 정상적으로 배치됩니다.
Operator
그리고 주목할 부분이 Operator입니다.
Operator에 따라 어떤 Rule로 Pod이 배치될지 정해지게 됩니다.
- In -> Label 중 하나라도 일치하면 적용
- NotIn -> Label 중 하나라도 일치하면 적용 X
- Exists -> 모든 key가 존재하면 적용, Label의 key만 설정
- DoesNotExists -> 모든 key가 존재하면 적용 X, Label의 key만 설정
- Gt -> greater than, Label의 value가 정수값이어야 함. value보다 큰 값일 때 적용
- Lt -> less than, Label의 value가 정수값이어야 함. value보다 작은 값일때 적용
위 6가지 Rule로 적용할 수 있으며, 상황에 맞게 적절하게 배치하면 됩니다.
아래는 Exists의 예시입니다.
신경 써야 할 부분은 values가 들어가면 안 됩니다.
...
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: key1
key: key2
key: key3
operator: Exists
#values: -> Exists, NotExists에서는 values 사용 안함.
topologyKey: kubernetes.io/hostname
...
아래는 Gt의 예시입니다.
신경 써야 할 부분은 values가 정수이어야 합니다.
...
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: key1
values: ["100"] # value가 정수어야 한다.
operator Gt
topologyKey: kubernetes.io/hostname
...
Topology Spread
affinity를 사용하는 방법도 있지만 Topology Spread를 활용한 방법이 있었습니다.
affinity만큼 디테일하게 Rule을 못 정하지만 현 상황에서 간편하게 쓸 수 있어 해당 방식으로 변경하였습니다.
Kubernetes Cluster 전체적으로 고르게 분포하게 쓸 때 유용한 방식입니다.
apiVersion: v1
kind: Pod
metadata:
name: example-pod
mathc-type: type1
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
mathc-type: type1
maxSkew
Pod가 균등하게 분배되지 않게 허용하는 정도를 나타냅니다.
maxSkew가 2라면 Node에 배치될 수 있는 해당 Pod의 개수가 2개까지 가능한다는 의미입니다.
whenUnsatisfiable
조건을 만족하지 않았을 때 Pod을 어떻게 처리할지 설정하는 부분입니다.
- DoNotSchdule -> 만족하지 않으면 Pod이 Pending 상태로 둠.
- ScheduleAnyway -> 만족하지 않아도 Pod을 정상적으로 구동
Affinity에서 requiredDuringSchedulingIgnoredDuringExecution, prferredDuringSchedulingIgnoredDuringExecution 설정과 비슷하다.
[참고사이트]
'MLOps > Kubernetes' 카테고리의 다른 글
명령어 한 번에 Kubernetes 설치하기 - Terraform으로 Kubernetes 설치 (4) | 2023.05.23 |
---|---|
Kubernetes에 CVAT 설치하기 - Helm으로 CVAT 설치 (8) | 2023.05.05 |
Kubernets Cluster에 Worker Node 추가 (0) | 2023.02.18 |
CoreDNS 설정 - Host 강제로 넣기 (0) | 2023.02.12 |
Master Node HA 구성(2) - HAProxy 세팅 (0) | 2023.02.02 |