본문 바로가기
쿠버네티스,쿠버플로우

쿠버네티스(파드 스케줄러)

by 세용용용용 2023. 7. 10.

노드 셀렉터는 파드를 특정 노드에 배치하기 위해 파드 스케줄러를 제어하는 가장 쉬운 방법!!!

- 노드에 레이블을 지정하고, 컨트롤러 및 파드 선언할떄  .spec.nodeSelector 필드로 레이블을 지정해 노드를 선택함

 

 

 

1) 노드 레이블 설정

kube-node1 노드에 gpu키와 high 값을 가지는 레이블 선언

kubectl label nodes kube-node1 gpu=high

 

kube-node2 노드에 gpu키와 mid 값을 가지는 레이블 선언

kubectl label nodes kube-node2 gpu=mid

 

kube-node3 노드에 gpu키와 low 값을 가지는 레이블 선언

kubectl label nodes kube-node3 gpu=low

 

노드에 선언된 레이블을 확인하자

kubectl get nodes --show-labels

 

 

2) 노드 셀렉터를 선언해 레플리카셋 생성

vim sy0218-rs-ns.yaml

  • apiVersion: apps/v1: 이 ReplicaSet YAML 파일이 사용하는 Kubernetes API 버전을 지정합니다.
  • kind: ReplicaSet: 이 YAML 파일이 ReplicaSet 리소스를 정의하고 있다는 것을 나타냅니다.
  • metadata: ReplicaSet 리소스의 메타데이터를 정의하는 섹션입니다.
    • name: sy0218-rs-ns: ReplicaSet의 이름을 지정합니다.
  • spec: ReplicaSet의 세부 사항을 정의하는 섹션입니다.
    • replicas: 2: ReplicaSet이 유지해야하는 파드의 복제본 수를 지정합니다.
    • selector: ReplicaSet이 관리하는 파드를 식별하기 위한 선택기(Selector)를 정의합니다.
      • matchLabels: ReplicaSet이 선택해야하는 파드의 레이블을 지정합니다. 여기서는 yname: sy0218 레이블을 가진 파드만 선택합니다.
    • template: ReplicaSet이 생성하는 파드 템플릿을 정의합니다.
      • metadata: 파드 템플릿의 메타데이터를 정의하는 섹션입니다.
        • labels: 파드의 레이블을 지정합니다. ReplicaSet이 선택할 때 사용되는 레이블입니다.
          • yname: sy0218: 이 파드 템플릿이 가지는 레이블입니다.
      • spec: 파드 템플릿의 사양을 정의하는 섹션입니다.
        • nodeSelector: 파드를 실행할 노드를 선택하는 노드 선택기를 지정합니다. 여기서는 gpu: high 레이블이 있는 노드만 선택합니다.
        • containers: 파드 내에 실행될 컨테이너를 정의하는 섹션입니다.
          • name: sy0218: 컨테이너의 이름을 지정합니다.
          • image: ghcr.io/c1t1d0s7/go-myweb:alpine: 사용할 컨테이너 이미지를 지정합니다   

레플리카셋 리소스를 생성

kubectl create -f sy0218-rs-ns.yaml

 

 

3) 파드가 어떤 노드에 배치됐는지 확인!!!

kubectl get pods -o wide

노드 셀렉터에 의해 kube-node1 노드에 배치된것을 확인!!!

 

 

레플리카셋 리소스 복제본 개수 3개로 확장

kubectl scale replicaset sy0218-rs-ns --replicas 3

마찬가지로 kube-node1 노드에 배치된것 확인!!

 

4) 리소스 삭제

kubectl delete replicasets.apps sy0218-rs-ns

 

 

 

어피니티

어피티니틑 선호하는 노드의 엄격함을 지정할 수 있음, 즉 특정 노드에 배치되는 것을 선호하지만 반드시 따라야 하는 것은 아닐 수도 있다는 의미!!!

 

노드 어피니티 : 파드를 특정 노드에 배치할것을 선호

파드 어피니티 : 파드 간에 같은 노드에 배치할 것을 선호

