들어가며
쿠버네티스를 처음 공부하게 되면 Master node와 Worker node에 대한 개념부터 배우기 시작합니다.
처음 그 개념을 익히며 왜 마스터 노드에는 파드가 스케줄링되지 않을까, 파드를 띄우는 방법은 없을까? 궁금했었습니다.
쿠버네티스에서 Master Node에 Pod가 스케줄링되지 않는 이유는 여러 가지가 있지만, 가장 주된 이유는 Master Node의 안정성과 성능을 유지하기 위해서입니다.
이를 구현하기 위해 쿠버네티스는 `Taints`와 `Tolerations`라는 메커니즘을 사용합니다.
Taints와 Tolerations
Taints와 Tolerations는 노드와 파드 간의 특정 조건을 설정하여 특정 파드가 특정 노드에 스케줄링될 수 없도록 하거나, 특정 조건을 만족하는 경우에만 스케줄링될 수 있도록 합니다.
Taints
Taints 는 더러움, 얼룩, 흔적이라는 뜻입니다.
노드에 Taints 즉, 얼룩이 있다면 파드에는 이를 견딜수있는 tolerations 가 있어야 해당 노드에 할당될 수 있습니다.
kubectl taint node ip-172-31-30-28.us-west-2.compute.internal alicek106/iirin-taint=dirty:NoSchedule
특정 노드에 alicek106/iirin-taint=dirty:NoSchedule
라는 taint를 추가합니다.
kubectl taint node ip-172-31-30-28.us-west-2.compute.internal alicek106/iirin-taint=dirty:NoSchedule-
이전에 설정된 taint를 제거하여 해당 노드가 다시 스케줄링 가능하도록 만듭니다.
이전 명령어에 `-`만 붙여주면 됩니다.
Taint 효과 종류
- `NoSchedule` 해당 노드에 새로운 파드가 스케줄링되지 않습니다.
- `PreferNoSchedule` 가능한 해당 노드에 파드가 스케줄링되지 않도록 합니다.
- `NoExecute` 해당 노드에서 파드가 실행되지 않도록 하며, 이미 실행 중인 파드도 퇴거시킵니다.
Tolerations
파드가 특정 taint를 무시하고 해당 노드에 스케줄링될 수 있도록 하는 설정입니다.
Tolerations를 통해 특정 파드가 특정 노드에 스케줄링될 수 있습니다.
Pod, Reflicaset 등에 적용할 수 있습니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations: # pod에 정의하는 방법
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"
kind: Runner
spec:
replicas: 2
spec:
labels:
- test
tolerations:
- key: capacity
value: spot
operator: Equal
- key: kind
value: runner
operator: Equal
마스터 노드의 Taints
마스터 노드에 파드가 할당되지 않는 주된 이유는 마스터 노드에 taint가 설정되어 있기 때문입니다.
`:NoExcute` 효과의 taint를 허용할 수 있는 파드가 마스터 노드에서 실행되고 있습니다.
Cordon과 Drain
쿠버네티스에서 제공하는 명시적인 노드 관리 방법입니다.
Cordon
kubectl cordon <node_name>
특정 노드를 cordon하여 더 이상 새로운 파드가 해당 노드에 스케줄링되지 않도록 합니다.
하지만 이미 실행 중인 파드에는 영향을 미치지 않습니다. uncordon
명령어를 사용하여 cordon 상태를 해제할 수 있습니다.
Drain
kubectl drain <node_name> --force
이 명령어는 해당 노드에서 실행 중인 파드들을 퇴거시킵니다.
노드 유지보수 등의 이유로 사용할 수 있습니다.
단일 파드로 생성된 파드가 있다면 drain이 실패할 수 있으므로 --force
옵션을 사용해야 할 수 있습니다.
PodDisruptionBudget (PDB)
PodDisruptionBudget은 특정 파드의 개수를 유지하기 위한 메커니즘입니다.
pod 퇴거가 발생할 때, 특정 개수 혹은 특정 비율만큼의 파드는 정상적인 상태를 유지하도록 사용됩니다.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: pdb
spec:
minAvailable: 80%
selector:
matchLabels:
app: my-app
주의사항
kubectl apply -f 06-simple-pdb-ex.yaml
error: resource mapping not found for name: "iirin-simple-pdb-example" namespace: "" from "06-simple-pdb-ex.yaml": no matches for kind "PodDisruptionBudget" in version "policy/v1beta1"
ensure CRDs are installed first
혹시 위와 같은 에러가 발생한다면, `policy/v1beta1` 버전을 더이상 지원하지 않기 때문입니다.
참고링크 https://cloud.google.com/kubernetes-engine/docs/deprecations/apis-1-25?hl=ko