개요
k8s에서의 schedule 동작 방식과 scheduling 방법을 알아보겠습니다.
https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/
nodeName(manual scheduling)
원리
pod를 만들때 배포할 node를 선택하는 방식 입니다.
필수 필드 : nodeName: worker1
nodeName을 지정하여 배포할 node를 선택 합니다.
apiVersion: v1
kind: Pod
metadata:
labels:
run: schedule-nginx-1
name: schedule-nginx-1
spec:
containers:
- image: nginx
name: schedule-nginx-1
ports:
- containerPort: 8080
nodeName: worker1
유의 사항
- nodeName이 yaml에 존재 시 오직 create / replace --force / delete 명령어만 사용 가능 합니다.
- apply 명령 사용시 아래와같이 에러가 발생 합니다.
kubectl apply -f nginx.yaml
The Pod "nginx" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds`, `spec.tolerations` (only additions to existing tolerations) or `spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)
core.PodSpec{
... // 9 identical fields
ServiceAccountName: "default",
AutomountServiceAccountToken: nil,
- NodeName: "",
+ NodeName: "node01",
SecurityContext: &{},
ImagePullSecrets: nil,
... // 19 identical fields
}
- 한번 생성된 pod의 nodeName은 수정 할 수 없습니다. k8s에서 막고 있습니다. 그래서 nodeName을 변경 하려면 삭제후 다시 만들어야 합니다.
auto scheduling
scheuduler가 동작 중일때 nodeName 필드가 없다면 scheduler는 pod를 배포 할 node를 어떻게 선택 할까요?
1. scheduler는 nodeName이 세팅 되지 않는 Pod를 찾습니다.
2. scheduling algorithm에 의해서 Pod를 배포할 적절한 node를 찾습니다.
3. nodeName에 선택한 node의 이름을 넣고 pod를 create 합니다.
scheduller가 없을 때 오류
우선 scheduller가 없거나 scheuller가 이상 동작할 때 pod를 배포하면 아래 아 같이 pod의 status가 pending이 됩니다
Labels and Selectors
k8s에서는 Labels을 이용해서 Pod들을 분류 합니다.
그리고 Selector에서는 Labels 이용하여 사용할 pod들을 선택 합니다.
Labels의 형태는 key: value가 통으로 하나의 Labels로 인식 됩니다. 그리고 yaml에서의 labels는 key: value 로 사용되며 command 상에서는 key=value 형태로 사용됩니다.
Pod에서 Labels 사용
명령어로 pod 생성시 label 추가
#kubectl run label-pod --image=nginx -l app=red,mode=test
pod/label-pod created
Label 확인
# kubectl describe pod label-pod
Name: label-pod
Namespace: default
Priority: 0
Service Account: default
Node: worker2/192.168.0.3
Start Time: Sat, 04 Feb 2023 22:30:08 +0900
Labels: app=red
mode=test
yaml로 pod 생성시 label 추가
아래 형식으로 추가 가능합니다.
metatdata :
labels:
app: red
실제 yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: red
mode: test
name: label-pod
spec:
containers:
- image: nginx
name: label-pod
label로 filtering 하기
#kubectl get pod -l app=red
NAME READY STATUS RESTARTS AGE
label-pod 1/1 Running 0 34m
# kubectl get pod -l app=red --no-headers
label-pod 1/1 Running 0 65m
Replicaset에서 Labels사용
matchLabels에서 관리한 Pod를 lables를 이용하여 선택 합니다.
taint 와 toleration
사용 시기
특정 node에 특정 pod만들 배치 하고 싶을 때 사용합니다.
원리
taint(오염)와 toleration(내성)을 사용하여 pod의 배치를 결정합니다. taint는 node 조건을 설정하는 방법이고toleration의 Pod에 조건을 설정하는 방법입니다. 그래서 결론 적으로 taint와 toleration이 일치하는 경우에만 Pod를 해당 node에 배포 할수 있습니다.
Node taint 설정
node에 특정 조건을 설정 합니다.
설정 방법
taint-effect
taint-effect를 사용하여 pod의 배포 및 기존 배포된 pod를 어떻게 처리 할지 결정합니다.
1. NoSchedule
앞으로 배포될 Pod에 "app=blue:NoSchedule" 이러한 조건에 맞는 toleration이 없으면 해당 node에 schedule 하지 않습니다
이미 배포된 Pod들은 그대로 운영이 됩니다.
kubectl taint nodes worker1 app=blue:NoSchedule
2. PreferNoSchedule
앞으로 배포될 Pod에 "app=blue:PreferNoSchedule" 이러한 조건에 맞는 toleration이 없으면 되도록이면 배포되지 않지만 리소스가 부족한 상황등에서는 우선순위를 낮춰서, Toleration이 없는 Pod도 배포될 수 있도록 합니다.
kubectl taint nodes worker1 app=blue:PreferNoSchedule
3. NoExecute
앞으로 배포 되거나 이미 배포된 Pod에 "app=blue:NoExecute" 이러한 조건에 맞는 toleration이 없으면 해당 node에 schedule 하지 않습니다. 이미 배포된 Pod들은 모두 추출(evicted)되어서 다른 node로 이동 됩니다.
kubectl taint nodes worker1 app=blue:NoExecute
추가로 알아두어야 할 필드 tolerationSeconds
이 필드는 Pod가 NoExexute taint를 만족하는 Pod여도 tolerationSeconds 에서 지정한 초동안만 Pod를 유지후 제거 합니다.
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
taint 제거
taint 설정 명령에서 끝에 - 만 붙이면 됩니다.
kubectl taint nodes worker1 app=blue:NoExecute-
taint 특징
1. 여러개의 taint를 설정 할 수 있습니다.
2. node의 taint가 NoExecute가 아니면 실행 중 인 Pod를 그대로 유지가 됩니다.
단. NoExecute인를 만족하는 Pod도 tolerationSeconds 옵션이 존재하면 해당 시간 만큼만 유지후 제거 됩니다.
Pod toleration 설정
pod에 tolerations 항목을 사용하여 조건을 설정 합니다.
아래그림은 node tain와 pod의 toleratino을 1대 1 매칭 시킨것입니다.
taint가 여러개인 node에 pod 배포
pod의 toleration도 동일하게 해주어야 배포가 됩니다.
apiVersion: v1
kind: Pod
metadata:
labels:
run: toleration-pod
name: toleration-pod
spec:
containers:
- image: nginx
name: toleration-pod
resources: {}
tolerations:
- key: app
operator: "Equal"
value: blue
effect: "NoExecute"
- key: app
operator: "Equal"
value: red
effect: "NoSchedule"
operator 에따른 value 존재 유무
Equal : value값이 존재 해야 합니다.
apiVersion: v1
kind: Pod
metadata:
labels:
run: toleration-pod
name: toleration-pod
spec:
containers:
- image: nginx
name: toleration-pod
resources: {}
tolerations:
- key: app
operator: "Equal"
value: blue
effect: "NoExecute"
Exists : value값이 없어도 됩니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"
정리
- Pod를 명시적으로 scheduling 할때는 nodeName을 사용합니다.
- Pod를 조건에 맞추어 scheduling 할 때는 taint로 node에 조건을 걸고 toleration으로 pod에 조건을 걸어서 사용합니다.
- Pod를 filtering 할 때는 label을 사용하여 filtering이 가능합니다.
Next Post
'Cloud > k8s-CKA' 카테고리의 다른 글
[CKA] 9. Pod resource 제어 방법 (0) | 2023.02.14 |
---|---|
[CKA] 8. schedule (Node Selector, Node Affinity) (0) | 2023.02.11 |
[CKA] 6. Object를 관리하는 방법 3가지 (0) | 2023.01.29 |
[CKA] 5. namespace (0) | 2023.01.24 |
[CKA] 4. Service (0) | 2023.01.20 |