[k8s] pod์ node ๋ฐฐ์น
์ฟ ๋ฒ๋คํฐ์ค๋ ๋ฉํฐ ๋
ธ๋ ๋ถ์ฐ ํ๊ฒฝ์์์ ์ปจํ
์ด๋ ๊ด๋ฆฌ๋ฅผ ์ํ ์์คํ
์ด๋ค.
๋ฉํฐ๋
ธ๋์ ์ปจํ
์ด๋๋ฅผ ์๋ฐํ๊ฒ ์ฑ์ฐ๋๊ฑด ์ข์๋ฐ, ๊ทธ๋ ๋ค๊ณ ํด์ ํญ์ ์ปจํ
์ด๋๊ฐ ๋๋ค ๋
ธ๋์ ํ ๋น๋์ด์๋ ๋ชฉํ๋ฅผ ์ด๋ฃฐ ์ ์์ ๊ฒฝ์ฐ๊ฐ ๋ง์ ๊ฒ์ด๋ค.
์๋ฅผ ๋ค๋ฉด, ๋ถํ๊ฐ ๋ง์ ์๋ฒ๋ฅผ ์คํ์ด ๋๋ํ ํน์ ์๋ฒ์ ๋ชฐ์์ค์ผ ํ๋ค๋ ์ง, ์๋๋ฉด ํน์ IP๋ฅผ ๊ฐ์ง ๋ ธ๋์ ์๋ฒ๋ฅผ ๋์์ผ๋ง ์๋๋๋ก ๋์ํ๋ค๋ ์ง ํ๋ ํ์ค์ ์ธ ์ ํ์ฌํญ๋ค์ด ์์ ์ ์๋ ๊ฒ์ด๋ค.
์ฌ๊ธฐ์๋ 2๊ฐ์ง ๋ฐฉํฅ์ฑ์ด ์๋ค.
Pod๊ฐ ์ง์ ํน์ ๋
ธ๋์ ๋ฐฐ์น๋๋๋ก ์ ๋ํ๋ ๊ธ์ ์ ์ธ ์ ๊ทผ๋ฒ์ด ์๊ณ , ๋
ธ๋๊ฐ Pod๋ฅผ ๊ฑฐ๋ถํ๋ ๋ถ์ ์ ์ธ ์ ๊ทผ๋ฒ์ด ์๋ค.
์ ์๋ nodeName, nodeSelector๋ affinity๋ผ๊ณ ๋ถ๋ฅด๋ ๋ฐฉ๋ฒ์ด๊ณ , ํ์๋ Taint๋ผ๊ณ ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
์ด ํฌ์คํธ์์ ์ฃผ๋ก ๋ค๋ฃฐ ๊ฒ์ ์ ์๋ค. ํ์์ ๊ฒฝ์ฐ์๋ ๋ณ๋ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ๋ค.
https://blog.naver.com/sssang97/223645592718
nodeSelector
nodeSelector๋ Pod๋ฅผ ํน์ Node์ ๋จ๋๋ก ์ ๋ํ๋ ๊ฐ์ฅ ๋จ์ํ ๋ฐฉ๋ฒ์ด๋ค.
Node๋ ๋ค๋ฅธ k8s ๋ฆฌ์์ค๋ค๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก label์ด๋ผ๊ณ ํ๋ ๋ฉํ๋ฐ์ดํฐ ๊ฐ๋ค์ ๊ฐ๋๋ค. ์ด๊ฑธ ๊ธฐ๋ฐ์ผ๋ก ๋ ธ๋๋ฅผ ์ ํํ๊ณ ๋ค์ด๊ฐ๋ ๊ฒ์ด๋ค.

๋
ธ๋์ ๋ ์ด๋ธ์ ์ถ๊ฐํ๋๊ฑด ์ด๋ ต์ง ์๋ค.
๊ทธ๋ฅ ์ด๋ ๊ฒ ์น๋ฉด ๋๋ค.
kubectl label nodes ๋
ธ๋๋ช
ํค=๊ฐ

