# 12장 파드 스케줄링
Assembled by GimunLee
# 파드 스케줄링
- 특정 파드들을 노드 하나에 모아두거나 특정 IP 대역의 노드들에서만 실행
- 같은 기능이 있는 파드들이 노드 하나에 몰려있지 않도록 분산 실행
- 관리가 필요한 노드가 있을때 해당 노드에 있는 파드들을 다른 노드로 이동
# 노드셀렉터
- 가장 간단한 스케줄링 옵션을
.spec
필드에 설정 가능한 노드셀렉터가 있음 - 파드가 클러스터 안 어떤 노드에서 실행될지를 키-값 쌍으로 설정
- 노드셀렉터는 노드의 레이블에 설정된 값으로 노드를 선택
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-nodeselector-pod
spec:
containers:
- name: kubernetes-nodeselector-pod
image: arisu1000/simple-container-app:latest
ports:
- containerPort: 8080
nodeSelector:
disktype: ssd # disktype이 ssd인 노드에 실행 가능
# 어피니티와 안티 어피니티
- 파드들을 함께 묶어서 같은 노드에서 실행하도록 설정하는 어피니티와 파드들을 다른 노드에 나누어서 실행하도록 설정하는 안티 어피니티
# 노드 어피니티(Node affinity)
- 노드 어피니티는 노드셀렉터와 비슷하게 노드의 레이블 기반으로 파드를 스케줄링
- 노드 어피니티와 노드셀렉터를 함께 설정할 수 있으며 이때는 노드 어피니티와 노드셀렉터의 조건을 모두. 만족하는 노드에 파드를 스케줄링
requiredDuringSchedulingIgnoredDuringExecution
,preferredDuringSchedulingIgnoredDuringExecution
두 필드는 실행 중에 조건이 바뀌어도 무시; 파드가 이미 스케줄링되어 특정 노드에서 실행 중이라면 중간에 해당 노드의 조건이 변경되더라도 이미 실행 중인 파드는 그대로 실행된다는 뜻
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-nodeaffinity-pod
spec:
containers:
- name: kubernetes-nodeaffinity-pod
image: arisu1000/simple-container-app:latest
ports:
- containerPort: 8080
affinity: # 어피니티 설정
nodeAffinity: # 노드 어피니티
requiredDuringSchedulingIgnoredDuringExecution: # 스케줄링하는 동안 꼭 필요한 조건
nodeSelectorTerms: # 노드 어피니티 유형
- matchExpressions: # 연관된 노드셀렉터 설정을 연결하는 필드
- key: beta.kubernetes.io/os # 노드의 레이블 키 중 하나를 설정
operator: In # 키가 만족할 조건
# In: .values[] 필드에 설정한 값 중 레입ㄹ에 있는 값과 일치하는 것이 하나라도 있는지 확인
# NotIn: In과 반대로 .values[] 필드에 있는 값 모두와 맞지 않는지 확인
# Exists: .values[] 필드가 필요 없고 .key 필드에 설정한 값이 레이블에 있는지만 확인
# DoesNotExist: Exists와 반대
# Gt: Greater than으로 .values[] 필드에 설정된 값보다 큰 숫자형 데이터인지를 확인. values에 값이 하나만 있어야함
# Lt: Lower than으로 Gt와 반대
values:
- linux
- window
- key: disktype
operator: Exists
# - key: core
# operator: Gt
# values:
# - "4"
preferredDuringSchedulingIgnoredDuringExecution: # 필수는 아니지만 스케줄링하는 동안 만족하면 좋은 조건
- weight: 10 # 1부터 100까지의 값 설정 가능; 노드의 설정이 맞을 때 마다 .weight 필드 값을 더하고, .weight 합산이 가장 큰 노드를 선택
preference: # 해당 조건에 맞는 걸 선호
matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- worker-node01
# 파드의 어피니티와 안티 어피니티
- 파드 사이의 어피니티와 안티 어피니티는 디플로이먼트나 스테이트풀세트로 파드를 배포했을 때 개별 파드 사이의 관계를 정의하는 용도로 사용
# 어피니티
- 컨테이너로 서비스를 운영하다 보면 서비스 A의 파드와 서비스 B의 파드 사이에 자주 통신할 때가 있는데, 이때 이 두 파드를 같은 노드에 속하게 만들어 효율을 높임
- 가장 흔한 예로 데이터베이스나 캐시 같은 서비스와 통신하는 앱 컨테이너를 같은 노드에 두어 네트워크 통신 비용을 줄이는 것
# 안티 어피니티
- CPU나 네트워크 같은 하드웨어 자원을 많이 사용하는 앱 컨테이너가 있을 때 여러 노드로 파드를 분산하는 것
- 안티 어피니티를 설정하지 않으면 디플로이먼트로 배포한 파드가 노드 하나에서만 실행되어 자원을 많이 소모할 수 있음
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
replicas: 2
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store # app 필드 값이 store인 파드가 속한 노드를 피해서 파드를 추가한다는 설정
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
image: redis:3.2-alpine
# 테인트와 톨러레이션
- 쿠버네티스 클러스터의 특정 노드에 테인트를 설정할 수 있는데, 테인트를 설정하면 설정한 노드에는 파드들을 스케줄링하지 않음
- 테인트를 설정한 노드에 파드들을 스케줄링하기 위해서는 톨러레이션을 설정해야함
- 테인트는 톨러레이션에서 설정한 특정 파드들만 실행하고 다른 파드는 실행하지 못하게 함
- 테인트와 톨러레이션은 주로 노드를 특정 역할만 하도록 만들 때 사용
- 예를 들어 데이터베이스용 파드를 실행한 후 노드 전체의 CPU나 RAM 자원을 독점해서 사용할 수 있도록 설정하는 것
- 테인트는 키, 값, 효과의 세 가지로 구성됨.
kubectl taint nodes {노드이름} {키=값:효과}
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-simple-app
labels:
app: kubernetes-simple-app
spec:
replicas: 1
selector:
matchLabels:
app: kubernetes-simple-app
template:
metadata:
labels:
app: kubernetes-simple-app
spec:
containers:
- name: kubernetes-simple-app
image: arisu1000/simple-container-app:latest
ports:
- containerPort: 8080
tolerations: # 테인트가 설정된 노드에 실행시키기 위한 톨러레이션 설정
- key: "key01"
operator: "Equal"
value: "value01"
effect: "NoSchedule"
# NoSchedule: 톨러레이션 설정이 없으면 파드를 스케줄링하지 않음. 기존에 실행되던 파드에는 적용되지 않음
# PreferNoSchedule: 톨러레이션 설정이 없으면 파드를 스케줄링하지 않음. 하지만 자원이 부족하면 스케줄링 가능
# NoExecute: 톨러레이션 설정이 없으면 새로운 파드를 스케줄링하지 않음. 기존 파드도 테인트 설정을 무시할수 있는 톨러레이션 설정이 없으면 종료
# 클러스터를 관리하는 커든과 드레인
쿠버네티스를 사용하다 보면 특정 노드에 있는 파드들을 모두 다른 노드로 옮기거나 특정 노드에 파드들을 스케줄링하지 않도록 제한할 필요 존재
커든(cordon): 지정된 노드에 추가로 파드를 스케줄링해서 실행하지 않도록 함
드레인(drain)
- 노드 관리 등의 이유로 지정된 노드에 있는 파드들을 다른 노드로 이동시키는 명령
- 노드에 데몬세트로 실행한 파드들이 있으면 데몬세트로 실행한 파드들은 삭제해도 데몬세트가 즉시 재실행시키기 때문에 드레인 설정을 적용할 수 없음
# Referenses
- 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리 자동화 표준 / 동양북스