티스토리 뷰

해당 포스팅은 "쿠버네티스 완벽 가이드" 책을 많이 참고해서 작성되었습니다.


Kubernetes의 스케줄링에는 필터링 과정과 스코어링 과정이 있습니다. 

 

* 필터링(단정)에서는 스케줄링하는 파드가 할당 가능한 노드를 계산합니다. 예를들어 파드를 스케줄링하는 데 충분한 리소스가 있는지 또는 필수 조건으로 지정한 레이블을 가진 노드인지 등을 체크합니다.

 

* 스코어링(우선순위)에는는 필터링된 후 노드 목록에 순위를 매겨 가장 적합한 노드를 계산합니다. 우선순위 조건으로 지정한 레이블을 가진 노드를 우선적으로 처리합니다.

 

따라서, 필터링이나 스코어링을 지정하지 않아도 Kubernetes가 자동으로 계산되어 스케줄링에 사용되는게 가장 큰 장점입니다.

 

Kubernetes 스케줄링 분류는 다음과 같습니다.

 

Kubernetes 사용자가 배치하고 싶은 노드를 선택하는 방법은 아래 표와같이 5가지로 나눌 수 있고, 스케줄링에는 Affinity와 Anti-Affinity를 많이 사용하며 Affinity는 특정 조건과 일치하는 곳에 스케줄링하고, Anti-Affinity는 특정 조건과 일치하지 않는 곳에 스케줄링합니다.

분류 스케줄링 기법 개요 비고
Kubernetes 사용자가 배치하고 싶은 노드를 선택하는 방법 nodeSelector (1) 단순한 Node Affinity 기능 Filtering
Node Affinity (2) 특정 Node상에서만 실행 Filtering / Scoring
Node Anti-Affinity (3) 특정 Node 이외에서 실행 Filtering / Scoring
Inter-Pod Affinity (4) 특정 Pod가 존재하는 Node에서 실행 Filtering / Scoring
Inter-Pod Anti-Affinity (5) 특정 Pod가 존재하지 않는 Node에서 실행 Filtering / Scoring
Kuberntes 관리자가 배치하고 싶지 않는 노드를 지정하는 방법 Taints / Tolerations (6)   Filtering / Scoring

 

nodeSelector (1)

가장 단순한 방법으로 예를들어 servicetype=web 레이블을 가진 특정 노드에 배치하는 스케줄링 가능합니다. nodeselector는 다중조건으로 지정할 수 없고 단일 조건만 지정이 가능합니다.

 

Node Affinity (2)

파드를 특정 노드에 스케줄링하는 정책입니다. deployment에 spec.affinity.nodeAffinity에 작성하여 설정합니다.

또한, 아래 표와 같이 필수 스케줄링 정책과 우선 스케줄링 정책이 있습니다.

아래 예제는 필수조건으로 servicetype이 web이어야 한다라는 정책이 들어가있습니다. 따라서, 필수 스케줄링 정책이 적용되어 노드에 servicetype=web인 label이 들어가있다면 해당 노드에 Pod가 배포되는것입니다.

설정항목 개요
requiredDuringSchedulingIgnoredDuringExecution 필수 스케줄링 정책
preferredDuringSchedulingIgnoredDuringExecution 우선적으로 고려되는 스케줄링 정책
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          	nodeSelector:
              - matchExpressions:
                  - key: servicetype
                    operator: In
                    values:
                      - web
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
             preference:
               matchExpressions:   
               - key: kubernetes.io/hostname
                 operator: In
                 values:
                 - devops-k8s-1

조금더 자세히 살펴보자면 아래처럼 노드 3개가 있다고 가정합니다.

 

노드1 -

servicetype: web / kubernetes.io/hostname: devops-k8s-1

 

노드2 -

servicetype: db / kubernetes.io/hostname: devops-k8s-2

 

노드3 -

servicetype: web / kubernetes.io/hostname: devops-k8s-3

 

위와같이 노드3개가 있을때 노드1을 Unschedulable 상태로 두고 배포하게 되면 노드3이 살아있기때문에 필수 스케줄링 정책이 부합되는 노드가 살아있으므로 Pod가 정상정으로 스케줄링됩니다. preferredDuringSchedulingIgnoredDuringExecution 정책은 어디까지나 우선적으로 스케줄링 정책이므로 values 값이 devops-k8s-1이 없어도 정상적으로 Pod는 스케줄링 됩니다.

 