파드 안티 어피니티 : 파드 간에 다른 노드에 배치할 것을 선호

 

 

1) 노드 어피니티 실습

노드 셀렉터는 반드시 해당 레이블이 있는 노드에만 배치!!! 노드 어피니티는 파드의 배치를 특정 노드에 강제하지 않을 수도 있음!!!

 

kube-node1 노드에 키 : sy0218 값 : 1998 값을 가지는 레이블 선언 

kube-node2 노드에 키 : sy0218 값 : 1999 값을 가지는 레이블 선언

kube-node3 노드에 키 : sy0218 값 : 2000 값을 가지는 레이블 선언

 

노드에 레이블이 잘 선언되었는지 확인

kubectl get nodes --show-labels

 

(3) 노드 어피니티 적용된 리소스 만들어보자

vim sy0218-rs-nodeaff.yaml

노드에 sy0218 = 1998, sy0218=1999 레이블이 반드시 있어야됨, sy0218=titan 레이블은 선호됨(강제사항 아님)

 

 

레플리카셋 리소스 생성

kubectl create -f sy0218-rs-nodeaff.yaml

 

(4) 노드 어피티니가 적요되었는지 확인해보자

kubectl get replicasets.apps >>> 레필르카셋 리소스 확인

 

이제 파드가 어떤 노드에 배치되었는지 확인 해볼까??

kubectl get pods -o wide

잘보면 sy0218='1998', sy0218='1999' 레이블이 있는 노드1과 노드2에 배치되었음

 

(5) 리소스 삭제하자

kubectl delete replicasets.apps sy0218-rs-nodeaff

 

 

 

2) 파드 어피니티, 파드 안티 어피티니

파드 간에 같은 노드에 배치할 것인지 , 다른 노드에 배치할 것인지 선호도를 지정!!!

파드 어피니티 및 파드 안티 어피니티 에서는 requiredDuringSchedulinglgnoredDuringExection 필드를 사용하는 것이 일반적!!!

 

 

(2) 파드 안티 어피니티 실습

vim sy0218-rs-podaff-cache.yaml

yname : sy0218 레이블을 설정했고, yname, sy0218로 동작하는 애플리케이션이라 가정

또한 토폴로지키를 "kubernetes.io/hostname" 레이블을 지정하였고, yname:sy0218 파드 간에는 같은 노드에 배치될수 없도록 구성

 

kubectl create -f sy0218-rs-podantiaff.yaml >>> 리소스 생성

 

이제 파드가 어떤 노드에 배치되었는지 확인!!

kubectl get pods -o wide

다른 노드에 생성된 것을 확인할수 있음

 

kubectl scale replicaset sy0218-rs-aff-sy0218 --replicas 3

똑같이 다른 노드에 생성된 것을 확인!!!

 

다시 스케일을 2로 줄이자

kubectl scale replicaset sy0218-rs-aff-sy0218 --replicas 2

 

 

파드 안티 어피니티랑 파드 어피니티 동시 생성 예제

vim sy0218-rs-podaff-front.yaml

해당 리소스는 yname=sehoon0502 레이블을 설정했고, sehoon0502 티어로 동작하는 애플리케이션이라 가정

또한 토폴로지키를 "kubernetes.io/hostname"레이블을 지정하였고, 프론트엔트 디어 파드 간에는 같은 노드에 배치되지 않고, 뇨0218 티어 파드와 같이 배치되도록 구성!!!!

 

리소스 생성

kubectl create -f sy0218-rs-podaff-front.yaml

 

파드가 어떤 노드에 배치되었는지 확인

kubectl get pods -o wide

각 노드에 sy0218파드 sehoon0502파드 쌍이 하나씩 배치됨!!!!

 

 

테인트 및 톨러레이션

 

테인트(Taint) : 특정 노드에 더 이상 추가적인 파드가 배치 안되게 파드를 스케줄링 하지 않음!!!!

톨러레이션(Toleration) : 톨러레이션을 사용하면 테인트가 설정된 노드에 파드를 스케줄링할 수 있도록 구성할 수 있다!!!!

 

테인트와 톨러레이션을 사용하는 주요목적!!!!

