DevOps/Kubernetes

[K8S] Resource Request, Limit이란?

운호(Noah) 2023. 11. 16. 17:18

요약

  • K8S에서 Resource의 Request와 Limit은 컨테이너에 할당되는 CPU, Memory의 자원량을 의미합니다.
  • Request는, 컨테이너 생성 시 필요한 자원량을 의미합니다.
  • Limit은, 컨테이너가 이미 실행 중인 상태에서 추가 리소스가 필요한 경우에 사용할 수 있는 최대 자원량을 의미합니다.
    • 이때 주의할 점은, 반드시 Limit은 Request보다 같거나 커야한다는 것입니다.
    • Limit은 추가로 얼만큼의 리소스를 더 사용할 것인지가 아닌,
    • 컨테이너 생성 시 필요한 자원량과 추가로 사용할 자원량을 더한 최대 자원량을 의미하기 때문입니다.
  • CPU와 Memory의 자원 단위는 아래와 같습니다.
    • CPU : Milicore (1,000 Milicore = 1Core)
    • Memory : Mbyte

K8S의 스케줄링이란?

  • Kubernetes에서, Pod를 어느 Node에 배포할지 결정하는 것을 스케줄링이라고 합니다.
  • Kubernetes 입장에서는 Pod에 필요한 자원의 양을 알아야,
  • 해당 자원을 사용할 수 있는 Node에 Pod를 배포할 수 있게 됩니다.
    • Pod는 하나 이상의 Container로 구성되므로,
    • 스케줄링은 Pod의 모든 Container Request 양을 합친 값을 기준으로 진행됩니다.

Request 양을 초과 사용하면 어떻게 되는가?

  • Pod가 Request 양을 초과하더라도 Limit 양을 넘지 않으면 문제가 발생하지 않습니다.
  • 다만, Node의 자원이 부족할 경우에는 Request 양을 초과한 Pod는 퇴거(Eviction)의 대상이 되어, 다른 Node에 재배치됩니다.
  • 만약 모든 Node의 자원이 부족하다면 이 Pod는 Pending 상태로 지속 됩니다.
    • 따라서, 서비스 운영 시 자원 부족에 따른 Pod의 재배치나 Pending 상태에 대응하기 위해
    • Replication을 설정하거나, 특정 Node에 Pod를 한정하여 배치하는 전략 등을 고려해야 합니다.

Limit 양을 초과하여 사용하면 어떻게 되는가?

  • Pod가 Limit 양을 초과하면, Overcommitted 상태에 진입하게 됩니다.
    • Overcommitted 상태란, 실제 사용 가능한 물리적인 자원량보다 해당 Pod에 할당된 자원량이 많은 상태를 의미합니다.
  • CPU가 Overcommitted 될 경우, CPU는 throttling을 통해 실제 CPU 사용량을 Request에 정의된 상태까지 낮추게 됩니다.
    • 예를 들어, Request가 100, Limit이 500인 경우, 현재 500으로 가동되고 있는 컨테이너의 CPU할당량을 100까지 낮추게 됩니다.
    • 그래도 Overcommitted 상태가 해결되지 않을 경우, 우선 순위에 따라서 운영중인 컨테이너를 강제 종료 시키게 됩니다.
  • Memory가 Overcommitted 될 경우, 사용중인 메모리의 크기를 줄일 수는 없기 때문에, 우선 순위에 따라서 운영 중인 컨테이너를 강제 종료 시키게 됩니다.

Request와 Limit 양을 설정하지 않으면 어떻게 되는가?

  • Request와 Limit 양을 설정하지 않으면, Node의 자원 전체를 사용할 수 있다는 의미와 같습니다.
  • 개발 중에는 자원량을 설정하지 않아도 문제는 없지만,
  • 운영 시에는 Request, Limit 양이 설정되지 않은 Pod는 정확한 스케줄링이 어렵습니다.
    • 한 Node에 Pod가 초과 배치될 수도 있고,
    • Node 자원 부족 시 퇴거 대상이 증가할 수도 있습니다.

ResourceQuota & LimitRange

  • 쿠버네티스에서는 ResourceQuota를 사용해 네임스페이스별로 사용할 수 있는 리소스의 양을 지정하거나,

  • LimitRange를 사용해 컨테이너마다 사용할 수 있는 리소스의 양을 지정할 수 있습니다.

  • ResourceQuota

      apiVersion: v1
      kind: ResourceQuota
      metadata:
        name: example-resourcequota
      spec:
        hard:
          requests.cpu: "1"
          requests.memory: 1Gi
          limits.cpu: "2"
          limits.memory: 2Gi
    • Resource Quota는 네임스페이스별로 사용할 수 있는 리소스의 양을 지정합니다.
    • 위 yaml 파일은, example-resourcequota라는 네임스페이스의 리소스 양을 지정한 예제입니다.
    • requests.cpu : 네임스페이스 전체의 CPU Request 리소스 제한 값입니다.
    • requests.memory : 네임스페이스 전체의 Memory Request 리소스 제한 값입니다.
    • limits.cpu : 네임스페이스 전체의 CPU Limit 리소스 제한 값입니다.
    • limits.memory : 네임스페이스 전체의 Memory Limit 리소스 제한 값입니다.
  • LimitRange

      apiVersion: v1
      kind: LimitRange
      metadata:
        name: example-limitrange
      spec:
        limits:
        - type: Container
          max:
            memory: 512Mi
            cpu: 1
          min:
            memory: 50Mi
            cpu: 100m
          default:
            memory: 128Mi
            cpu: 200m
          defaultRequest:
            memory: 64Mi
            cpu: 100m
    • Limit Range는 컨테이너 개별 자원의 사용 가능 범위를 지정합니다.
    • type : Container : 이 LimitRange는 컨테이너에 대한 제한을 정의합니다.
    • max : 컨테이너의 Limit을 지정할 경우, 설정 가능한 최대 값입니다.
    • min : 컨테이너의 Limit을 지정할 경우, 설정 가능한 최소 값입니다.
    • default : 컨테이너의 Limit 값에 대한 기본값을 정의합니다.
    • defaultRequest : 컨테이너의 Request 값에 대한 기본값을 정의합니다.

참고