ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] QoS 알아보기 (Quality of Service)
    Kubernetes 2024. 2. 4. 08:54
    728x90
    반응형

     

    - 목차

     

     

    들어가며.

    이번 글에서는 쿠버네티스의 QoS 에 대해서 알아봅니다. QoS 는 Quality of Service 의 약자인데요.

    "서비스의 품질" 와 같이 해석할 수 있지만, 쿠버네티스의 관점에서 설명하자면 Pod 의 생존을 보장하는 정도를 나타냅니다.

    ( 구체적으로는 Pod 가 Eviction 되는 가능성을 낮추는 정도인데요. 아래에서 자세히 설명하도록 하겠습니다. )

    Pod 는 특정 Node 에 스케줄링되어 실행되고, Pod 의 내부에서 컨테이너들이 실행됩니다.

    컨테이너의 갯수는 하나 또는 그 이상일 수 있습니다. (일반적으로 1개의 Pod 는 1개의 컨테이너를 가집니다.)

    컨테이너는 CPU 와 메모리에 대해서 사용량을 제한할 수 있는데요. 이는 request 와 limit 나뉘어집니다.

     

    아래의 yaml 은 resource 사용량을 설정하는 Pod 의 yaml 입니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: frontend
    spec:
      containers:
      - name: app
        image: images.my-company.example/app:v4
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

     

    아래와 같이 총 4가지 설정을 할 수 있는데요.

    - spec.containers[*].resources.requests.cpu

    - spec.containers[*].resources.requests.memory

    - spec.containers[*].resources.limits.cpu

    - spec.containers[*].resources.limits.memory

     

    spec.containers[*].resources.limits 은 Pod 가 사용할 수 있는 최대 용량의 제한입니다.

    그래서 "spec.containers[*].resources.limits.cpu : 500m" 은 최대 0.5개의 Core 로 제한을 두며,

    병렬 처리가 수행되지 않고, 연산 수행이 적은 애플리케이션이 이러한 리소스 제한에 적합합니다.

    "spec.containers[*].resources.limits.memory : 128Mi" 는 메모리의 제한을 128Mi 만큼 설정합니다.

     

    "spec.containers[*].resources.requests.cpu" 와

    "spec.containers[*].resources.requests.memory" 에 해당하는 request 설정은 Pod 가 필요로하는 최소 리소스 사용량을 뜻합니다.

     

    requests 와 limits 설정값을 통해서 Pod 의 QoS  가 결정됩니다.

    그리고 QoS 는 Pod 의 생존을 보장하는 기준으로써 사용됩니다.

     

    Eviction.

    Pod 는 Node 에서 구동된다고 말씀드렸죠 ?

    아래 이미지처럼 하나의 Node 내부에서 여러개의 Pod 들이 구동됩니다.

    Node 는 물리적은 서버 인스턴스를 의미하고, Pod 는 가상화된 애플리케이션을 의미할 수 있는데요.

    Pod 는 Node 의 리소스를 사용하게 됩니다.

    만약 Pod 가 너무 많은 CPU, Memory, Disk 를 사용하게 되면 Node 는 Resource Pressure 를 받게 됩니다.

    Pressure 을 받고 있는 Node 는 안정적인 구동을 위해서 Pod 를 제거하게 되는데, 이렇게 Pod 가 제거되는 행위를 Eviction 이라고 합니다.

    출처 : https://kubernetes.io/docs/tutorials/kubernetes-basics/explore/explore-intro/

     

    그럼 어떤 Pod 가 Eviction 의 대상이 될까요 ?

    이 Eviction 에 관여하는 정보가 바로 Pod 의 QoS 입니다.

    QoS 가 낮을수록 Eviction 의 대상이 될 가능성이 높아집니다.

    반면 QoS 가 높을수록 Eviction 의 대상이 될 가능성이 낮아지죠.

    그래서 위 글에서 "Pod 의 생존이 보장되는 정도"라고 말씀드렸습니다.

     

    즉, Node 가 불안정한 상황에서 Pod 를 다른 Node 로 쫓아내거나 제거해야하는데요.

    QoS 의 정도가 낮은 Pod 가 Eviction 의 대상이 됩니다.

    QoS 종류.

    Pod 의 리소스 요청량과 제한값을 기준으로 Pod 의 QoS 가 결정됩니다.

    QoS 는 3가지 종류를 가집니다.

    QoS 가 높은 순서대로 말씀드리면, "Guaranteed", "Burstable", "BestEffort" 가 존재합니다.

     

    Guaranteed.

    Guaranteed 상태는 이름에서 유추할 수 있듯이 보장된 상태입니다.

    즉, Eviction 이 될 가능성이 매우 적습니다.

    이는 리소스 요청량과 리소스 제한의 값이 동일한 Pod 가 Guaranteed 상태의 QoS 를 가집니다.

    Quaranteed Pod 는 리소스의 사용량을 예측할 수 있기 때문에 돌발적으로 Node 에 Pressure 를 가하지 않습니다.

    그래서 이러한 Pod 는 Eviction 대상에서 제외될 가능성이 큽니다.

     

    정리하자면, Pod 의 돌발적인 리소스 사용으로 인해서 Node 가 Pressure 를 받게되는데

    Guaranteed Pod 는 안정적인 리소스를 사용하므로 Node 에게 Pressure 를 가할 가능성이 적습니다.

    즉, Kubernetes 는 어떤 Pressure 가 발생한 경우에 Guaranteed Pod 가 원인이 아닐거라고 확신하는거죠.

    설령 Guaranteed Pod 가 Pressure 를 일으킨 원인이더라도 Eviction 의 우선순위에서 제외됩니다.

     

    Burstable.

    Burstable 상태 또한 이름에서 유추할 수 있듯이 리소스 사용량이 튈 수 있는 Pod 입니다.

    이는 리소스 요청량과 리소스 제한이 다른 Pod 가 Burstable QoS 를 가지는데요.

    리소스의 사용 범위가 있기 때문에 Min-Max 사이에서 Burstable 하다고 여깁니다.

    이는 Guaranteed 다음으로 Eviction 될 가능성이 낮을 QoS 입니다.

     

    BestEffort.

    마지막 BestEffort 상태는 Eviction 될 가능성이 가장 큰 QoS 입니다.

    이는 리소스 요청량과 리소스 제한을 설정하지 않은 Pod 의 QoS 입니다.

    증권의 용어에서 BestEffort 라는 표현이 있는데요.

    모집주선(best-effort)이란 발행기관이 발행 사무를 담당하여 모집에 최선을 다하지만 
    만일 이러한 모집의 결과 미소화분의 증권이 발생하면 이를 발행자에게 되돌려 줌으로써 
    발행위험을 부담하지 않는 방법입니다.

     

    용어가 어렵지만 증권사에서 최선을 다하지만 약간의 손실이 발생하는 투자자들에게 투자금을 즉시 반환한다는 뜻으로 이해했구요.

    핵심은 언제든지 회수되거나 제거될 수 있는 대상이라는 뉘앙스를 받았습니다.

    그래서 쿠버네티스의 BestEffort QoS 또한 Node Pressure 상황에서 즉시 제거될 수 있는 Pod 의 QoS 를 의미하는 것 같네요.

     

     

    실습해보기.

    마지막으로 QoS 를 직접 실습해보는 시간을 가지겠습니다.

    아래의 링크의 페이지는 KinD 를 통해 쿠버네티스 클러스터를 로컬 환경에서 실행하는 방법을 설명합니다.

    https://westlife0615.tistory.com/407

     

    KinD 알아보기.

    - 목차 소개. KinD 는 "카인드" 라고 발음되며, 로컬 머신에서 쿠버네티스를 간편하게 실행할 수 있는 도구입니다. KinD 는 Kubernetes in Docker 의 약자이구요. Docker 를 활용하여 쿠버네티스 환경을 구성

    westlife0615.tistory.com

     

    쿠버네티스 클러스터가 생성된 이후에 아래의 명령어들을 실행하면 Guaranteed 상태의 Pod 를 생성할 수 있습니다.

    cat <<EOF> /tmp/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2 # tells deployment to run 2 pods matching the template
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80
            resources:
              requests:
                cpu: '1000m'
                memory: '1Gi'
              limits:
                cpu: '1000m'
                memory: '1Gi'  
    EOF
    kubectl apply -f /tmp/deployment.yaml

     

     

    Burstable.

    아래의 명령어를 통해서 Burstable 상태의 Pod 들을 생성할 수 있습니다.

    의도적으로 리소스의 requests 와 limits 를 다르게 적용하였습니다.

    cat <<EOF> /tmp/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-burstable-deployment
    spec:
      selector:
        matchLabels:
          app: nginx-burstable
      replicas: 2 # tells deployment to run 2 pods matching the template
      template:
        metadata:
          labels:
            app: nginx-burstable
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80
            resources:
              requests:
                cpu: '500m'
                memory: '512Mi'
              limits:
                cpu: '1000m'
                memory: '1Gi'  
    EOF
    
    kubectl apply -f /tmp/deployment.yaml

     

    그리고 아래의 이미지와 같이 Burstable Pod 들이 생성됩니다.

     

     

    BestEffort.

    BestEffort 상태의 Pod 를 생성합니다.

    BestEffort QoS 는 Pod 생성 시에 spec.resources 설정을 제외시키면 됩니다.

    cat <<EOF> /tmp/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-besteffort-deployment
    spec:
      selector:
        matchLabels:
          app: nginx-besteffort
      replicas: 2 # tells deployment to run 2 pods matching the template
      template:
        metadata:
          labels:
            app: nginx-besteffort
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80
    EOF
    
    kubectl apply -f /tmp/deployment.yaml

     

    아래의 이미지처럼 BestEffort 인 Pod 들이 생성됩니다.

     

     

    반응형
Designed by Tistory.