- 쿠버네티스 클러스터의 노드에 특정 역할을 할당하기 위해 사용

 

ex) 마스터 노드에는 마스터 역할의 테인트를 부여 했기 때문에 특정 톨러레이션이 없는 경우 마스터 노드에 스케줄링 하지 않음!!

 

 

 

1) 테인트

노드에 테인트 설정 방법

kubectl taint node (노드이름) (key=values:EFFECT]

 

테인트 EFFECT 종류 3가지

- NoSchedule : 톨러레이션에 해당 레이블이 없는 파드는 스케줄링 못함!!!(기존파드에 적용X)

- PreferNoSchedule : 톨러레이션에 해당 레이블이 없는 파드는 스케릴링 못함!!!! 그러나.... 리소스가 부족하면 배치가능(기존파드 적용 X)

- NoExecute : 톨러레이션에 해당 레이블이 없는 파드는 스케줄링 못함!!!(기존 파드도 설정을 무시할 수 없음)

 

 

노드의 상세 정보중 테인트 관련 정보 확인!!

kubectl describe nodes | grep Taints

즉, control-plane 노드는 

"node-role.kubernetes.io/control-plane" 레이블의 키가 없으면 파드를 스케줄링 하지 않겠다 라는 테인트가 설정되어 있음, 나머지 노드에는 테인트가 없는것을 확인

 

 

**앞선 어피니티 실습서 파드가 배치되지 않은 노드에 테인트를 설정해보자**

 

(2) 노드에 테인트 설정

kubectl taint node kube-node1 env=production:NoSchedule

 

테인트 잘 설정 되었는지 확인

kubectl describe nodes | grep Taints

 

이제 실습 해보자 일단 톨러에이션이 없는 에플리카셋 생성

vim sy0218-rs-notol.yaml

해당 리소스는 톨러레이션 선언 x, 복제본 개수하나, yname=sj0913 레이블이 설정 되있고, yname=sy0218 레이블과 같은 노드에 배치되지 않는 안티 어피니티가 설정!!!!

즉 노드1에는 테인트가 설정되있기에 톨러레이션이 없으면 배치가 안됨!!, 노드2, 노드3은 yname=sy0218 레이블을 가진 파드가 있어서 안티 어티피니 설정떔시 리소스 배치가 불가

 

확인해보자 리소스 생성

kubectl create -f sy0218-rs-notol.yaml

 

파드의 배치 상태 확인

kubectl get pods -o wide

맨밑에 sy0218-rs-notol 파드가 pending 상태로 파드가 스케줄링 안되고있는 것을 확인할수 있음!!!

 

kubectl describe pod sy0218-rs-notol-qt7bj >>> Events 정보를 확인해 무슨일인지 확인해보자

두개의 노드는 파드 어피니티/ 안티 어피니티로 매칭안되고 , 하나의 노드는 테인트를 가지고 있고 톨러레이션이 없다고 보고하고 있다!!!!

 

레플리카셋 삭제

kubectl delete -f sy0218-rs-notol.yaml

 

 

이제 톨러레이션 정의가 되있는 리소스예제를 해보자

vim sy0218-rs-tol.yaml

env=production:NoSchedule 톨러레이션이 설정 되었음!!!!

 

 

리소스 생성해보자

kubectl create -f sy0218-rs-tol.yaml

 

(3) 톨러레이션을 사용한 리소스 확인

파드의 상태및 배치된 노드를 확인해보자

kubectl get pods -o wide

문제 없이 테인트 설정을 한 노드1 에 배치된 것을 확인할 수 있음!!!

 

스케일 두개로 확장해보자

kubectl scale replicaset sy0218-rs-tol --replicas 2

 

kubectl get pods -o wide >>> 다시 배치된 노드를 확인

역시나 테인트가 설정된 노드1에 배치된것을 확인할수 있다!!!

 

(4) 이제 사용했던 모든 레플리카셋 컨트롤러를 삭제하자

kubectl delete replicasets.apps --all

 

노드1에 설정한 테인트로 삭제해야된다

kubectl taint node kube-node1 env-

 

