쿠버네티스 스케줄링

코딩노잼·2022년 8월 4일
0

Overview

여기서 말하는 스케줄링이란 컨테이너 등을 생성할 때 어느 서버(노드)에 생성할지 결정하는 일을 뜻한다.

스케줄링이 필요한 사례는 다음과 같다.

  • 컨테이너가 빠른 입출력을 필요로 해서 SSD를 가진 서버에 배포하고 싶을 때
  • 무중단, 고가용성을 확보하기 위해 다른 region에 있는 서버들에 고르게 배포하고 싶을 때

이 글에서는 파드 생성과 스케줄링 과정, 스케줄링을 하기 위한 다양한 방법들에 대해 다룬다.


스케줄링 과정

파드 생성 요청 Flow

사용자가 kubectl, api로 파드 생성 요청을 보내면 클러스터에서는 다음과 같은 일이 일어난다.

  1. ServiceAccount, RBAC 을 이용한 인증, 인가 작업이 수행되고, 요청한 사용자가 실제 파드 생성 권한이 있는지 검증한다.
  2. Quota, LimitRange등을 적절히 변형하거나 검증한다.
  3. 워커 노드 중 한 곳에 실제로 파드를 생성한다

스케줄링은 위 과정 중 3번 단계에서 일어나는데, 조금 더 자세히 살펴보면 다음과 같다.

kube-scheduler 와 etcd의 역할

  1. 파드 생성 요청이 승인되면 api 서버는 파드의 nodeName 항목을 설정하지 않은 상태로 etcd 에 저장한다

    etcd는 분산 코디네이터로, 클라우드 플랫폼 환경에서 여러 컴포넌트가 정상적으로 상호작용 할 수 있도록 데이터를 조정하는 역할을 담당한다. etcd에는 api 서버만 접근 가능하기 때문에, 사용자가 kubectl get pods 명령어를 실행하면 api서버에 전달되고, api서버가 etcd 의 값을 읽어와 사용자에게 반환하게 된다.

  2. kube-scheduler 는 api 서버의 watch를 통해 파드 생성을 알게 된다

    클러스터의 kube-system 네임스페이스에는 kube-scheduler, etcd 등의 핵심 컴포넌트들이 기본적으로 실행되고 있다. 이들 또한 파드로 실행되기 때문에 kubectl get pods 명령어로 확인할 수 있다.

  3. kube-scheduler 는 파드를 할당할 적절한 노드를 선택하고, 해당 파드와 노드를 바인딩할 것을 api 서버에 요청한다.
  4. api서버는 etcd 에 nodeName 항목 값을 업데이트한다

3번 단계의 '파드를 할당할 적절한 노드를 선택' 하는 일은 어떻게 일어나게 될까?

파드가 생성될 노드를 선택하는 스케줄링 과정

  1. 노드 필터링 : 파드를 할당할 수 없는 노드를 필터링하는 과정. 필요한 만큼의 가용 자원이 없거나 장애가 발생한 워커 노드 등은 제외된다.
  2. 노드 스코어링 : 쿠버네티스의 소스코드에 미리 정의된 알고리즘의 가중치에 따라 점수가 계산되고, 점수가 높은 노드가 선택된다. 예를 들어, 파드가 사용하는 도커 이미지가 이미 노드에 존재할 때는 빠르게 파드를 생성할 수 있기 때문에 노드의 점수가 증가한다.

사용자는 보통 노드 필터링 단계에 적용할 수 있는 설정을 yaml 파일에 설정하여 스케줄링에 관여하게 된다.


다양한 스케줄링 방법들

NodeSelector, Node Affinity, Pod Affinity

  • NodeName 에 직접 노드 이름 명시하기
  • NodeSelector 로 <키=값> 라벨 설정하여 라벨이 붙은 노드에만 생성되도록 하기
  • Node Affinity
    • 반드시 충족해야 하는 조건(Hard) :
      requiredDuringSchedulingIgnoredDuringExecution
    • 선호하는 조건(Soft) : prefferedDuringSchedulingIgnoredDuringExecution (가중치도 설정 가능함)
apiVersion: v1
kind: Pod
metadata:
  name: nginx-nodeaffinity-preferred
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 80               # 조건을 만족하는 노드에 1~100까지의 가중치를 부여
        preference:
          matchExpressions:
          - key: mylabel/disk
            operator: In
            values:
            - ssd
  containers:
  - name: nginx
    image: nginx:latest
  • Pod Affinity : 특정 조건을 만족하는 파드와 같은 노드에서 함께 실행되도록 스케줄링 (설정 방법은 Node Affinity 와 같음)

Taints와 Tolerations

  • Taints : 특정 노드에 Taints(얼룩)을 지정함으로써 파드 할당을 막는 기법
    • key=value 형태로 설정
    • effect 추가 설정 가능
      • NoSchedule : 파드를 스케줄링 하지 않음 (마스터 노드에 기본적으로 붙어있는 Taints)
      • NoExecute : 파드의 실행을 허용하지 않음
      • PreferNoSchedule : 가능하면 스케줄링 하지 않음
  • Tolerations : 어떤 Taints 에 대응하는 Tolerations(용인)을 설정하면 Taints 노드에도 할당될수 있음

Cordon, Drain 및 PodDistributionBudget

  • Cordon : Kubectl cordon <nodeName> 명령어를 사용하면 노드에 NoSchedule Taints 가 붙음
  • Drain : kubectl drain <nodeName> cordon + 실행중인 파드도 다른 노드로 옮겨짐. 커널 버전 업그레이드, 유지보수 등 이유 때문에 노드를 잠시 중지할 때 사용.
  • PodDistributionBudget : drain에 의해 파드 옮겨질때 유지되어야 하는 파드 수 지정

커스텀 스케줄러 및 스케줄러 확장


References

  • 시작하세요 도커 쿠버네티스
profile
올해는 진짜 블로그 써야지 (라고 매년 말하기)

0개의 댓글