๊ทธ๋ฆฌ๊ณ Pod์ node ์ ํ ์ ๋ณด๋ฅผ ๋ฃ์ผ๋ ค๋ฉด, spec.nodeSelector์ ํค๊ฐ์์ ๋ฃ์ผ๋ฉด ๋๋ค.
nodeSelector:
ํค: ๊ฐ
๋ง์ฝ ์ ์
๋ ํฐ์ ์ผ์นํ๋ ๋
ธ๋๊ฐ ์๋ค๋ฉด
pod๋ ์ค์ผ์ค๋์ง ๋ชปํ๊ณ ๋ฌดํ ๋๊ธฐ์ํ์ ๋น ์ง๋ค.
์ผ์นํ๋๋๋ก ์
๋ ฅํ๋ค๋ฉด
๊ทธ ๋
ธ๋์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ฐฐ์น๋ ๊ฒ์ด๋ค.
nodeName
nodeSelector๋ ๋ ์ด๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ํ ๋
ธ๋ ์ ํ์ด์๋ค.
๋ฐ๋ฉด, ์ง์ง ๋
ธ๋ ์ด๋ฆ์ ์ง์ ์ง์ ํด์ ๋ฑ ๊ทธ ๋
ธ๋์ ๋จ๊ฒ ํ๋ ๋ฐฉ๋ฒ๋ ์๋ค.
์ฌ์ฉ๋ฒ์ ๋งค์ฐ ๊ฐ๋จํ๋ค.
spec:
nodeName: ๋
ธ๋๋ช
๊ทธ๋ฅ ์ด๋ ๊ฒ ๋ ธ๋๋ช ๋ฃ๊ณ ๋๋ฆฌ๋ฉด

๋ฑ ๊ทธ ๋
ธ๋์ ๋ฐฐ์น๊ฐ ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ผ์นํ๋ ๋ ธ๋๊ฐ ์๋ค๋ฉด