테인트 잘 삭제 되었는지 확인

kubectl describe nodes | grep Taints

 

 

커든 및 드레인

커든 : 특정 노드에 새로운 파드가 스케줄링 되지 않도록 하는 기능!!!, 현재 배치되어 동작중인 파드에는 영향을 않주고 새로 스케줄링 되지 않도록 만 하는 것이다!!!!

 

드레인 : 유지보수 목적으로 해당 노드에 파드가 없어야 하는 경우, 모든 파드는 퇴거나 다른 노드로 이전 한다. 

드레인을 설정시 모든 파드는 이전하기 전 커든이 먼저 적용됨!!!

 

 

1) 커든

(1) 노드에 커든을 설정하고 해제하는 명령

kubectl cordon (노드명)

kubectl uncordon(노드명)

 

(2) 노드1 노드2에 커든을 설정해보자!!

kubectl cordon kube-node1

kubectl cordon kube-node2 

 

커든이 적용되었는지 확인하려면 노드의 상태를 확인하면됨

kubectl get nodes

STATUS에 SchedulingDisabled로 보고하는 것을 확인할 수 있다!!!

 

 

(3) 커든이 적용된 노드에 파드가 배치되지 않는것을 확인해보자!!!!

레플리카셋 리소스 생성

vim sy0218-rs-cordon.yaml

 

파드의 배치상태를 확인해보자

kubectl get pods -o wide

확인해보면 커든이 설정되지 않음 노드3에만 두개의 파드가 배치된 것을 확인!!!

 

레플리카셋 리소스 스케일 확장해보자잇!!

kubectl scale replicaset sy0218-rs-cordon --replicas 4

 

파드 배치를 확인해보면

역시나 노드3에만 배치된것을 확인할수 있따!!!

 

이제 리소스 삭제 및 커든 해제 ㄱ ㄱ ㄱ

kubectl delete replicasets.apps sy0218-rs-cordon

 

까묵지 말규~~~ 노드에 설정된 커든도 해제 해주자

kubectl uncordon kube-node1

kubectl uncordon kube-node2

 

커든이 해제 되었는지 확인!!

kubectl get nodes

 

 

 

 

드레인

드레인은 다른노드로 이전하는 것인데 만약 드레인 설정할 노드에 데몬셋 파드가 실행중이면???!!??!

데몬셋이 실행하는 파드는 삭제되도 즉시 재실행되기에 데몬셋이 적용된 파드를 드레인 할 수 없음 ㅠㅠㅠㅠ

이럴때는 데몬셋 리소스를 무시하는 옵션을 사용해 드레인을 할 수 있다!!!!!

 

 

쿠버네티스 클러스터 전체 데몬셋 리소스를 확인해보자

kubectl get daemonsets.apps -- all-namespaces

이러한 데몬셋 떔시 기본적으로 드레인을 할 수 없음..!.!!

 

노드에 드레인ㄴ을 설정하고 해제하는 명령!!

kubectl drain (노드명) (옵션)

kubectl uncordon (노드명)

** 드레인은 커든을 시행후 파드를 이전시킴!! 별도의 드레인을 해제하는 명령은 없고 반드시 수행후 커든을 해제해야됨

 

 

 

(3) 드레인 설정

노드3에 드레인 설정해보자!!!!

kubectl drain kube-node3 >>> 오홍 에러가뜬다!!!!!!

이유는 데몬셋이 관리하는 파드들이 있기 때문임

데몬셋 파드 종료를 무시하는 옵션은 --ignore-daemonests=true다.

 

kubectl drain kube-node3 --ignore-daemonsets=true >>> 데몬셋이 관리하는 파드를 제외하고, 모든 파드가 퇴거하는 것을 확인

노드 상태 확인

kubectl get nodes

노드3이 커든 상태인 것을 확인할 수 있다

 

 

드레인 설정한 노드의 관리가 끝났으면 반드시 커든을 해제!!!!!!!!!!

kubectl uncordon kube-node3

 

kubectl get nodes  >>> 커든 해제 되었는지 노드 상태 학인!!!