Today I Learned

[쿠버네티스 인 액션] 16. 고급 스케줄링 본문

쿠버네티스

[쿠버네티스 인 액션] 16. 고급 스케줄링

하이라이터 2023. 3. 30. 16:31
728x90

16장에서 다루는 내용

  • 특정 노드에서 파드가 실행되지 않도록 노드 테인트와 파드 톨러레이션 사용
  • 노드 셀렉터의 대안으로 노드 어피니티 규칙 정의
  • 파드 어피니티를 사용해 파드를 함께 배치
  • 파드 안티-어피니티를 사용해 파드를 서로 떨어뜨려 놓기

16.1 테인트와 톨러레이션을 사용해 특정 노드에서 파드 실행 제한

  • 노드 셀렉터와 노드 어피니티 규칙은 특정 정보를 파드에 추가해 파드가 스케줄링되거나 될 수 없는 노드를 선택할 수 있다.
  • 테인트는 기존의 파드의 수정 없이 노드에 테인트만 추가하면 파드가 특정 노드에 배포되지 않도록 한다.

 

16.1.1 테인트와 톨러레이션 소개

노드의 테인트 표시하기

$kubectl describe node master.k8s
  • 테인트에는 키, 값, 효과가 있고 <key>=<value>:<effect> 형태로 표시된다.
  • 마스터 노드의 테인트는 node-role.kubernetes.io/master:NoSchedule을 갖는다. (value:null은 표시되지 않음)
  • 이 테인트는 파드가 이 테인트를 허용하지 않는 한 마스터 노드에 스케줄링되지 못하게 막는다.

파드의 톨러레이션 표시하기

  • kubeadm으로 설치한 클러스터에는 마스터 노드를 포함해 모든 노드에서 kube-proxy 클러스터 컴포넌트가 파드로 실행된다.
  • 파드로 실행되는 마스터 노드 컴퍼넌트도 쿠버네티스 서비스에 접근해야할 수 있기 때문에 kube-proxy가 마스터 노드에서 실행되며 이를 위한 적절한 톨러레이션을 포함한다.

 

테인트 효과 이해하기

  • kube-proxy의 다른 두 가지 톨러레이션은 준비되지 않았거나(notReady), 도달할 수 없는 (unreachable) 노드에서 파드를 얼마나 오래 실행할 수 있는지를 정의한다.
  • 각 테인트의 효과는 다음과 같다.
    • NoSchedule: 파드가 테인트를 허용하지 않는 경우 파드가 노드에 스케줄링되지 않는다.
    • PreferNoSchedule: NoSchedule의 소프트한 버전. 스케줄러가 파드를 노드에 스케줄링하지 않으려 하지만 다른 곳에 스케줄링할 수 없으면 해당 노드에 스케줄링된다.
    • NoExecute: 스케줄링에만 영향을 주는 NoSchedule이나 PreferNoSchedule과 달리, NoExecute는 노드에서 이미 실행중인 파드에도 영향을 준다. NoExecute 테인트를 노드에 추가하면 해당 노드에서 이미 실행중이지만 NoExecute 테인트를 허용하지 않은 파드는 노드에서 제거된다.

 

16.1.2 노드에서 사용자 정의 테인트 추가하기

  • 프로덕션 워크로드와 프로덕션이 아닌 워크로드를 하나의 쿠버네티스에 실행한다면, 프로덕션 노드에서 프로덕션이 아닌 파드가 실행되지 않도록 해야한다.

  • 프로덕션 노드에 NoSchedule 효과를 갖는 테인트를 추가하면 일반적인 파드는 스케줄링되지 않는다.

 

16.1.3 파드에 톨러레이션 추가

  • 위 디플로이먼트를 배포하면 해당 노드가 프로덕션 노드에 배포된다.

  • 하지만 프로덕션 노드가 아닌 node2에도 파드가 배포됐는데, 이러한 상황이 발생하지 않게 하려면 프로덕션이 아닌 노드에 node-type=non-production:NoSchedule과 같은 테인트를 추가한다.

 

16.1.4 테인트와 톨러레이션의 활용 방안 이해

