Devops/Kubernetes

[Kubernetes] 한 노드에 동일한 파드 스케줄링 제한

dev_ss 2024. 11. 24. 23:13

 

 

 


개요

 

쿠버네티스 클러스터 환경에서 운영을 할 때에는, 생각하지 못한 다양한 상황을 많이 접할 수 있다.

 

 

그중 하나는 Deployments의 파드가 재 스케줄될 때, 상황에 따라 하나의 노드에 같은 파드가 두 개 이상 스케줄될 수 있다는 것이다.

 

 

이것이 문제가 되는 이유는 Deployments의 Replicas가 2인 경우 하나의 노드에 이 파드가 2개가 생성된다면, 단일 장애 지점(SPOF)이 되어버린다는 것이다.

 

 

가용성을 위하여 파드를 2개로 설정을 했음에도, 노드에 장애가 발생하면 가용성을 보장받지 못하는 상황이 되어버린다는 것이다.

 

 

물론 쿠버네티스에는, 이를 방지하기 위한 설정이 존재한다.

 

이제 해당 옵션을 알아볼 것이다.

 


 

아래는 replicas가 2인 nginx라는 deployment의 내용이다.

 

 

 

옵션을 하나하나 찾아본다면 알 수 있겠지만, 파드의 스케줄링에 관한 옵션이 없다는 것을 알 수 있을 것이다.

 

 

기본적으로 Deployment를 생성할 때 아무런 제약이 없도록 생성된다는 것이다.

 

 

 

 

 

아래 쿠버네티스 레퍼런스를 읽어본다면, 어떤 파드를 어떤 노드에 배정할지에 관한 옵션에 대한 내용을 볼 수 있다.

 

 

https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/

 

Assigning Pods to Nodes

You can constrain a Pod so that it is restricted to run on particular node(s), or to prefer to run on particular nodes. There are several ways to do this and the recommended approaches all use label selectors to facilitate the selection. Often, you do not

kubernetes.io

 

 

 

여기서 눈여겨 볼 옵션은 podAffinitypodAntiAffinity이다.

 

 

 

podAffinity는 파드를 스케줄링 할 때 해당 조건을 만족한다면 파드를 배정하는 것이고,

 

podAntiAffinity는 해당 조건을 만족하면 파드를 배정하지 않겠다는 옵션을 나타내는 것이다.

 

 

 

여기서도 세부적인 옵션이 존재한다.

 

requiredDuringSchedulingIgnoredDuringExecution와 preferredDuringSchedulingIgnoredDuringExecution가 있다.

 

 

단어에서도 볼 수 있는 것처럼 required는 강제(Hard)하는 옵션이고, preferred옵션의 내용을 우선적으로(Soft) 지키고 강제는 아닌 옵션이다.

 

 

그래서 required는 옵션을 충족하지 못하면 파드는 스케줄링되지 못하여 Pending 상태가 되고, preferred는 그렇지 않다는 차이점이 존재한다.

 

 

 

 

그렇다면 이제 제목에서 본 것 처럼 하나의 노드에 동일한 파드를 제한할 수 있을 것이다.

 

podAntiAffinity와 requiredDuringSchedulingIgnoredDuringExecution를 적절히 조합한다면, 동일한 파드가 하나의 노드에 스케줄 되는 것을 방지할 수 있다는 것을 알 수 있다.

 

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-cache
spec:
  selector:
    matchLabels:
      app: store
  replicas: 3
  template:
    metadata:
      labels:
        app: store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: redis-server
        image: redis:3.2-alpine

 

 

그 예시로 위와 같은 옵션이 있다면 파드는 kubernetes.io/hostname이 각각 다른 곳에 스케줄이 될 것이고 가용성을 높일 수 있을 것이다.

 


주의 사항

 

단일 노드로 운영 시 podAntiAffinity 옵션을 적용하게 된다면, 파드의 재시작이 불가능하다.

(MaxSurge의 가용성에 대한 부분과 podAntiAffinity의 파드 스케줄에 대한 제약이 충돌이 발생)

 


 

 

 

 

반응형