K8s는 Pod를 어떤 노드에서 실행할지에 대한 다양한 옵션이 있고 아래 4가지 방식을 지원합니다.
- Node Selector
- Node Affinity & pod Affinity pod antiAffinity
- node taint & pod toleration
- cordon & drain
Node Selector?
- Pod가 클러스터 안 어떤 노드에서 실행될지를 Label을 이용하여 지정하는 방식
Node Selector 테스트
apiVersion: v1
kind: Pod
metadata:
labels:
run: webserver
name: webserver
spec:
containers:
- image: nginx
name: webserver
ports:
- containerPort: 80
nodeSelector:
cpu: "2core_over"

- # kubectl label node w{1,2}-k8s cpu=2core_over
- node 1, 2에 label 추가

- cpu label이 지정된 노드에서만 pod가 실행됨을 확인 할 수 있다.
Node Affinity & antiAffinity?
- Node Node Affinity
- 특정 노드에서만 Pod가 실행되도록 하는 기능
- Node Selector와 유사하지만 아래의 두가지 요구조건이 만족하는 Pod에만 스케줄링 하도록 지정 할 수 있습니다
- requiredDuringSchedulingIgnoredDuringExecution
- 스케줄링하는 동안 꼭 필요한 조건
- preferedDuringSchedulingIgnoredDuringExecution
- 스케줄링하는 동안 만족하면 좋은 조건
- requiredDuringSchedulingIgnoredDuringExecution
- Pod Affinity
- Pod들을 더 가깝게 배치하는 방법
- Pod AntiAffinity
- Pod들을 분산 배치하는 방법
Node Affinity 테스트
apiVersion: v1
kind: Pod
metadata:
name: nginx-gpu-ssd
spec:
containers:
- name: webserver
image: nginx:1.15
ports:
- containerPort: 8888
protocol: TCP
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- {key: disktype, operator: Exists}
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 10
preference:
matchExpressions:
- {key: gpu, operator: In, values: ["true"]}
- {key: disktype, operator: In, values: ["ssd"]}

- w1-k8s 노드에 gpu=true cpu=2core disktype=ssd 레이블 추가

- requiredDuringSchedulingIgnoredDuringExecution 설정에 의해서 disktype label이 존재하는 레이블 중에서 gpu가 true disktype이 ssd인 w1-k8s node가 스케줄링 되는것을 확인 할 수 있다
- w1-k8s 가중치: 20
- w2-k8s disktype 레이블이 없으므로 해당사항없음
- w3-k8s 가중치: 10
Pod Affinity 테스트
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 5
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: backend
topologyKey: kubernetes.io/hostname
containers:
- name: main
image: busybox
args:
- sleep
- "100000"

- backend pod가 실행중인 w3-k8s node에서 frontend pod가 실행됨을 확인 할 수 있다
Pod AntiAffinity 테스트
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 5
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: backend
topologyKey: kubernetes.io/hostname
containers:
- name: main
image: busybox
args:
- sleep
- "100000"
- topologyKey
- 노드 label을 이용해 pod의 affinity와 antiaffinity를 설정할 수 있는 또 하나의 기준
- K8s는 Pod를 스케줄링 할 때 먼저 Pod의 label을 기준으로 대상 노드를 찾고, topology 필드를 확인하여 해당 노드가 원하는 노드인지 확인한다.

- backend pod가 실행중인 w1-k8s node에서 frontend pod가 실행되지 않음을 확인 할 수 있다
node taint & pod toleration
- node taint
- 특정 Node에 taint를 설정하여 설정한 Node에는 Pod를 스케줄링 하지 않도록 할 수 있음.
- master node인 m-k8s에는 taint NoSchedule가 설정돼 있어 해당 Node는 스케줄링을 받지 않도록 설정되어 있다
- toleration
- taint를 설정한 Node에 Pod를 스케줄링하려면 toleration을 설정해아 함
- toleration이 있는 Pod는 동일한 taint가 있는 node를 포함하여 tain가 설정돼있지 않은 모든 node에 배치된다
- 특정 Node에 taint를 설정하여 설정한 Node에는 Pod를 스케줄링 하지 않도록 할 수 있음.
node taint & pod toleration 테스트
1. taint 설정되지 않는 node에만 pod 배치여부확인
apiVersion: apps/v1
kind: Deployment
metadata:
name: weserver
spec:
replicas: 4
selector:
matchLabels:
app: webserver
template:
metadata:
name: nginx-pod
labels:
app: webserver
spec:
containers:
- name: nginx-container
image: nginx