nodeSelector์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฌดํ ๋๊ธฐ ์ํ์ ๋น ์ง๋ค.
nodeName์ด ๊ฐํธํ๊ธด ํ์ง๋ง, ์ฅ๊ธฐ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ์๋ ์ ์ข์ง ์์์ ์ผ๋ฐ์ ์ผ๋ก ๊ถ์ฅ๋์ง ์๊ณ , ์ ์ฌ์ฉ๋์ง๋ ์๋๋ค. ๊ทธ๋ฅ ์๊ธฐ๋ง ํ ๊ธฐ๋ฅ์ด๋ค.
์๋ฌดํผ nodeName์ด๋ nodeSelector ๊ธฐ๋ฐ์ ๋ฐฉ๋ฒ์ ์ง๊ด์ ์ด๊ณ ์ ๋์ํ๊ธด ํ์ง๋ง, ๋ณต์กํ ์ํฉ์์๋ ์ ์ฉํ๊ธฐ ์ด๋ ค์ธ ์๋ ์๋ค.
๋ฑ ํน์ ๋จธ์ ์ ๋ฐฐ์น๋๋๊ฑธ ์ํ ์๋ ์์ง๋ง, ๊ทธ๋ฅ ์ฐ์ ์์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํน์ ๋จธ์ ์ ๋ฐฐ์นํ๋ ๊ฒ์ "์ ํธ"ํ๋๋ก ๊ตฌ์ฑํ๊ณ ์ถ์ ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๊ฑธ ์ํ ๊ธฐ๋ฅ์ด affinity๋ค.
node affinity
node affinity๋ ๋ณต์กํ ํํ์ ๋ ธ๋ ๋ฐฐ์น ๊ตฌ์กฐ๋ฅผ ์ ์ํ ์ ์๋ ๋งค์ปค๋์ฆ์ด๋ค.
์ด๊ฑด nodeSelector์ฒ๋ผ ์ผ์นํ๋ ๊ฒ์๋ง ๋ฐฐ์น๋๋๋ก ์๊ฒฉํ ์ ํ์ ์ถ๊ฐํ ์๋ ์๊ณ , ๋จ์ง "์ ํธ"ํ๋๋ก ์ฐ์ ์์๋ฅผ ์ง์ ํ๋ ์ ๋๋ก ๋๋ผ ์๋ ์๋ค.
๋ฑ ์ผ์นํ๋ ๊ฒ์๋ง ๋ฐฐ์น๋๋๋ก ํ๋ ์ต์ ์ด requiredDuringSchedulingIgnoredDuringExecution๊ณ , ์ฐ์ ์์๋ง ์ง์ ํ๋ ๊ฒ์ด preferredDuringSchedulingIgnoredDuringExecution๋ค.
ํ๋ฒ ์์ ๋ฅผ ๊น๋ณด๋ฉด์ ๊ธฐ๋ณธ ํํ๋ฅผ ์ดํดํด๋ณด์.
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: label-1
operator: In
values:
- key-1
- weight: 50
preference:
matchExpressions:
- key: label-2
operator: In
values:
- key-2
์์ ์ธ๊ธํ๋ฏ requiredDuringSchedulingIgnoredDuringExecution๋ must ์กฐ๊ฑด์ด๋ค.
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
์ด๊ฑด kubernetes.io/os=linux๋ผ๋ ๋ ์ด๋ธ์ด ํฌํจ๋ node์๋ง pod๊ฐ ๋ฐฐ์น๋ ๊ฒ์์ ๋ปํ๋ ๊ตฌ๋ฌธ์ด๋ค.
์ด ๋ถ๋ถ์ ๊ฝค ๋จ์๋ช
๋ฃํ๋ค.
preferredDuringSchedulingIgnoredDuringExecution๋ ๋จ์ํ ์ฐ์ ์์๋ฅผ ์ง์ ํ๋ ์ต์
์ด๋ค.
์ด ์ฐ์ ์์์ ๋ง์ง ์๋๋ผ๋ ์ ์ ํ ๋
ธ๋๊ฐ ์์ผ๋ฉด ์๋ฌด๊ฑฐ๋ ์ํฉ์ ๋ฐ๋ผ ๋ฐฐ์นํ๋ค.
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: label-1
operator: In
values:
- key-1
- weight: 50
preference:
matchExpressions:
- key: label-2
operator: In
values:
- key-2
๋ณด์ด๋ ๊ฒ์ฒ๋ผ, ์ด๊ฑด ๊ฐ์ค์น(weight) ๊ธฐ๋ฐ์ผ๋ก ๋
ธ๋๋ฅผ ์ ํํ๋ค.
๊ทธ๋ฌ๋๊น, label-1:key-1 ๋ ์ด๋ธ์ด ์๋ ๋
ธ๋์ 1์ ์ ์ฃผ๊ณ , label-2:key-2 ๋ ์ด๋ธ์ด ์๋ ๋
ธ๋์ 50์ ์ ์ค์ ๊ฐ์ฅ ๋์ ์ ์๋ฅผ ๊ฐ์ง ๋
ธ๋๋ฅผ ์ฐ์ ์ ์ผ๋ก ์ ํํ๋ ๊ฒ์ด๋ค.
pod affinity & pod anti affinity
์ด๊ฑด ์ข ๋ ๋ณต์กํ ์ฌ์ฉ์ฌ๋ก๋ฅผ ์์ ํ ๋
ธ๋ ์ ํ ๋งค์ปค๋์ฆ์ด๋ค.
node affinity์ ๊ฒฝ์ฐ์๋ ์์ํ๊ฒ ๋
ธ๋์ ๋ ์ด๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ํด์ ๋
ธ๋๋ฅผ ์ ํํ๋ค. ๋
ธ๋๊ฐ pod๊ฐ ๋ช๊ฐ ๋ ์๋ , ๋ฆฌ์์ค๊ฐ ์ผ๋ง๋ ๋จ์๋ ์ ๊ฒฝ์ฐ์ง ์๋๋ค.
ํ์ง๋ง pod๊ฐ ์ด๋ฏธ ๋ ์๋ ๊ฒ๊น์ง ๊ณ ๋ คํด์ ๋
ธ๋ ๋ฐฐ์น๋ฅผ ๊ณ ๋ คํ๊ณ ์ถ์ ์๋ ์๋ค.
์๋ฅผ ๋ค๋ฉด ํน์ Pod๊ฐ ๋ ์๋ ๋
ธ๋๋ ๋ฆฌ์์ค๊ฐ ๋ถ์กฑํ ํ
๋ ๋ค๋ฅธ ๋
ธ๋์ ๋ฐฐ์นํ๊ฒ๋ ํ๊ณ ์ถ๋ค๋ ์ง ํ๋ ๊ทธ๋ฐ ์ํฉ ๋ง์ด๋ค.
pod affinity๋ ์ด๋ฐ ์ํฉ์ ์ ์ฉํ ๊ธฐ๋ฅ์ด๋ค.
pod affinity๋ node affinity์ ๋น์ทํ๊ฒ 2๊ฐ์ง ์ต์ ์ ๊ฐ์ง๋ค.
- requiredDuringSchedulingIgnoredDuringExecution
- preferredDuringSchedulingIgnoredDuringExecution
ํ๋ฒ ์ค์ ์ ์ธ ์์๋ฅผ ๋ค์ด์ ๋ณด์ฌ๋ณด๊ฒ ๋ค.
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: topology.kubernetes.io/zone
์ด๊ฑด security:S1๋ผ๋ pod๊ฐ ์๋ ์์ญ(zone)์ ๋ฐฐ์นํ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ด zone์ ๊ธฐ์ค์ด topologyKey๋ก ์ค์ ํ "topology.kubernetes.io/zone"๋ค. ์ด๊ฑด ๋ ธ๋๋ฅผ ๋ฌถ๋ ๊ธฐ์ค์ด ๋๋ ๋ ์ด๋ธ ๊ฐ์ด๋ค.
๊ทธ๋ฌ๋๊น, ๋ค์ ๋งํด ์ด ๊ฒฝ์ฐ์๋ security:S1๋ผ๋ pod๊ฐ ์๋ ๋ ธ๋์ ๋์ผํ "topology.kubernetes.io/zone" ๋ ์ด๋ธ์ ๊ฐ์ง ๋ชจ๋ ๋ ธ๋๊ฐ ์ค์ผ์ค๋ง ๋์์ด ๋ ์ ์๋ ๊ฒ์ด๋ค.
"topology.kubernetes.io/zone"๋ ํด๋ผ์ฐ๋ ํด๋ฌ์คํฐ ํ๊ฒฝ์์ ์๋์ผ๋ก ์ฃผ์
๋๋ ๋ ์ด๋ธ ๊ฐ์ด๊ณ , ์จํ๋ ๋ฏธ์ค์์๋ ์ง์ ์ ์ ํ ๊ตฌ์ฑํด์ผ ํ๋ค.
๊ด๋ก์ ์ผ๋ก kubernetes.io/hostname๋ ๋ง์ด ์ด๋ค. ์ด๊ฑด ๋ณดํต ๋
ธ๋๋ง๋ค ๋ค๋ฅด๊ฒ ์ง๋๋ค.
podAntiAffinity๋ ์๋ฆฌ๊ฐ ๊ฑฐ์ ๊ฐ๋ค. ์ ํํ ๊ทธ ๋ฐ๋๋ก, ๊ทธ zone์ ์ํ๋ ๊ฒ๋ค์ pod๊ฐ ๋ฐฐ์น๋์ง ์๊ฒ ํ๋ ๊ฒ์ผ ๋ฟ์ด๋ค.
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: topology.kubernetes.io/zonepod anti affinity ์์ฉ - ๋ ธ๋ ๋ถ์ฐ
๊ทธ๋ผ ์ ๋ณต์กํ ๋๋ค์ ์ด๋ป๊ฒ ์จ๋จน์ด์ผ ํ ๊น?
anti affinity๋ ํน์ ์กฐ๊ฑด์ pod๊ฐ ๋ ์๋ ์ํฉ์ ๊ธฐํผํ๋๋ก ๊ตฌ์ฑํ ์ ์๋ค.
๊ทธ๋ฌ๋๊น, ์ด ํน์ฑ์ ์์ฉํ๋ฉด deployment ๊ฐ์ ๊ทธ๋ฃน ๋จ์์ pod๊ฐ ๋
ธ๋๋ณ๋ก ๊ณ ๋ฅด๊ฒ ๋ถ์ฐ๋๋ ๊ฒ์ ๊ฐ์ํ ์ ์๋ ๊ฒ์ด๋ค.
๋ค์์ redis๋ก ๋
ธ๋ ๋ถ์ฐ์ ๊ตฌ์ฑํ๋ ๊ฐ๋จํ ์์ ๋ค.
redis ๊ฐ์ ๊ฒฝ์ฐ์๋ ์ค์ ๋ก ๊ฐ ๋
ธ๋์ ์น ์๋ฒ๋ค์ด ์ต์ ์ ๊ฒฝ๋ก๋ก ์ ๊ทผํ ์ ์๊ฒ๋ ๋
ธ๋๋ณ๋ก ๋ฐฐ์น๋ฅผ ํ ํ์๊ฐ ์์ ์ ์์ ๊ฒ์ด๋ค.
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
image: redis:3.2-alpine
๋ณด๋ค์ํผ ์ด deploement๋ ๊ฐ๊ฐ์ pod์ app: store ๋ ์ด๋ธ๊ฐ์ ๊ฐ๋๋ก ๊ตฌ์ฑํ๋ค.
๊ทธ๋ฐ๋ฐ podAntiAffinity๋ก๋ app: store๊ฐ ์๋ ๋
ธ๋๋ฅผ ๋ฌด์ํ๋๋ก ํ์ผ๋, ์ด 3๊ฐ์ ๋
ธ๋์ ๋๋ค์ผ๋ก ๋ถ์ฐ๋๋ ๊ฒ์ด๋ค.
์ด์ฒ๋ผ ๋ณต์กํ ์๋ ์๋ ํ๋ก๋น์ ๋ ๊ตฌ์ฑ์ ๋น๊ต์ ๊ฐํธํ๊ฒ ์ค์ ํ ์ ์๋ค.
pod affinity ์์ฉ - ๋ถ์ฐ ๋ ธ๋ ๋ฐ๋ผ๊ฐ๊ธฐ
๋ฐฉ๊ธ ์์์๋ redis๋ฅผ 3๊ฐ์ ๋
ธ๋์ ๋ถ์ฐํด์ ๋ฐฐ์นํ๋๋ก ๊ตฌ์ฑ์ ํ์๋ค.
๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ redis๋ฅผ ๊ฐ๋ฆฌํค๋ ์น์๋ฒ๋ค์ ์ต์ ์ ๊ฒฝ๋ก๋ก ๋ถ๊ฒ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น?
์ด๊ฒ๋ pod affinity๋ฅผ ์์ฉํ๋ฉด ๋น๊ต์ ๊ฐํธํ๊ฒ ๊ตฌ์ฑ์ด ๊ฐ๋ฅํ๋ค.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
selector:
matchLabels:
app: web-store
replicas: 3
template:
metadata:
labels:
app: web-store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: web-app
image: .../web-server-image
์ข ๊ธธ๊ณ ๋ณต์กํด๋ณด์ผ ์๋ ์๋๋ฐ, ๊ตฌ์กฐ๋ฅผ ์๋ค๋ฉด ๊ทธ๋ ๊ฒ ์ด๋ ต์ง๋ ์๋ค.
podAntiAffinity์๋ ๋ฐฉ๊ธ redis ๊ตฌ์ฑ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ ธ๋๋ณ๋ก ํ๋์ฉ๋ง ๋จ๋๋ก ๋ถ์ฐ ๊ตฌ์ฑ์ด ๋์ด์๋ค. ์ด๊ฑด ์ด๋ ค์ธ ๊ฑด ์๋ค.
๊ทผ๋ฐ ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ๋ ๋์๊ฐ์, ๊ฐ redis๊ฐ ์์นํ ๊ณณ์ ์น์๋ฒ๋ฅผ ์์น์์ผ์ ์ต์ํ์ ๋ ์ดํด์๋ฅผ ๋ง๋ค๊ณ ์ถ๋ค.
๊ทธ๋์ podAffinity๋ฅผ ํตํด์ app: store๊ฐ ์๋, ๊ทธ๋ฌ๋๊น redis๊ฐ ์๋ node์๋ง ๋ฐฐ์นํ๋๋ก ํ๋ค.
์ด๋ ๊ฒ ๊ตฌ์ฑํ ๊ฒฝ์ฐ redis๊ณผ ์น์๋ฒ๋ ๋ค์๊ณผ ๊ฐ์ด ์ปดํฉํธํ๊ฒ ๊ตฌ์ฑ๋ ์ ์๋ค.

์ฐธ์กฐ
https://kubernetes.io/ko/docs/tasks/configure-pod-container/assign-pods-nodes/
https://kubernetes.io/ko/docs/concepts/scheduling-eviction/assign-pod-node/#%EC%96%B4%ED%94%BC%EB%8B%88%ED%8B%B0-affinity-%EC%99%80-%EC%95%88%ED%8B%B0-%EC%96%B4%ED%94%BC%EB%8B%88%ED%8B%B0-anti-affinity
https://kubernetes.io/ko/docs/concepts/scheduling-eviction/pod-priority-preemption/
https://stackoverflow.com/questions/72240224/what-is-topologykey-in-pod-affinity