스케줄링에 테인트와 톨러레이션 사용하기

  • 테인트는 새 파드의 스케줄링을 방지(NoSchedule)하고, 선호하지 않는 노드를 정의(PreferNoSchedule)하고, 노드에서 기존 파드를 제거(NoExcute)하는 데 사용할 수 있다.

노드 실패 후 파드를 재스케줄링하기까지의 시간 설정

  • 이 두 톨러레이션은 파드가 notReady 또는 unreachable 상태를 300초동안 허용한다는 것을 의미한다.
  • 톨러레이션을 별도로 정의하지 않은 파드에 자동으로 추가되며, 지연 시간을 조정할 수도 있다.

16.2 노드 어피니티를 사용해 파드를 특정 노드로 유인하기

노드 어피니티와 노드 셀렉터 비교

  • 노드 셀렉터와 유사하게 각 파드는 고유한 노드 어피니티 규칙을 정의할 수 있다.
  • 이를 통해 필수 요구 사항이나 선호도를 지정할 수있다.
  • 선호도를 지정하면 쿠버네티스는 해당 노드 중 하나에 파드를 스케줄링하려고 시도하며, 불가능할 경우 다른 노드를 선택한다.

디폴트 노드 레이블 검사

  • 노드 어피니티와 파드 어피니티에 있어서 마지막 세 개의 레이블이 중요하다.
  • 이 세 레이블의 의미는 다음과 같다.
    • failure-domain.beta.kubernetes.io/region: 노드가 위치한 지리적 리전(region)을 지정
    • failure-domain.beta.kubernetes.io/zone: 노드가 있는 가용 영역(zone) 지정
    • kubernetes.io/hostname: 노드의 호스트 이름
  • 이 레이블과 그 외 다른 레이블이 파드 어피니티 규칙에 사용될 수 있다.

 

16.2.1 하드 노드 어피니티 규칙 지정

  • 3장의 예제에서 노드 셀렉터를 사용해 GPU가 있는 노드에만 파드를 배포하는 방식은 다음과 같았다.

  • 이 노드 셀렉터를 노드 어피니티 규칙으로 바꾸면 파드 정의는 다음과 같아진다.

  • 노드 셀렉터보다 훨씬 복잡한 이유는 표현력이 훨씬 풍부하기 때문이다.

 

긴 nodeAffinity 속성 이름 이해

  • requiredDuringScheduling ... 이 필드 아래에 정의된 규칙은 파드가 노드로 스케줄링되고자 가져야하는 레이블을 지정한다.
  • ...IgnoredDuringExecution 이 필드 아래에 정의된 규칙은 노드에서 이미 실행중인 파드에는 영향을 미치지 않는다.

 

nodeSelectorTerm 이해

  • nodeSelectoerTerms 필드와 matchExpressions 필드는 파드를 노드에 스케줄링하고자 노드의 레이블이 일치하도록 표현식을 정의하는 데 사용된다.

 

16.2.2 파드의 스케줄링 시점에 노드 우선순위 지정

  • 노드 어피니티를 사용하면 스케줄링 중에 노드의 우선 순위를 지정할 수 있다.

 

노드 레이블링

  • 각 노드에는 노드가 속한 가용 영역을 지정하는 레이블과 전용 또는 공유 노드로 표시하는 레이블이 있어야 한다.

 

선호하는 노드 어피니티 규칙 지정

  • 이제 zone1의 dedicated 노드를 선호하는 디플로이먼트를 생성할 수 있다. 다음 예제는 디플로이먼트 매니페스트를 보여준다.

  • 필수 요구 사항 대신 노드 어피니티 선호도를 정의하고 있으며, available-zone=zone1과 share-type=dedicated 레이블이 포함된 노드에 파드를 스케줄링하려 한다.

 

노드의 선호도 작동 방법 이해하기

  • 이전 예제의 디플로이먼트에 파드를 스케줄링할 때, 클러스터에 노드가 많은 경우 다음 그림과 같이 노드가 네 개의 그룹으로 분할된다.
  • Availability-zone과 share-type 레이블이 파드의 노드 어피니티와 일치하는 노드에 가장 높은 순위가 매겨지며, 가중치에 따라 우선순위가 부여된다.

 

