본 포스팅은 Udemy Certificated Kubernetes Administrator 강좌를 공부한 내용입니다.
이전 포스팅(CKA 준비 (2) - Basic Control Plane Components )을 통해 POD가 배정받을 때 어떤 Worker Node에 배정받을지를 kubernetes Control Plane의 kube-scheduler가 결정한다고 했다.
여기서 배우게될 주된 주제는 POD가 어떤 node에 배정되고 퇴출(eviction)될지에 대한 내용이다.
이전 포스팅에서 namespace는 논리적인 단위로 POD 들을 격리(isolation) 시킨다고 했다.
그렇다면 실제로 각 POD의 역할에 맞게 다른 node에 POD를 실행시켜 물리적으로 격리시킬 방법이 있을까?
kubernetes에서는 다양한 방법을 통해 이러한 기능을 제공해준다.
Manual
kubernetes에서는 POD spec에서 배정될 node를 직접 명시할 수 있게 제공해준다.
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
nodeName: master
containers:
- image: nginx
name: nginx
dnsPolicy: ClusterFirst
restartPolicy: Never
이렇게 실행할 경우 POD는 kube-scheduler에 의해서 scheduling 되지 않고 바로 master node에 배정된다.
$ $ kubectl get pods -o wide
NANAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ngnginx 1/1 Running 0 102s 10.244.0.4 master <none> <none>
하지만 Scheduler에 의하지 않고 명시적으로 node를 명시하는 것은 여러 node의 리소스를 다양한 application이 사용한다는 kubernetes의 컨셉과는 맞지 않는다.
Taint & Toleration
Node는 POD가 실제로 실행되는 물리 또는 가상 머신이다.
각 Node는 자의적으로 자신이 실행시켜줄 POD를 구분지을 수 있어야 한다.
이러한 기능을 제공해주는게 Taint & Toleration이다.
사전적으로 Taint는 더러움, 감염 등을 의미한다.
kubernetes는 각 노드에 taint를 설정해 감염으로부터 용인(toleration)된 POD만 해당 node에서 실행시켜준다.
Pod 1은 red와 blue taint에 대해 toleration이 있기 때문에 Node1, Node2에 실행될 수 있고
Pod 2는 허용된 toleration이 없기 때문에 3 곳 모두에서 실행될 없고
Pod 3은 green toleration이 있기 때문에 Node 3에서 실행될 수 있다.
실제 taint와 toleration 설정 방법을 살펴보자.
taint 설정
$ kubectl taint nodes {NODE_NAME} key=value:{TAINT_EFFECT}
taint를 지정하고 싶은 NODE_NAME을 명시하고 key와 value를 입력한다.
그리고 TAINT_EFFECT를 통해 taint에 허용되지 않은 POD에 대한 node의 액션을 지정한다.
TAINT_EFFECT | 내용 |
NoSchedule | taint가 허용되지 않는 POD는 Scheduling 하지 않는다. 이미 실행 중인 POD는 관여하지 않는다. |
PreferNoSchedule | taint가 허용되지 않는 POD는 Scheduling 하지 않는 것을 시도한다. 하지만 cluster의 리소스가 부족한 것과 같은 상황이 되면 toleration이 만족하지 않아도 node에 Scheduliig이 된다. |
NoExecute | taint가 허용되지 않는 POD는 Scheduling 하지 않는다. 이미 실행 중인 POD도 eviction(퇴출) 한다. |
taint 를 삭제할 때는 가장 뒤에 "-"를 붙인다.
$ kubectl taint nodes {NODE_NAME} key=value:{TAINT_EFFECT}-
toleration 설정
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
tolerations:
- key: "color"
operator: "Equal"
value: "red"
effect: "NoSchedule"
status: {}
tolerations은 위와 같이 key/operator/value/effect를 명시한다.
tolerations 설정이 taint와 일치하면 POD는 해당 node에 배정될 수 있다.
(node에 여러개의 taint가 있다면 pod는 모든 taint를 만족해야 배정될 수 있다.)
toleration seconds
taint effect인 NoExecute를 활용한 toleration seconds에 대해 알아보자.
NoExecute는 이미 실행중인 POD에 대해서도 toleration이 맞지 않으면 퇴출한다.
$ kubectl taint nodes node01 color=red:NoExecute
위와 같이 설정되어 있다면 color=red:NoExecute에 만족되지 않는 POD는 node01에서 모두 퇴출된다.
그런데 toleration을 만족하더라도 특정 시간 이후에는 퇴출되도록 할 수 있다.
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
tolerations:
- key: "color"
operator: "Equal"
value: "red"
effect: "NoExecute"
tolerationSeconds: 3600
status: {}
위처럼 설정되어 있다면 nginx POD는 node01에서 3600초 이후에 퇴출된다.
이 기능은 kubernetes의 node controller에 의해서 사용된다.
Control Plane의 controller-manager는 모든 node의 상태를 모니터링 한다.
그런데 특정 node가 응답하지 않는다면 controller-manager는 node에 아래와 같은 taint를 지정한다.
key: node.kubernetes.io/unreachable
effect: NoExecute
또한 모든 POD는 아래와 같은 toleration이 default로 설정된다.
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000
즉, node의 상태가 이상하다고 판단되면 node controller는 taint를 설정하고 POD는 6000초 후에 해당 node에서 퇴출된다.
퇴출된 POD는 다른 정상상태의 node에 새롭게 scheduling된다.
이처럼 tolerationSeconds를 이용해 node 상태에 따른 scheduling이 가능하다.
더 자세한 내용은 아래 링크를 참고하자.
https://kubernetes.io/ko/docs/concepts/scheduling-eviction/taint-and-toleration/
정리
kubernetes의 scheduling에 대해서는 모르는 부분이 많았는데 도움이 많이 되었다.
'Kubernetes > CKA' 카테고리의 다른 글
CKA 준비 (8) - Scheduling 3 (DaemonSet, Static Pod) (0) | 2020.06.16 |
---|---|
CKA 준비 (7) - Scheduling 2 (Node Selector, Node Affinity) (0) | 2020.06.09 |
CKA 준비 (5) - namespace, service (0) | 2020.06.07 |
CKA 준비 (4) - Pod, ReplicaSet, Deployment (0) | 2020.06.05 |
CKA 준비 (3) - Basic Data Plane Components (kubelet, kube-proxy) (0) | 2020.06.05 |