하지만, 노드3개는 동일하고 필수 스케줄링 정책에 value를 web도 아니고 db도 아닌 spring을 넣었을때는 필수조건을 만족하는 노드가 아예 없으므로 Pod는 스케줄링 되지 않습니다.

 

Node Anti-Affinity (3)

Pod를 특정 노드 이외의 다른 노드에 스케줄링 하는 정책입니다. 엄밀히 말하면 Node Anti-Affinity는 존재하지 않고, Node Affinity의 spec.affinity.nodeAffinity에 부정형 오퍼레이터를 지정하여 작성하면 됩니다.

 

따라서 matchExperssions의 오퍼레이터에서 사용 가능한 연산자를 파악할 필요가 있습니다. 위에서 Node Anti-Affinity에서는 부정형 오퍼레이터를 사용한다고 말씀드렸는데, 대표적인 부정형 오퍼레이터는 NotIn, DoesNotExist이며, 경우에 따라서는 Gt와 Lt가 됩니다.

 

matchExperssion에서 사용 가능한 오퍼레이터는 다음 표와 같습니다.

오퍼레이터 종류 사용 방법 의미
In A In [B,...] 레이블 A의 값이 [B, ...]중 어느 하나 이상과 일치
NotIn A NotIn [B, ...] 레이블 A의 값이 [B, ...]중 어느 것에도 일치하지 않음
Exists A Exists [] 레이블 A가 존재
DoesNotExist A DoesNotExist [] 레이블 A가 존재하지 않음
Gt A Gt [B] 레이블 A의 값이 B보다 큼
Lt A Lt [B] 레이블 A의 값이 B보다 작음
In 오페레이터는 values 레이블에 하나 이상의 값을 지정하고 key 레이블 값이 values 중 어느 하나에 일치하는 것이 조건입니다. Notin 오퍼레이터는 key 레이블 값이 values 레이블 중 어느 하나에도 일치하지 않는 것이 조건입니다.
Exists 오퍼레이터는 values 레이블을 지정할 수 없습니다. Key 레이블이 존재하는지 여부만이 조건입니다.
Gt / Lt 오퍼레이터는 values 레이블에 하나의 정수 값만 지정해 Gt 오퍼레이터의 경우 key 레이블 값이 values 레이블로 지정된 값보다 큰 것이 조건이고 Lt는 반대입니다.

 

Inter-Pod Affinity (4)

특정 파드가 실행되는 노드에 Pod를 스케줄링 하는 정책입니다. Pod 정의 안에 spec.affinity.podAffinity에 조건을 지정하여 PodAffinity를 설정하고 Pod끼리는 가까이 배치할 수 있으므로 Pod간 통신 레이턴시를 낮출 수 있습니다.

 

아래 설정을 보면 Node Affinity와 구조가 비슷하지만 한 가지 다른점은 topologyKey가 추가된 부분입니다. topologyKey는 어느 범위(도메인)를 스케줄링 대상으로 할지를 지정합니다. 아래 설정값으로 보자면 app=hansung-devops 레이블을 가진 Pod가 실행되는 노드의 kubernetes.io/hostname과 같은 값을 가진 노드에 스케줄링한다. 조금 더 쉽게 말하자면 app=hansung-devops 레이블을 가진 파드와 같은 노드에 스케줄링 되는 의미입니다.

Node Affinity와 마찬가지로 requiredDuringSchedulingIgnoredDuringExecution, preferredDuringSchedulingIgnoredDuringExecution 설정이 사용하는데 위에서 설명한 그대로 입니다. 똑같이 필수 스케줄링 정책과 우선적으로 고려되는 스케줄링 정책을 지정할 수 있습니다.

    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - hansung-devops
              topologyKey: "kubernetes.io/hostname"

 

□ Taints / Tolerations (6)

지금까지 설명한 NodeSelector나 Node / Pod Affinity는 Pod를 스케줄링 할 때 Kubernetes 사용자가 특정 노드를 선택해하는 스케줄링 정책이었습니다. 반면 Taints, Tolerations는 반대 개념으로 Kubernetes 관리자가 배치하고 싶지 않는 노드를 지정하는 방법입니다.

기존 방식은 Pod가 요청하고 노드가 응답을 반환하는 형태였지만, 이번엔 반대로 Pod가 제시하고 노드가 허가하는 형태로 스케줄링합니다. Node Affinity 에서는 지정하지 않을 경우 어느 노드에나 스케줄링 되지만, 반대로 Taints, Tolerations 경우네는 지정하지 않는 한 노드에 스케줄링 되지 않습니다.

 