- # kubectl taint nodes w3-k8s key01=value01:NoSchedule
- w3-k8s Node에 taint 설정
- 형식: kebectl taint nodes 노드이름 키=값:효과
- taint가 설정된 m-k8s ,w3-k8s Node에는 pod가 할당되지 않음을 확인 할 수 있다
2. Pod에 toleration 설정하여(taint가 동일한 Node는 없음) Node에 Pod 배치여부 확인
apiVersion: apps/v1
kind: Deployment
metadata:
name: weserver
spec:
replicas: 4
selector:
matchLabels:
app: webserver
template:
metadata:
name: nginx-pod
labels:
app: webserver
spec:
containers:
- name: nginx-container
image: nginx
tolerations:
- key: "role"
operator: "Equal"
value: "web"
effect: "NoSchedule"

- Taint가 설정돼있지 않은 w1-k8s, w2-k8s에만 pod가 스케줄링됨을 알 수 있다
3. Pod에 toleration 설정하여(taint가 동일한 Node는 있음) Node에 Pod 배치여부 확인
apiVersion: apps/v1
kind: Deployment
metadata:
name: weserver
spec:
replicas: 4
selector:
matchLabels:
app: webserver
template:
metadata:
name: nginx-pod
labels:
app: webserver
spec:
containers:
- name: nginx-container
image: nginx
tolerations:
- key: "role"
operator: "Equal"
value: "web"
effect: "NoSchedule"

- # kubectl taint node w1-k8s role=web:NoSchedule
- w1-k8s Node에 taint 설정
- taint와 tolerations이 일치하는 w1-k8s Node에 Pod가 스케줄링 됨을 확인 할 수 있다.
- 또한 taint가 설정되지 않은 w2-k8s에 Pod에도 스케줄링 된다
4. Node에 전부 taint가 설정되어 있고 pod tolerations 설정이 맞지 않는다면?
apiVersion: apps/v1
kind: Deployment
metadata:
name: weserver
spec:
replicas: 4
selector:
matchLabels:
app: webserver
template:
metadata:
name: nginx-pod
labels:
app: webserver
spec:
containers:
- name: nginx-container
image: nginx
tolerations:
- key: "role"
operator: "Equal"
value: "web"
effect: "NoSchedule"

- 모든 Node에 taint가 설정되어 있고 Pod tolerations 설정이 맞지 않는 경우 pod는 pending 상태가 된다.
cordon & drain?
- 특정 Node에 있는 Pod들을 모두 다른 노드로 옮기거나 특정 Node에 Pod들을 스케줄링하지 않도록 제한하는 기능
- cordon
- 특정 노드에 Pod 스케줄링 금지
- uncordon
- 특정 노드에 Pod 스케줄링 해제
- drain
- 특정 노드에서 동작중인 모든 Pod를 제거
- kubectl drain Node [option]
- option
- --ignore-deamonsets
- DaemonSet이 관리하는 Pod들은 ignore
- --force
- RC, RS, Job, DaemonSet 또는 StatefulSet에서 관리하지 않는 Pod 제거
- --ignore-deamonsets
- option
- kubectl drain Node [option]
- 특정 노드에서 동작중인 모든 Pod를 제거
cordon & uncordon 테스트
apiVersion: apps/v1
kind: Deployment
metadata:
name: weserver
spec:
replicas: 4
selector:
matchLabels:
app: webserver
template:
metadata:
name: nginx-pod
labels:
app: webserver
spec:
containers:
- name: nginx-container
image: nginx

- # kubectl cordon w1-k8s
- w1-k8s Node를 cordon 설정
- w1-k8s Node에 pod가 할당되지 않음을 확인 할 수 있다
- # kubectl uncordon w1-k8s
- cordon 해제
drain 테스트
apiVersion: apps/v1
kind: Deployment
metadata:
name: weserver
spec:
replicas: 4
selector:
matchLabels:
app: webserver
template:
metadata:
name: nginx-pod
labels:
app: webserver
spec:
containers:
- name: nginx-container
image: nginx

- w3-k8s Node에서 Controller에 의해서 관리되지 않는 db pod와 deployment에 의해서 관리되는 webserver pod가 실행중이다.
- # kubectl drain w3-k8s --ignore-daemonsets --force
- Controller에 의해서 관리되지 않는 db pod는 삭제되고 deployment의 관리를 받는 webserver pod는 다른 Node에서 실행됨을 확인 할 수 있다.
- w3-k8s Node는 cordon을 했을때와 동일하게 상태가 SchedulingDisabled인것을 확인 할 수 있다.
- static Pod는 삭제되지 않습니다.
'클라우드 > K8s' 카테고리의 다른 글
| K8s volume (0) | 2022.04.03 |
|---|---|
| K8s 인증과 권한관리 (0) | 2022.04.03 |
| K8s Secret (0) | 2022.03.31 |
| K8s Configmap (0) | 2022.03.31 |
| K8s 버전 업그레이드 (0) | 2022.03.18 |