[kubernetes] Pod 스케줄링 조건 및 정책
[kubernetes] Pod 스케줄링 조건 및 정책
Kubernetes는 컨테이너화된 애플리케이션을 자동으로 배포, 확장, 관리하는 오픈 소스 플랫폼이며, 다양한 환경에서 일관된 애플리케이션 실행을 가능하게 해주는 컨테이너 오케스트레이션 도구입니다.
Kubernetes에서 스케줄링은 Kubelet이 Pod를 실행할 수 있도록 Pod가 Node에 적합한지 확인하는 것을 말합니다.
Pod가 배포될 때 적용되는 조건과 정책은 Pod의 배치, 리소스 할당, 네트워크, 보안 등 다양한 측면에서 영향을 미칩니다.
Kubernetes에서 다양한 환경과 조건에 유연하게 Pod를 배포하기 위한 스케줄링 조건 및 정책에 대해 알아보도록 하겠습니다.
스케줄링 조건 및 정책
Node Selector
Node Selector는 Pod가 특정 Node에 배치되도록 하기 위해 사용됩니다.
Node에 Key-Value 형태로 라벨을 추가하고, Pod의 nodeSelector
필드에 해당 라벨을 지정합니다.
지정된 라벨을 가진 Node가 없으면 Pod 배포가 불가합니다.
apiVersion: v1
kind: Pod
metadata:
name: node-selector-pod
spec:
nodeSelector:
disktype: ssd
Node Affinity
Node Affinity는 Node Selector보다 유연한 방식으로, Node에 대한 강제(required) 조건과 선호(preferred) 조건을 정의할 수 있습니다.
requiredDuringSchedulingIgnoredDuringExecution
: 반드시 조건을 만족해야만 배포preferredDuringSchedulingIgnoredDuringExecution
: 조건을 선호하지만, 만족하지 않아도 배포 가능
apiVersion: v1
kind: Pod
metadata:
name: node-affinity-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: zone
operator: In
values:
- us-west-1
Taint & Toleration
Taint는 특정 Node에 Pod 배치를 제한하거나 허용하기 위한 정책으로 사용됩니다.
Node에 Taint를 설정하고, Pod에 해당 Taint를 허용하는 Toleration을 추가하면 해당 Node에 Pod 배치가 가능합니다.
이를 통해 클러스터의 리소스를 효율적으로 활용하고, 특정 Node에서 실행할 Pod를 제어할 수 있습니다.
Node에 Taint를 추가하는 명령어입니다.
# kubectl taint nodes node1 key=value:NoSchedule
Master(Control) Node에 Pod가 배포되지 않는 이유는 아래와 같이 Taint가 설정되어 있기 때문입니다.
# kubectl describe node node1 | grep Taint
Taints: node-role.kubernetes.io/control-plane:NoSchedule
Toleration 설정을 통해 NoSchedule Taint가 설정된 Node에만 Pod를 배치할 수 있도록 허용합니다.
apiVersion: v1
kind: Pod
metadata:
name: taint-toleration-pod
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
Resource request & limit
Pod의 CPU, Memoery 등의 리소스 요청(requests) 및 제한(limits)을 설정하여, 해당 요구사항을 만족하는 Node에 배포되도록 합니다.
Pod에서 요청한 CPU/Memory를 수용할 수 없는 Node에는 배치 불가하며, 수용할 수 있는 Node가 없으면 Pod 배포는 불가합니다.
Pod가 사용하는 CPU와 메모리 리소스를 효율적으로 관리하기 위해 사용됩니다.
apiVersion: v1
kind: Pod
metadata:
name: resource-pod
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Pod Affinity & Anti-Affinity
Pod Affinity는 특정 Pod가 클러스터 내의 다른 Pod와 가까운 위치(같은 Node 또는 같은 영역(zone))에 배치되도록 스케줄링하는 기능입니다.
서비스 간 네트워크 지연을 최소화하거나, 동일한 하드웨어 리소스를 공유하여 성능을 최적화해야 하는 경우 유용합니다.
반대로, Pod Anti-Affinity는 특정 Pod가 특정 조건을 가진 다른 Pod와 떨어진 위치에 배치되도록 합니다.
Pod Affinity requiredDuringSchedulingIgnoredDuringExecution
: 반드시 조건을 만족해야만 배포
Pod Affinity preferredDuringSchedulingIgnoredDuringExecution
: 조건을 선호하지만, 만족하지 않아도 배포 가능
예시) app=frontend
라벨을 가진 Pod가 반드시 app=backend
라벨을 가진 Pod와 같은 Node에 배치되도록 설정합니다.
apiVersion: v1
kind: Pod
metadata:
name: frontend-pod
labels:
app: frontend
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- backend
topologyKey: "kubernetes.io/hostname"
containers:
- name: nginx
image: nginx
예시) app=frontend
라벨을 가진 Pod가 가능하면 app=backend
라벨을 가진 Pod와 같은 Node에 배치되도록 선호합니다.
apiVersion: v1
kind: Pod
metadata:
name: frontend-pod
labels:
app: frontend
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- backend
topologyKey: "kubernetes.io/hostname"
containers:
- name: nginx
image: nginx
예시) app=frontend
라벨을 가진 Pod가 반드시 app=frontend
라벨을 가진 다른 Pod와 다른 Node에 배치되도록 설정합니다.
apiVersion: v1
kind: Pod
metadata:
name: frontend-pod
labels:
app: frontend
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- frontend
topologyKey: "kubernetes.io/hostname"
containers:
- name: nginx
image: nginx
다영한 스케줄링 조건 및 정책을 사용하는 이유?
Kubernetes에서 다양한 스케줄링 조건 및 정책을 사용하는 이유는 클러스터의 자원 효율성, 애플리케이션 안정성, 운영 유연성을 극대화하기 위해서입니다. Kubernetes는 온프레미스, 클라우드, 하이브리드 환경 등 다양한 인프라에서 운영될 수 있으며, 각 환경과 워크로드의 요구 사항에 최적화된 배포를 지원하는 것이 중요합니다. 이러한 목적을 달성하기 위해 다양한 스케줄링 조건과 정책이 조합되어 사용됩니다.
예시 시나리오
- 고성능 워크로드 배포
- Node Affinity를 사용해 GPU를 장착한 Node에만 배포.
- Taints/Tolerations로 일반 워크로드가 GPU Node에 배치되지 않도록 설정.
- Resource Limits로 GPU 리소스를 효율적으로 할당.
- 웹 애플리케이션 배포
- Pod Affinity를 사용하여 backend 서버와 DB 서버를 같은 Node에 배포.
- Pod Anti-Affinity를 사용하여 backend 서버와 frontend 서버를 다른 Node에 배포.
- Node Selector를 사용하여 disk가 ssd인 Node에 DB 서버 배포.
- 데이터 분석 워크로드 배포
- Node Affinity로 SSD를 사용하는 Node에만 배치.
- Resource Requests로 대량의 메모리와 CPU 확보.
- Anti-Affinity로 동일한 Node에 과도한 분석 작업 배치 방지.
결론적으로는 Kubernetes의 스케줄링 조건과 정책은 클러스터의 자원 활용을 최적화하고, 다양한 환경과 워크로드에 맞춰 배포를 유연하게 조정하며, 장애 복원력과 안정성을 강화하여 전체적인 운영 효율성을 높이는 데 중요한 역할을 합니다. 이를 통해 클라우드 네이티브 환경에서의 워크로드 배포를 효과적으로 관리할 수 있습니다.
스케줄링 사용 유의점
Kubernetes에서 스케줄링을 사용할 때는 다양한 조건과 정책을 적절히 설정해야 하는데, 잘못된 설정이나 과도한 복잡성은 클러스터의 성능 저하, 운영상의 문제, 리소스 낭비 등을 초래할 수 있습니다.
Pod의 Resource Requests와 Limits를 잘못 설정하면 스케줄링 가능한 Node가 부족해지거나, Limits를 너무 낮게 설정하면 Pod이 리소스를 초과해 비정상동작할 수 있습니다. 또한 Node Affinity, Pod Affinity/Anti-Affinity, Taints와 Tolerations 등의 조건은 배포를 세밀하게 제어할 수 있지만, 너무 복잡한 조건을 설정하면 오히려 스케줄링 가능한 Node가 줄어드는 문제가 발생할 수 있습니다.
이러한 문제를 방지하기 위해 애플리케이션의 실제 리소스 요구 사항을 모니터링한 후 적절한 값을 설정하거나 필수 조건과 선호 조건을 적절히 분리하여 설정하고, 필요 이상의 복잡성을 피하는 것이 중요합니다.
Kubernetes에서 Pod 스케줄링 조건 및 정책에 대해 알아봤습니다.
Pod를 배포할 때 다양한 조건과 정책을 사용하여 클러스터의 자원 활용을 최적화하고, 애플리케이션의 안정성과 운영 효율성을 높일 수 있습니다. Node Selector와 Node Affinity를 통해 특정 Node에 Pod를 배치하거나, Taints와 Tolerations을 통해 특정 Node에서만 실행되도록 제어할 수 있습니다. 또한, Resource Request와 Limits를 활용해 Pod의 리소스를 관리하고, Pod Affinity 및 Anti-Affinity로 Pod 간의 배치 관계를 세밀히 조정할 수 있습니다.
이러한 설정을 통해 Kubernetes는 다양한 환경에서 워크로드를 유연하고 안정적으로 배포할 수 있으며, 클라우드 네이티브 애플리케이션의 관리를 더욱 간편하게 만듭니다.
지금까지 Deployment를 통해 pod를 배포하는 방법을 알아보는 시간을 가졌습니다.
유익하게 보셨다면 공감을 눌러주고, 댓글로 의견을 공유해 남겨주시면 감사하겠습니다!
[Reference]
https://kubernetes.io/docs/concepts/scheduling-eviction/
https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/
https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/