- 스케쥴러 컴포넌트는 master에 올라간다
- 4인방 중 하나
- kubectl run 을 이용해서 pod를 실행시킬 수 있는데, 각 가용 리소스들 등의 여러가지 요소들을 스케쥴러를 이용하여 노드를 배정하는 역할을 한다.
- 배정을 스케쥴러가 한 후 api server로 전달한다.
- api-server는 각 worker 의 kubelet에게 전달한다.
- 스케쥴러 -> api-server -> kubelet -> 해당 node의 docker 쪽으로 내용을 전달 -> 컨테이너 생성
- 기본적으로 default scheduler를 사용한다.
- 다중 scheduler도 사용할 수 있다.
Advanced Scheduling
- nodeAffinity : 가중치 분산 스케줄이 가능
• 예를 들어 파드와 다른 노드에 지정될수 있도록 Affinity 설정 가능 • 즉 스케쥴링할때 체크하는 조건이라고 생각하면 된다. •Pod 명세서 자체에 스케쥴을 명시한다. - Prefer : 만족하는 node에 준하면 실행된다. - required : 만족하는 node가 없으면 pending 된다. |
- podAffinity : pod 간 엄격한 선호하는 레벨의 친화성을 제어
• 조건에 만족하는 pod라면 해당 node에 배포 • topologyKey : 호스트네임 의 pod가 배포된 node에 해당 pod도 함께 배포 (같은 가용 zone에 배포 되도록 바운더리를 지정할 수 있다.) |
Taints and Tolerations 시나리오
1.taint를 설정하여 해당 taint가 설정된 노드에만 pod가 생성되는지 확인한다
2.worker 노드에 taint를 설정한다. (node-type=prod:NoSchedule)
3.dev-pod pod 생성
4.prod-deployment deployment 생성
시작
1. node 레벨 taint 로 설정 (taint가 설정된 시스템에 배정 받을 수 있도록 설정 후 테스트한다.)
resource 타입 : node
epect : NoSchedule
#kubectl taint node ip-172-31-13-180 node-type=prod:NoSchedule
2. 일반 pod 배정 -> master에 배정되는지 확인 (worker에 배포가 안되고 master에 배포되는것을 확인)
dev-pod.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: dev-pod
labels:
app: busybox
spec:
containers:
- name: dev
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
3. dev-pod 생성
kubectl create -f dev-pod.yaml
4. prod-deployment.yaml 명세서 작성
apiVersion: apps/v1
kind: Deployment
metadata:
name: prod
spec:
replicas: 1
selector:
matchLabels:
app: prod
template:
metadata:
labels:
app: prod
spec:
containers:
- args:
- sleep
- "3600"
image: busybox
name: main
tolerations: # tolerations 설정을 했으므로 worker에 배포되는것을 확인한다
- key: node-type
operator: Equal
value: prod
effect: NoSchedule
5. prod-deplyment 생성
#kubectl create -f prod-deployment.yaml
root@ip-172-31-4-27:~/taint# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dev-pod 1/1 Running 0 2m18s 192.168.51.216 ip-172-31-4-27 <none> <none>
prod-86b6d56d8d-trgh9 1/1 Running 0 71s 192.168.82.37 ip-172-31-13-180 <none> <none>
#kubectl describe node ip-172-31-13-180
#kubectl taint node ip-172-31-13-180 node-type-
#@ taint 해제하는 방법은 node-type-
root@ip-172-31-4-27:~/taint# kubectl taint node ip-172-31-13-180 node-type-
node/ip-172-31-13-180 untainted
Cordon 시나리오
1.worker에 cordon을 설정하여 스케쥴링 제외한다.
2.worker노드에 uncordon으로 해제
3.worker노드에 drain을 설정한다.(cordon 보다 강력 : 스케즁일 제외 + 현재 pod까지 제거)
시작
1. 더 이상 스케줄링 하지 못하도록 설정 후 작업
#kubectl cordon ip-172-31-13-180 (이후 스케줄링에서 제외) #@ worker에 cordon을 설정하여 스케쥴링 제외
root@ip-172-31-4-27:~/taint# kubectl cordon ip-172-31-13-180
node/ip-172-31-13-180 cordoned
root@ip-172-31-4-27:~/taint# kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-31-13-180 Ready,SchedulingDisabled <none> 2d v1.19.4
ip-172-31-4-27 Ready master 2d1h v1.19.4
#kubctl describe node ip-172-31-13-180|grep -i taint
root@ip-172-31-4-27:~/taint# kubectl describe node ip-172-31-13-180|grep -i taint
Taints: node.kubernetes.io/unschedulable:NoSchedule
#kubectl uncordon ip-172-31-13-180 #node로 해제
root@ip-172-31-4-27:~/taint# kubectl uncordon ip-172-31-13-180
node/ip-172-31-13-180 uncordoned
#kubectl drain ip-172-31-13-180 (이후 스케줄링에서 제외 + 모든 pod를 제거) #@ cordon 보다 강력 : 스케즁일 제외 + 현재 pod까지 제거
#kubctl describe node ip-172-31-13-180|grep -i taint
#kubectl get nodes
root@ip-172-31-4-27:~/taint# kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-31-13-180 Ready,SchedulingDisabled <none> 2d v1.19.4
ip-172-31-4-27 Ready master 2d1h v1.19.4
#kubectl uncordon ip-172-31-13-180 로 해제
root@ip-172-31-4-27:~/taint# kubectl uncordon ip-172-31-13-180
node/ip-172-31-13-180 uncordoned
#kubectl get nodes #@ 확인
root@ip-172-31-4-27:~/taint# kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-31-13-180 Ready <none> 2d v1.19.4
ip-172-31-4-27 Ready master 2d1h v1.19.4
CordonAffinity 시나리오
1.master와 worker노드에 label을 설정한다.
2.pod-nodeaffinity pod를 생성한다. (nodeSelectorTerms.matchExpressions으로 team1 레이블을 갖고있는 node에 생성되는지 확인한다)
3.pod-nodeaffinity.yaml <----key를 team2로 변경, pod_name 변경
4.pod-nodeaffinity pod를 생성한다 (마스터와 워커에 pod가 생성됨을 확인. team2로 변경했으므로)
5.pod-required pod를 생성한다. (prod이라는 lable이 있는지 체크한다. 요구조건에 맞는 node가 없으므로 pending 되는 것을 확인)
6.pod-prefer pod를 생성한다. (preferredDuringSchedulingIgnoredDuringExecution: #조건이 없음에도 불구하고 running 이 되는지 확인)
7.label을 생성한다. (kubectl label nodes ip-172-31-13-180 prod=true)
8.워커의 label을 변경하여 조건에 맞춰 pod-required가 pending에서 running됨을 확인
시작
1.master, worker에 label 설정
root@ip-172-31-4-27:~/taint# kubectl label nodes ip-172-31-4-27 team1=dev
node/ip-172-31-4-27 labeled
root@ip-172-31-4-27:~/taint# kubectl label nodes ip-172-31-13-180 team2=dev
node/ip-172-31-13-180 labeled
2.pod-nodeaffinity.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: pod-1
spec:
affinity:
nodeAffinity: #노드 레벨로 조사
requiredDuringSchedulingIgnoredDuringExecution: #강제로 필수 조건설정
nodeSelectorTerms:
- matchExpressions:
- {key: team1, operator: Exists} # team1 레이블을 갖고있는 node
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
3.pod-required.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: pod-required
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- {key: prod, operator: Exists} # prod이라는 lable이 있는지 체크한다. 요구조건에 맞는 node가 없으므로 pending 되는 것을 확인
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
4.pod-prefer.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: pod-prefer
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution: #조건이 없음에도 불구하고 running 이 되는지 확인
- weight: 1
preference:
matchExpressions:
- {key: prod, operator: Exists}
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
5.생성
root@ip-172-31-4-27:~/affinity# kubectl create -f pod-nodeaffinity.yaml
pod/pod-1 created
#@ master에서 구동됨을 확인
root@ip-172-31-4-27:~/affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-1 1/1 Running 0 56s 192.168.51.217 ip-172-31-4-27 <none> <none>
# vi pod-nodeaffinity.yaml <----key를 team2로 변경, pod_name 변경
# kubectl create -f pod-nodeaffinity.yaml
pod/pod-2 created
#@ 마스터와 워커에 pod가 생성됨을 확인
root@ip-172-31-4-27:~/affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-1 1/1 Running 0 2m33s 192.168.51.217 ip-172-31-4-27 <none> <none>
pod-2 1/1 Running 0 12s 192.168.82.38 ip-172-31-13-180 <none> <none>
#@ 조건이 맞는게 없으므로 pending 되는 것을 확인
root@ip-172-31-4-27:~/affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-1 1/1 Running 0 3m16s 192.168.51.217 ip-172-31-4-27 <none> <none>
pod-2 1/1 Running 0 55s 192.168.82.38 ip-172-31-13-180 <none> <none>
pod-required 0/1 Pending 0 8s <none> <none> <none> <none>
# kubectl create -f pod-prefer.yaml #@조건이 없음에도 불구하고 running 이 되는지 확인
#@조건이 없음에도 불구하고 running 이 되는지 확인
root@ip-172-31-4-27:~/affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-1 1/1 Running 0 3m53s 192.168.51.217 ip-172-31-4-27 <none> <none>
pod-2 1/1 Running 0 92s 192.168.82.38 ip-172-31-13-180 <none> <none>
pod-prefer 1/1 Running 0 7s 192.168.82.39 ip-172-31-13-180 <none> <none>
pod-required 0/1 Pending 0 45s <none> <none> <none> <none>
# kubectl label nodes ip-172-31-13-180 prod=true
root@ip-172-31-4-27:~/affinity# kubectl label nodes ip-172-31-13-180 prod=true
node/ip-172-31-13-180 labeled
#@ 워커의 label을 변경하여 조건에 맞춰 pod-required가 pending에서 running됨을 확인
root@ip-172-31-4-27:~/affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-1 1/1 Running 0 4m56s 192.168.51.217 ip-172-31-4-27 <none> <none>
pod-2 1/1 Running 0 2m35s 192.168.82.38 ip-172-31-13-180 <none> <none>
pod-prefer 1/1 Running 0 70s 192.168.82.39 ip-172-31-13-180 <none> <none>
pod-required 1/1 Running 0 108s 192.168.82.40 ip-172-31-13-180 <none> <none>
Pod affinity 시나리오
1.front-end pod 생성 시도, pending 됨 (사유 nodeSelector: #해당 team에 맞는게 없어 pending 됨을 확인)
2.db pod 생성 시도,
3.label 생성 시도
kubectl label node ip-172-31-4-27 team=dev #db.yaml이 label이 생성되어 scheduler가 시작된다. 확인필요
kubectl label node ip-172-31-13-180 team=prod
4.db와 front-end가 동일한 node에 올라감을 확인한다.
조건에 맞는 label이 생성되어 pending -> running 됨을 확인한다.
1.db.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: db
labels:
type: db
spec:
nodeSelector: #해당 team에 맞는게 없어 pending 됨을 확인
team: dev
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
2.front-end.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: front-end
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution: #required 이기 때문에 조건에 맞지 않아 pending 되는것을 확인
- topologyKey: team
labelSelector:
matchExpressions:
- {key: type, operator: In, values: [db]} # db라는 value가 있는 lable을 체크한다
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
3.생성 및 확인
$ kubectl create -f front-end.yaml
pod/front-end created
$ kubectl get po
NAME READY STATUS RESTARTS AGE
front-end 0/1 Pending 0 6s
$ kubectl describe po
#pending 된 이유를 확인한다.
root@ip-172-31-4-27:~/pod_affinity# kubectl get po
NAME READY STATUS RESTARTS AGE
front-end 0/1 Pending 0 9s
#노드 셀렉터가 맞지 않아 pending이 발생
root@ip-172-31-4-27:~/pod_affinity# kubectl describe po
생략
Node-Selectors: team=dev
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 19s (x2 over 19s) default-scheduler 0/2 nodes are available: 2 node(s) didn't match node selector. #노드 셀렉터가 맞지 않아 pending이 발생
$ kubectl create -f db.yaml
pod/db created
$ kubectl get po
NAME READY STATUS RESTARTS AGE
db 0/1 Pending 0 4s
front-end 0/1 Pending 0 68s
root@ip-172-31-4-27:~/pod_affinity# kubectl get po
NAME READY STATUS RESTARTS AGE
db 0/1 Pending 0 5s
front-end 0/1 Pending 0 2m51s
$ kubectl label node ip-172-31-4-27 team=dev #db.yaml이 label이 생성되어 scheduler가 시작된다. 확인필요
node/ip-172-31-4-27 labeled
root@ip-172-31-4-27:~/pod_affinity# kubectl label node ip-172-31-4-27 team=dev
node/ip-172-31-4-27 labeled
$ kubectl label node ip-172-31-13-180 team=prod
node/ip-172-31-13-180 labeled
root@ip-172-31-4-27:~/pod_affinity# kubectl label node ip-172-31-13-180 team=prod
node/ip-172-31-13-180 labeled
$ kubectl get po
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 2m
front-end 1/1 Running 0 3m4s
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
db 1/1 Running 0 2m10s 192.168.137.98 ip-172-31-4-27 <none> <none>
front-end 1/1 Running 0 3m14s 192.168.137.99 ip-172-31-4-27 <none> <none>
#@db와 front-end가 동일한 node에 올라감을 확인한다.
#@조건에 맞는 label이 생성되어 pending -> running 됨을 확인한다.
root@ip-172-31-4-27:~/pod_affinity# kubectl get po
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 59s
front-end 1/1 Running 0 3m45s
pod-affinity 시나리오 2
1.pod-affinity 생성 시도
2.조건에 만족하지 않음으로 pending됨을 확인 (사유 : required -> matchExpressions -> db2라는 label의 pod가 있어야 생성된다)
3.db2 pod 생성
4.조건에 부합하여 pending되어 있던 pod-affinity가 running됨을 확인한다
5.db2라는 label의 pod가 있어야 생성된다
시작
1.pod-affinity.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: team
labelSelector:
matchExpressions:
- {key: type, operator: In, values: [db2]} #db2라는 label의 pod가 있어야 생성된다
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
2.db2.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: db2
labels:
type: db2
spec:
nodeSelector:
team: prod
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
3.생성 및 확인
$ kubectl create -f pod-affinity.yaml
pod/pod-affinity created
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
db 1/1 Running 0 5m23s 192.168.137.98 ip-172-31-4-27 <none> <none>
front-end 1/1 Running 0 6m27s 192.168.137.99 ip-172-31-4-27 <none> <none>
pod-affinity 0/1 Pending 0 22s <none> <none> <none> <none>
#@ 조건에 만족하지 않음으로 pending됨을 확인
root@ip-172-31-4-27:~/pod_affinity# kubectl get po
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 2m47s
front-end 1/1 Running 0 5m33s
pod-affinity 0/1 Pending 0 7s
$ kubectl create -f db2.yaml
pod/db2 created
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
db 1/1 Running 0 5m42s 192.168.137.98 ip-172-31-4-27 <none> <none>
db2 0/1 ContainerCreating 0 4s <none> ip-172-31-13-180 <none> <none>
front-end 1/1 Running 0 6m46s 192.168.137.99 ip-172-31-4-27 <none> <none>
pod-affinity 0/1 ContainerCreating 0 41s <none> ip-172-31-13-180
#@ 조건에 부합하여 pending되어 있던 pod-affinity가 running됨을 확인한다
#@ #db2라는 label의 pod가 있어야 생성된다
root@ip-172-31-4-27:~/pod_affinity# kubectl get po
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 3m12s
db2 1/1 Running 0 9s
front-end 1/1 Running 0 5m58s
pod-affinity 1/1 Running 0 32s
Anti-affinity 시나리오
1.primary 생성 시도, 완료
2.secondary 생성 시도, 완료
# primary는 마스터에, secondary는 워커에 배포됨을 확인
# kubectl get nodes --show-labels
# 이전에 kubectl label node ip-172-31-4-27 team=dev
# kubectl label node ip-172-31-13-180 team=prod 로 설정해 두었기 때문에 아래와 같은 결과가 나옴
시작
1.primary.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: primary
labels:
role: primary
spec:
nodeSelector:
team: dev # team dev에 배포가 되도록 셋팅
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
2.secondary.yaml 명세서 작성
apiVersion: v1
kind: Pod
metadata:
name: secondary
spec:
affinity:
podAntiAffinity: # primary와 다른 node에 배포되도록 설정
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: team
labelSelector:
matchExpressions:
- {key: role, operator: In, values: [primary]}
containers:
- name: container
image: nginx
terminationGracePeriodSeconds: 0
3. 생성 및 확인
$ kubectl create -f primary.yaml
pod/primary created
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 0/1 ContainerCreating 0 4s <none> ip-172-31-4-27 <none> <none>
root@ip-172-31-4-27:~/anti_affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 1/1 Running 0 19s 192.168.51.220 ip-172-31-4-27 <none> <none>
$ kubectl create -f secondary.yaml
pod/secondary created
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 1/1 Running 0 21s 192.168.137.100 ip-172-31-4-27 <none> <none>
secondary 0/1 ContainerCreating 0 4s <none> ip-172-31-13-180 <none> <none>
# primary는 마스터에, secondary는 워커에 배포됨을 확인
# 이전에 kubectl label node ip-172-31-4-27 team=dev
# kubectl label node ip-172-31-13-180 team=prod 로 설정해 두었기 때문에 아래와 같은 결과가 나옴
root@ip-172-31-4-27:~/anti_affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 1/1 Running 0 41s 192.168.51.220 ip-172-31-4-27 <none> <none>
secondary 1/1 Running 0 7s 192.168.82.43 ip-172-31-13-180 <none> <none>
# 배포된것 모두 삭제
$ kubectl delete deploy --all
$ kubectl delete po --all
pod "primary" deleted
pod "secondary" deleted
시나리오
1.primary에 team: prod 로 nodeSelector를 변경한다. (즉, worker 노드에 생성하겠다는 의미)
2.secondary pod를 생성 시도 (podAntiAffinity 옵션으로 primary와 다른 node에 설정 옵션 있음)
3.secondary가 worker노드에 생성됨
4.primary pod 생성 시도
5.primary가 pending됨 (이유 : worker 노드에 생성되도록 nodeSelector를 설정했는데 이미 secondary가 있으므로)
6.secondary pod 삭제 시도, 완료
7.primary pod 가 pending -> running으로 변경
8.secondary pod 생성 시도, 완료
시작
1.primary.yaml 의 team: prod로 변경
2. 생성 및 확인
$ kubectl create -f secondary.yaml
pod/secondary created
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
secondary 0/1 ContainerCreating 0 4s <none> ip-172-31-13-180 <none> <none>
# primary가 없기 때문에 secondary는 아무곳에나 적용됨을 확인
root@ip-172-31-4-27:~/anti_affinity# kubectl create -f secondary.yaml
pod/secondary created
root@ip-172-31-4-27:~/anti_affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
secondary 1/1 Running 0 33s 192.168.82.44 ip-172-31-13-180 <none> <none>
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
secondary 1/1 Running 0 19s 192.168.235.186 ip-172-31-13-180 <none> <none>
$ kubectl create -f primary.yaml
pod/primary created
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 0/1 Pending 0 3s <none> <none> <none> <none>
secondary 1/1 Running 0 30s 192.168.235.186 ip-172-31-13-180 <none> <no
#anti 때문에 서로 다른 노드에 배정되어야 하는데 secondary때문에 primary가 pending됨을 확인한다
root@ip-172-31-4-27:~/anti_affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 0/1 Pending 0 5s <none> <none> <none> <none>
secondary 1/1 Running 0 59s 192.168.82.44 ip-172-31-13-180 <none> <none>
$kubectl describe po primary
#생략
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 26s (x2 over 26s) default-scheduler 0/2 nodes are available: 1 node(s) didn't match node selector, 1 node(s) didn't match pod affinity/anti-affinity, 1 node(s) didn't satisfy existing pods anti-affinity rules.
$ kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
ip-172-31-4-27 Ready master 3d17h v1.19.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-172-31-4-27,kubernetes.io/os=linux,node-role.kubernetes.io/master=,team1=dev,team=dev
ip-172-31-13-180 Ready <none> 3d12h v1.19.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-172-31-13-180,kubernetes.io/os=linux,node=worker,prod=true,team2=dev,team=prod
#@ 마스터와 워커의 label 확인
root@ip-172-31-4-27:~/anti_affinity# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
ip-172-31-13-180 Ready <none> 2d1h v1.19.4 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-172-31-13-180,kubernetes.io/os=linux,nfs=node2,prod=true,team2=dev,team=prod
ip-172-31-4-27 Ready master 2d1h v1.19.4 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-172-31-4-27,kubernetes.io/os=linux,nfs=node1,node-role.kubernetes.io/master=,team1=dev,team=dev
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 0/1 Pending 0 2m50s <none> <none> <none> <none>
secondary 1/1 Running 0 3m17s 192.168.235.186 ip-172-31-13-180 <none> <none>
$ kubectl delete po secondary
pod "secondary" deleted
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 1/1 Running 0 3m41s 192.168.235.187 ip-172-31-13-180 <none> <none>
#@ secondary가 삭제 되었기 때문에 primary가 배포됨을 확인한다
root@ip-172-31-4-27:~/anti_affinity# kubectl delete po secondary
pod "secondary" deleted
root@ip-172-31-4-27:~/anti_affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 1/1 Running 0 2m29s 192.168.82.45 ip-172-31-13-180 <none> <none>
$ kubectl create -f secondary.yaml
pod/secondary created
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 1/1 Running 0 3m56s 192.168.235.187 ip-172-31-13-180 <none> <none>
secondary 0/1 ContainerCreating 0 2s <none> ip-172-31-4-27 <none>
#@ 서로 다른 노드에 정상 pod가 생성됨을 확인한다.
root@ip-172-31-4-27:~/anti_affinity# kubectl create -f secondary.yaml
pod/secondary created
root@ip-172-31-4-27:~/anti_affinity# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
primary 1/1 Running 0 3m2s 192.168.82.45 ip-172-31-13-180 <none> <none>
secondary 1/1 Running 0 11s 192.168.51.221 ip-172-31-4-27 <none> <none>