노드가 두 개인 클러스터에 파드 배포하기

  • 노드가 두 개인 클러스터에 이 디플로이먼트를 생성하면 대부분의 파드가 node1에 배포된다.

  • 파드 중 하나가 node1 대신 node2에 배포된 이유는 스케줄링 시에 노드 어피니티 우선순위 지정 기능 외에 다른 우선순위 지정 기능도 사용하기 때문이다.
  • Selector-SpreadPriority 기능이 그 중 하나인데, 동일한 레플리카셋 또는 서비스에 속하는 파드를 여러 노드에 분산시켜 노드 장애로 인해 전체 서비스가 중단되지 않도록 한다.

16.3 파드 어피니티와 안티-어피니티를 이용해 파드 함께 배치하기

  • 노드 어피니티 규칙을 사용해 프론트엔드 파드와 백엔드 파드를 동일한 노드에 배포되도록 할 수 있지만 정확한 노드를 지정해야 한다.
  • 파드 어피니티를 사용하면 두 파드를 서로 가깝게 유지하면서 적절한 곳에 배포되도록 할 수 있다.

 

16.3.1 파드 간 어피니티를 사용해 같은 노드에 파드 배포하기

  • 하나의 백엔드 파드와 다섯 개의 프론트엔드 레플리카셋을 배포할 것이며, 동일한 노드에 배치되도록 파드 어피니티를 설정할 것이다.

  • 백엔드 파드를 배포하며, -1 옵션을 사용해 파드에 추가한 app=backend 레이블은 프론드엔드 파드의 podAffinity 설정에 사용된다.

 

파드 정의에 파드 어피니티 지정

  • 다음은 프론트엔드 파드의 정의이다.

 

파드 어피니티를 갖는 파드 배포하기

  • 백엔드파드가 어떤 노드에 스케줄링돼 있는지 확인한 후, 프론트엔드 파드를 생성해서 어디에 배포되는지 살펴보자.

  • 스케줄러는 먼저 프론트엔드 파드의 podAffinity 설정에 정의된 labelSelector와 일치하는 모든 파드를 찾은 다음 프론트엔드 파드를 동일한 노드에 스케줄링한다.

 

스케줄러가 파드 어피니티 규칙을 사용하는 방법 이해

  • 이제 파드 어피니티 규칙을 정의하지 않은 백엔드 파드를 삭제하더라도 스케줄러는 백엔드 파드를 node2에 스케줄링한다.
  • 백엔드 파드가 다른 노드로 스케줄링 되나면, 프론트엔트 파드의 어피니티 규칙이 깨지기 때문이다.

  • 로그의 굵은 두 줄을 보면, 백엔드 파드를 스케줄링하는 과정에서 node2가 node1보다 높은 점수를 받았다는 것을 알 수 있다.

 

16.3.2 동일한 랙, 가용 영역 또는 리전에 파드 배포

  • 모든 프론트엔드 파드가 동일한 머신에서 실행되는 것을 바라지는 않겠지만, 가용 영역에서 실행하는 것과 같이 백엔드와 가깝게 유지하길 원할 것이다.

동일한 가용 영역에 파드 함께 배포하기

  • 노드가 서로 다른 가용 영역에 있는 경우 두 파드를 동일한 가용영역에서 실행하려면 topogyKey 속성을 설정하면 된다.
topologyKey : failure-domain.beta.kubernetes.io/zone

 

같은 리전에 파드를 함께 배포하기

  • 동일한 가용영역 대신 동일한 리전에 배포하려면
topologyKey : failure-domain.beta.kubernetes.io/region

 

topologyKey 작동 방법 이해

  • 원하는 경우 자체적으로 정의한 topologyKey를 사용해 파드를 동일한 서버 랙에 쉽게 스케줄링할 수 있다.

  • 스케줄러가 파드를 배포할 위치를 결정할 때 파드의 podAffinity 구성을 확인하고 레이블 셀렉터와 일치하는 파드를 찾은 다음 파드가 실행 중인 노드를 찾는다.
  • 특히 podAffinity에 지정된 topologyKey 필드와 일치하는 키를 갖는 노드 레이블을 찾는다.
  • 그리고 레이블이 이전에 찾은 파드의 값과 일치하는 모든 노드를 선택하고 그 중의 하나에 스케줄링 된다.

 

