안녕하세요~ 오늘은 k8s 관련된 이야기로 돌아왔어요.
그동안 deployment 로 배포하는 방법과, 운영되는 pod 들에 대해 hpa 를 통해 auto scale 하는 방법들에 대해서 알아보았는데요
오늘은 조금 더 Node 의 자원 활용을 극대화할 수 있는 Topology spread constraint 에 대해 알아보도록 할게요.
Topology spread constraint 를 적용하면 현재 운영중인 Node 에서 가용중인 Pod 의 개수를 원하는 대로 control 하거나 균등하거나 배포하는 방식을 보장할 수 있어요
한번 알아보러 가볼게요~!
Topology spread constraint
먼저 Topology spread constraint 를 왜 사용해야 할까요?
예시를 통해 한번 알아보도록 할게요.
app=foo 라는 label 을 가진 Pod 을 특정 Node 에 배포하고 싶은데요
Zone1 에는 이미 2개의 pod 가 운영되고 있고, Zone2 에는 운영중인 pod 가 없습니다
이 상황에서 pod 가 집중되는 현상을 막고 싶은데요. topology spread constraint 를 적용하지 않으면, pod 가 어디로 배포될지 보장할 수 없습니다
따라서 새롭게 pod 가 배포될 때 Zone2 로 배포하는 것을 보장하기 위해 topology spread constraint 설정을 추가하여
pod 가 배포되는 개수를 보장할 수 있습니다.
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
topologySpreadConstraints:
- maxSkew: <integer>
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
위 yaml 에 있는 설정들을 설명드리면...
설정 | 설명 | 예시 |
maxSkew | Pod 의 개수의 차이를 허용하는 상한선 | 위 예시에서는 1 이니 topology key 를 가진 node 에 속해있는 pod 의 개수 최대 상한선은 1로 맞추어야한다 |
topologyKey | Node 에 붙여진 Label 의 key | 위 예시에서는 zone 이라는 label key 를 가진 node 를 대상으로 한다 |
whenUnsatisfiable | maxSkew 를 만족하지 않을 때 어떻게 처리할 것인지 결정 | DoNotSchedule: 별도의 스케줄링을 하지 않는다 (기본값) ScheduleAnyway: maxSkew 값을 참고하지 않고, skew 의 차이를 최소화하는 전략으로 스케줄링한다. |
labelSelector | Pod 의 대상을 나타냄 | 위 예시에서는 app=foo 라는 label 을 가진 pod 가 대상 |
따라서 모든 pod 가 리소스가 동일하게 사용하는 상황에서 운영중인 k8s cluster 의 리소스를 최대 효율적으로 활용하기 위해서는
maxSkew 를 1 로 설정하는 것이 일반적이다 라고 볼 수 있겠네요
위에 상황은 단순화된 예시라서, 이해를 확실하게 하기 위해 조금 더 고도화 된 예시로 한번 넘어가볼게요
Advance
위와 같이 조금 더 복잡한(?) 상황에서 어떻게 동작할지를 한번 알아볼게요.
Zone1 이라는 위치에는 Node 는 A,B 2개로 존재하고, app=foo 라는 pod 는 3개 배포되어 있고,
Zone2 이라는 위치에는 Node 는 X,Y 2개로 존재하고, app=foo 라는 pod 는 2개 배포되어 있습니다.
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: foo
zone 을 기반으로 하는 topologyKey 는 zone1 과 zone2 를 비교하게 됩니다.
- zone1 로 배포하면 zone1[4개], zone2[2개] 로 되어 maxSkew 가 4-2=2 가 되어 위반하게 됩니다.
- zone2 로 배포하면 zone1[3개], zone2[3개] 로 되어 maxSkew 가 3-3=0 이 되어 만족합니다.
따라서 무조건 zone2 가 배포 대상으로 선정하게 되는 것이죠
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: node
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: foo
node 를 기반으로 하는 topologyKey 는 nodeA, nodeB, nodeX, nodeY 를 비교하게 됩니다.
- nodeA 로 배포하면 nodeA[1개], nodeB[3개], nodeX[2개], nodeY[0개] 로 되어 각 Node 간의 개수 차이가 skew 가 1로 되어 만족합니다.
- nodeB 로 배포하면 nodeA[0개], nodeB[4개], nodeX[2개], nodeY[0개] 로 되어 skew 가 4가 되어 위반하게 됩니다.
- nodeX 로 배포하면 nodeA[0개], nodeB[3개], nodeX[3개], nodeY[0개] 로 되어 skew 가 3이 되어 위반하게 됩니다.
- nodeY 로 배포하면 nodeA[0개], nodeB[3개], nodeX[2개], nodeY[1개] 로 되어 skew 가 1이 되어 만족합니다.
따라서 nodeA 혹은 nodeY 로 배포 대상이 선정하게 됩니다.
결과적으로 2개의 topologySpreadConstraint 를 모두 만족하는 zone2 의 nodeY 로 배포 대상이 결정되게 됩니다
만일, 2개의 topologySpreadConstraint 에서 교집합이 발생하지 않는다면 어떻게 될까요?
바로 Pod 가 배포될 수 없는 Pending 상태로 이어지게 됩니다.
즉, 2개 이상의 topologySpreadConstraint 를 사용할 때는 조금 더 신중해야 겠네요
생각하며
개인적인 생각으로는 topologySpreadConstraint 를 복잡하게 가져가는 전략은 가급적 하지 않으면 좋겠네요.
배포 설정이 많아질 수록, 어떻게 배포될지 생각하기가 많이 어렵고 돌발상황들을 만들 수 있기 때문에
가장 간단한 설정으로 풀어나가는 것이 현명할 수 있어요.
어떻게 보면 whenUnsatisfies 에서 ScheduleAnyway 전략을 선택하는 것이 운영상 심플하고 현명할 수 있죠
하지만 이건 제 개인적인 생각이기에 각자의 상황에 맞는 인프라 조건에 따라 설정 전략을 유동적으로 생각하면 좋겠습니다! :)
간단하게 정리하고 이번 게시글도 마쳐볼게요 ㅎㅎ
- topologySpreadConstraint 를 통해 Pod 가 어디로 배포될지 결정할 수 있다
- topologyKey 에 따라 skew 를 계산하게 된다
- labelSelector 로 계산하는 대상의 pod 를 선정하게 된다
- topologySpreadConstraint 는 운영되고 있는 현황에 맞추어 전략을 설정하자
참고
파드 토폴로지 분배 제약 조건
Introducing PodTopologyThread
'Developer > Kubernetes' 카테고리의 다른 글
[K8S] Secret - 비밀 정보 관리 (1) | 2024.04.19 |
---|---|
[K8S] HPA - 쿠버네티스 Horizontal Pod AutoScaler (2) | 2021.12.26 |
[k8s/쿠버네티스] - Deployment로 애플리케이션 배포 (0) | 2020.07.20 |
Docker - python server기반 Dockerfile을 만들어보자 (0) | 2020.07.04 |
[쿠버네티스 입문] - Pod 운영 (0) | 2019.01.15 |