Taints는 세 가지 파라미터를 사용한 Key=Value:Effect 형식으로 구성됩니다. 노드에 Taints를 부여하려면 kubectl taint 명령어를 사용하고 삭제도 가능합니다. 또한 일괄적으로 여러 노드에 부여할 수 있습니다.

특정 노드에 Pod를 배치하지 않기를 원한다면 Taints를 사용하여야 합니다.

 

즉, Effect란 Taint가 노드에 설정될 때 어떤 효과를 가지게 될지 설정하는것입니다. (적용될 효과를 정의)

 

Taints와 Tolerations에서 사용 가능한 Effect는 종 3가지 종류가 있습니다.

Effect 종류 개요
PreferNoSchedule 가능한 한 스케줄링 하지 않음
NoSchedule 스케줄링 하지 않음(이미 스케줄링 되어있는 파드는 그대로 유지)
NoExecute 실행을 허가하지 않음(이미 스케줄링 파드는 정지됨)
* PreferNoSchedule Effect는 가능한 한 스케줄링 하지 않는 Taints Effect입니다. Pod에 Tolerations 설정이 없는 경우나 Taints에 일치하지 않는 경우에도 스케줄링 대상 노드가 됩니다.
예를들어 env=prod:PerferNoSchedule값으로 Taints가 걸려있는 노드1개가 있다고 가정했을때, 거기서 이미 가동중인 Pod들은 그대로 있고 prod용 Pod는 스케줄링되고, stage용 Pod는 다른 노드가 없으니 스케줄링 됩니다.
* NoSchedule Effect는 반드시 스케줄링하지 않는 Taints Effect입니다. Pod에 Tolerations 설정이 없을 경우나 Tolerations에 일치하지 않을 경우 스케줄링 하지 않습니다. 이미 파드가 존재하는 노드에는 나중에 Taints를 추가한 결과 조건에 맞지 않게 된 Pod가 있어도 그 Pod에는 영향을 주지 않습니다.
예를들어 위와 같이 똑같은 env=prod:PerferNoSchedule값으로 Taints가 걸려있는 노드1개가 있다고 가정했을때, 거기서 이미 가동중인 Pod들은 그대로 있고 prod용 Pod는 스케줄링되고, stage용 Pod는 prod 전용 이기때문에 스케줄링 되지 않습니다.
* NoExecute Effect는 노드상에 조건이 일치하지 않는 파드는 절대로 동작시키지 않는 Taints Effect 입니다. NoSchedule 과 마찬가지로 조건과 일치하지 않는 Pod들은 생성하지 않고 이미 기존에 있는 Pod들 중에서도 조건이 일치하지 않으면 그 Pod를 종료시켜버립니다. (기존에 실행되고 있는 Pod에게 영향을 줌)
예를들어 위와 같이 똑같은 env=prod:PerferNoSchedule값으로 Taints가 걸려있는 노드1개가 있다고 가정했을때, 거기서 이미 가동중인 Pod들 중에 조건이 일치하지 않으면 즉 prod용이 아니면 삭제됩니다. prod용 Pod는 스케줄링되고, stage용 Pod는 prod 전용 이기때문에 스케줄링 되지 않습니다.

Tolerations란 Key/Value/Effect를 지정하고 Taint에서 부여된 Key/Value/Effect가 같은 경우에 조건이 일치한다고 판단하고 허용합니다.

즉, Taint 처리가 되어 있는 work node에는 Taint에 맞는 Toleration을 가지고 있는 Pod만 배포될 수 있습니다.

 

Tolerations에서 사용 가능한 오퍼레이터

오퍼레이터 종류 개요
Equal Key와 Value가 같다.
Exists Key가 존재한다.

예를들어, 아래 node가 3개 있다고 가정합니다. 근데, node3에만 Taint 옵션을 주었습니다.

 

node1

node2

node3 (role=system:NoSchedule)

 

여기에서 pod를 배포할때 즉, deployment를 apply할때 deployment 안에 Tolerations 설정값이 없으면 node3에는 배포되지 않고 node1, node2에만 배포될 것입니다. 하지만, deployment안에 Tolerations 옵션이 key가 role이고 value가 system이고 Effect는 NoSchedule 이라고 정의가 되어있다면 node3도 용인 되어 node1, node2, node3에 고루 배포될 것입니다.

 

조금 쉽게 더 풀어보자면 

Toleration 설정이 된 Pod는 node1, node2, node3에 랜덤으로 생성될 수 있고,

Toleration 설정이 안된 Pod는 node1, node2에만 생성이 될 수 있습니다.

 

 

 

 

댓글
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30