Pod Anti-Affinity를 사용한 Kubernetes pod Multi-AZ 배포
IT/DevOps

Pod Anti-Affinity를 사용한 Kubernetes pod Multi-AZ 배포

반응형

Intro

AWS에서는 아래 그림과같이 여러개의 zone을 사용하여 HA구성을 할 수 있습니다. 관리형 쿠버네티스 서비스인 AWS EKS를 구성할때도 다중 AZ로 Node를 구성할 수 있습니다.

그러면 이렇게 노드가 여러개의 AZ로 구성되어있을 경우 pod가 다중 AZ로 배포되도록 스케줄링하려면 어떻게 해야할까요?
오늘은 그 이야기를 해보고자 합니다.

kuberntes의 기본 스케줄링 알고리즘

kubernetes 스케줄러는 기본적으로 scoring 알고리즘을 사용합니다. 이는 컨테이너에 필요한 리소스(CPU,RAM)에 적합한 노드를 자동으로 판단하여 스케줄링 할 수 있도록 합니다.

따라서 기본적으로 kubernetes스케줄러는 노드의 부하(load)에 따라서 pod를 분산하며 다중 AZ에 고르게 분산되지는 않습니다. pod가 AZ간 고르게 배포되도록 설정하기 위해서는 이 경우 Pod의 Anti-Affinity를 사용해야합니다.

Pod Anti-Affinity

Pod Anti-Affinity란 노드에서 실제 동작중인 pod의 lable 기반으로 스케줄링되는 방식이며, topologyKey를 기준으로 동일한 값에 할당하지 않도록 하는 규칙입니다.
설정은 아래 deployment.yaml 예시에서 podAntiAffinity 부분을 참고하시면 됩니다.
여기서 preferredDuringSchedulingIgnoredDuringExecution 설정으로 스케줄링의 유연함(soft)을 주었습니다.
그 이유는 requiredDuringSchedulingIgnoredDuringExecution 으로 hard하게 설정하면 파드가 스케줄링이 안될 수 있기 때문입니다. 예를들어 hard 정책을 사용하였을 경우 예를 들어 A존 C존에 노드가 각각 1개씩 있고 pod를 3개 배포하고 싶다라고하면 1개의 pod는 스케줄링이 되지 않은 상태로 존재하게 됩니다.

apiVersion: v1
items:
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    labels:
      argocd.argoproj.io/instance: backend-emp
    name: emp-api
    namespace: backend
  spec:
    replicas: 2
    revisionHistoryLimit: 3
    selector:
      matchLabels:
        app: emp-api
    strategy:
      rollingUpdate:
        maxSurge: 25%
        maxUnavailable: 25%
      type: RollingUpdate
    template:
      metadata:
        labels:
          app: emp-api
      spec:
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
              - matchExpressions:
                - key: nodegroup-type
                  operator: In
                  values:
                  - BACKEND
          podAntiAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
            - podAffinityTerm:
                labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - emp-api
                topologyKey: failure-domain.beta.kubernetes.io/zone
              weight: 100
        containers:
        ....(생략)

참고로 soft정책을 사용하였으므로 노드에 경우에 따라 고르게 스케줄링이 안될 수 있습니다. 예를들어 3개의 az에 각각 1개씩의 노드가 있다고하고 pod를 9개 배포한다고하면 3,3,3 이 아닌 4,2,3 과 같이 배포가 될 수 있다는점은 인지해야 합니다.

감사합니다.

반응형