Pod Scheduling
NodeSelector
nodeSelector
๋ node ์ ํ ์ฌํญ์ ๊ฐ์ฅ ๊ฐ๋จํ๋ฉด์๋ ์ถ์ฒํ๋ ํํ.
pod spec์nodeSelector
ํ๋๋ฅผ ์ถ๊ฐํ๊ณ , ํ๊ฒ์ผ๋ก ์ผ๊ณ ์ถ์ node๊ฐ ๊ฐ๊ณ ์๋ lable์ ๋ช ์.
kubernetes๋ ์ฌ์ฉ์๊ฐ ๋ช ์ํ label์ node์๋ง pod๋ฅผ ์ค์ผ์ค๋งํ๋ค.
#ํ
์ํ๋ก์ด๊ฐ์ ๋จธ์ ๋ฌ๋ ์ปจํ
์ด๋๋ gpu๊ฐ ํ์์ธ๋ฐ,
#node์ค์ label gpu:true์ธ ๊ณณ์์ ์คํํ๊ฒ ๋ง๋ค ์ ์๋ค.
cat tensorflow-gpu.yaml
apiVersion: v1
kind: Pod
metadata:
name: tensorflow-gpu
spec:
containers:
- name: tensorflow
image: tensorflow/tensorflow:nightly-jupyter
ports:
- containerPort: 8888
protocol: TCP
nodeSelector:
gpu: "true"
Affinity & antiAffinity
Affinity(์ ํธ) & antiAffinity(๋น ์ ํธ)node์ ์ ์ฉํ ์๋ ์๊ณ pod์ ์ ์ฉํ ์๋ ์๋ค.
์๊ฒฉํ์๊ตฌ(required~~), ์ ํธ๋(preferred~~)(๊ฐ์ค์น)์๊ตฌ ์ค์ ๊ฐ๋ฅ.
topologyKey : kubernetes๋ pod๋ฅผ ์ค์ผ์ฅด๋ง ํ ๋ ๋จผ์ pod์ label์ ๊ธฐ์ค์ผ๋ก ๋์๋ ธ๋๋ฅผ ์ฐพ๊ณ , ์ดํ topologyKey ํ๋๋ฅผ ํ์ธํด ์ํ๋ ๋ ธ๋์ธ์ง ํ์ธ
#node affinity
cat tensorflow-gpu-ssd.yaml
apiVersion: v1
kind: Pod
metadata:
name: tensorflow-gpu-ssd
spec:
containers:
- name: tensorflow
image: tensorflow/tensorflow:nightly-jupyter
ports:
- containerPort: 8888
protocol: TCP
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- {key: disk, operator: Exists} #<--- disk type์ด ์๋ ๊ณณ์์๋ง ์คํ์์ผ์ค
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 10
preference:
matchExpressions:
- {key: gpu, operator: In, values: ["true"]} #<-- gpu๊ฐ true์ธ ๊ณณ์์ 10์ ํ ๋น
- {key: disk, operator: In, values: ["ssd"]} #<-- disk๊ฐ ssd์ธ ๊ณณ์์ 10์ ํ ๋น
#pod-affinity ํ
์คํธ
kubectl run backend -l app=backend --image=busybox -- sleep 9999999
# -->node2์ ์คํ๋์๋๋ฐ
cat > pod-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 5
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
affinity:
podAffinity: #โ require์ด๊ธฐ๋๋ฌธ์, pod label์ด backend๊ฐ ์๋ node์์ ์คํ๋๋ค
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: backend
topologyKey: kubernetes.io/hostname
containers:
- name: main
image: busybox
args:
- sleep
- "99999"
kubectl create -f pod-affinity.yaml
# --> replicas๊ฐ 5๋ ๋์ง๋ง ๋ชจ๋ node2์์ ์คํ๋์๋ค.
taint & toleration
๊ฐ์ผ, ๊ด์ฉ
taint์ toleration์ ํจ๊ป ์๋ํ์ฌ pod๊ฐ ๋ถ์ ์ ํ node์ ์ค์ผ์ค๋์ง ์๊ฒ ํ๋ค
node์ NoSchedule์ด๋ผ๋ taint๋ฅผ ์ค์ ํ๊ฒ ๋๋ฉด, ํด๋น node์ pod๊ฐ ๋ฐฐ์น๋์ง ์๋๋ค.
#๋
ธ๋1์ taint ์ค์
kubectl taint nodes node1.example.com role=web:NoSchedule
kubectl describe nodes node{1,2}.example.com | grep -i taint
Taints: role=web:NoSchedule
Taints: <none>
cat deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webui
spec:
replicas: 4
selector:
matchLabels:
app: webui
template:
metadata:
name: nginx-pod
labels:
app: webui
spec:
containers:
- name: nginx-container
image: nginx:1.14
# tolerations:
# - key: "role"
# operator: "Equal"
# value: "web"
# effect: "NoSchedule"
kubectl apply -f deploy-nginx.yaml
# --> taint๊ฐ ์๋ node2์๋ง pod๊ฐ ์์ฑ๋์๋ค.
# ์์ deploy-nginx.yaml์์ ์ฃผ์์ ์ญ์ ํ์ฌ toleration์ ์ค์ ๋ ๋ํ๋ก์ด๋ฅผ ์คํํ๋ฉด
# node1์๋ ๋ค์ด๊ฐ๊ณ , node2์๋ ๋ค์ด๊ฐ๋ค
# toleration์ด ์์ผ๋ฉด, key๊ฐ ๋ง๋ taint ๋
ธ๋์๋ ๋ค์ด๊ฐ๊ณ , taint๋
ธ๋๊ฐ ์๋ ๊ณณ์๋ ๋ค์ด๊ฐ๋ค.
#taint ์ญ์
kubectl taint nodes node1.example.com role-
cordon & drain
cordon : ํน์ ๋ ธ๋์ pod์ค์ผ์ฅด์ ๊ธ์ง(cordon)ํ๊ฑฐ๋ ํด์ (uncordon)
drain : ํน์ node์ pod๋ฅผ ๋น์ฐ๊ณ , cordon์ฒ๋ฆฌ๊น์ง ํ๋ค.
deployment์ ๊ฒฝ์ฐ, ๋ค๋ฅธ ๋น์ด์๋ node๋ก pod๊ฐ ์ด๊ด๋๋ฉฐ, ์ผ๋ฐ pod๋ ์๋ฉธ๋๋ค.
#node2์ ์ค์ผ์ฅด๋ง์ ๋ฐ์ง ์๊ฒ ๋ค
kubectl cordon node2.example.com
kubectl apply -f deploy-nginx.yaml # <--- ํ๋4๊ฐ ์คํ์ํค๋ ๋ํ๋ก์ด ์คํํด๋ณด๋ฉด,
# node1์์๋ง ์คํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
#node2์ ์ค์ผ์ฅด๋ง์ ๋ฐ๊ฒ ๋ค
kubectl uncordon node2.example.com
kubectl delete deployments.apps webui
#drain : ํน์ ๋
ธ๋์์ ๋์์ค์ธ ๋ชจ๋ pod๋ฅผ ์ ๊ฑฐ
#node1๊ณผ node2์ ํ๋ ์คํ
kubectl apply -f deploy-nginx.yaml #<--- node1, node2์ ๊ฐ๊ฐ 2๊ฐ ์คํ๋์๋ค๊ณ ํ๋ค
kubectl run db --image=redis # <--- node2์ ์คํ๋์๋ค๊ณ ํ๋ค
#์ด์ํ์์ node2 ์ฅ๋น๋ฅผ ๋น์๋ณด์
kubectl drain node2.example.com #<--- ์๋ฌ๋๋ค. ์๋ ์ต์
์ ์ฌ์ฉํด์ผํจ. ๊ทธ๋ฆฌ๊ณ node2๋ ์๋ cordon์ฒ๋ฆฌ๋จ
# --ignore-daemonsets : DaemonSet-managed pod๋ค์ ignore
# --force=true : RC,RS,Job,DaemonSet ๋๋ StatefulSet์์ ๊ด๋ฆฌํ์ง ์๋ Pod๊น์ง ์ ๊ฑฐ
#์ต์
์ ํตํด node2 ์ฅ๋น๋ฅผ ๋น์๋ณด์
kubectl drain node2.example.com --ignore-daemonsets --force
# --> redis pod๋ ์ญ์ ๋์์ผ๋ฉฐ, deploy๋ pod๋ค์ node1์์ ์ฌ์์ฑ ๋์๋ค