16.3.3 필수 요구 사항 대신 파드 어피니티 선호도 표현하기

  • 노드 어피니티와 마찬가지로 파드 어피니티에서도 선호도를 지정할 수 있다.

  • 노드 어피니티 선호도 규칙과 마찬가지로 가중치를 정의해야하며, topologyKey와 labelSelector를 지정해야 한다.

 

16.3.4 파드 안티-어피니티를 사용해 파드들이 서로 떨어지게 스케줄링하기

  • 파드 어피니티와 정반대로 파드 안티-어피니티를 사용하면 파드를 서로 멀리 떨어뜨려 놓을 수 있다.
  • podAffinity 대신 podAntiAffinity 속성을 사용한다는 점만 다르며, 레이블 셀렉터와 일치하는 파드가 실행중인 노드를 선택하지 않는다.

 

같은 디플로이먼트에 파드를 분산시키기 위해 안티-어피니티 사용

  • podAntiAffinity를 정의하고 labelSelector를 생성한 후에 이 디플로이먼트를 만들어보자.

  • 단 두개의 파드만 스케줄링됐으며, 스케줄러가 동일한 노드에 스케줄링할 수 없으므로 나머지 세 개의 파드는 pending 중이다.

선호하는 안티-어피니티 사용하기

  • preferredDuringSchedulingIgnoredDuringExcution 속성을 사용해 필수 요구 사항 대신 소프트한 요구 사항을 지정할 수 있다.
  • 파드 어피니티와 마찬가지로 topologyKey 속성은 파드를 배포해서는 안되는 범위를 결정한다.

 

 

 

Q. 다음 중 테인트의 필수 값이 아닌 것은?

1. key
2. value

3. effect

 

Q. 테인트에 대한 설명으로 옳지 않은 것은?

1. 테인트에는 키, 값, 효과가 있고 <key>=<value>:<effect> 형태로 표시된다.

2. 테인트의 효과는 이미 실행중인 파드에는 영향을 줄 수 없다.

3. 톨러레이션을 사용해서 노드가 준비되지 않았다면 곧바로 다른 노드로 스케줄링되도록 할 수 있다.

4. 톨러레이션을 별도로 정의하지 않은 파드에는 자동으로 추가된다.

 

Q.파드가 스케줄링 될 노드의 우선순위(선호도)를 지정하는 데 사용되는 기능은?

1. 테인트

2. 톨러레이션

3. 노드 어피니티

4. 파드 어피니티

 

Q.다음 중 어피니티에 대한 설명으로 옳지 않은 것은?

1. 어피니티 설정에 있어 가장 중요한 레이블은 region, zone, hostname이다.

2. 노드 어피니티 규칙을 사용해 서로 다른 파드를 동일한 노드에 배포하려면 정확한 노드를 지정해야만 한다.

3. 파드 어피니티 설정에서 자체적으로 정의한 topologyKey를 사용하려면 노드의 레이블명이 필요하다.

 

 

Q.안티-어피니티에 대한 설명으로 옳지 않은 것은?

1. 파드 안티-어피니티를 사용하면 가용영역을 분산시켜 장애 시에 서비스가 중단되지 않도록 할 수 있다.

2. 서로 다른 노드에 스케줄링할 수 없는 경우 더이상 스케줄링 되지 못하고 pending 상태로 대기한다.

3. 안티-어피니티에서는 topology 속성을 사용할 수 없다.

 

 

Q.팀 별로 테인트만 지정하고 어피니티는 지정하지 않고 사용하는 쿠버네티스 환경에서 파드는 어떻게 배치될까?

1. 우리팀 소유의 노드에만 우리팀의 파드가 잘 배치될 것이다.

2. 우리팀 소유의 노드에 우리팀의 파드가 잘 배치되지만, 타 팀에 노드에도 우리 팀의 파드가 스케줄링될 수 있다.

3. 우리팀 소유의 노드에 우리팀의 파드가 잘 배치되지만, 타 팀의 파드가 우리팀 노드에 스케줄링될 수 있다.

 

728x90
Comments