KUBERNETES

13. FinOps 개념과 필요성, 실행 방안

이번 장은 FinOps(Financial Operations)를 알아봅니다. FinOps는 클라우드 비용 관리와 최적화를 중심으로 한 새로운 운영 모델입니다. 클라우드 환경에서 지출을 효율적으로 관리하고 최적화하기 위해 재무, 운영, 기술 팀 간의 협업을 강조합니다. FinOps는 기업이 클라우드 비용을 더 투명하고, 관리 가능하며, 예측 가능하게 만드는 것을 목표로 합니다.

1. FinOps란 무엇인가?

DevOps를 아마도 들어보았을 것 입니다. (제 명함의 Role도 DevOps입니다. ^^)

DevOps란 개발자(Dev)와 운영자(Ops)가 서로 Silo(개별 팀 단위로 격리된 환경, 부서 이기주의 정도로 해석 가능합니다.)로 일하지 않고 회사의 성장이라는 공통의 목표로 협력해서 일하는 방식, 문화를 의미입니다. 기술적인 부분과 문화적인 부분을 모두 포함합니다. FinOps도 유사합니다. 재무팀(Fin)과 운영팀(Ops)이 서로 협력하는 것을 중시하는 문화적인 부분을 강조합니다. 용어는 2016년 경 AWS 행사에서 처음 사용하였다고 합니다. 한국에서는 아직 낯선 용어이지만 미국에서는 어느 정도 일반화되어 FinOps 전담 팀을 두는 회사도 많이 생기는 추세라고 합니다. 물론 FinOps 이전에도 비용 절감이라는 주제는 아주 익숙합니다.

FinOps는 클라우드 비용의 가시성과 최적화를 추구하는 운영 모델의 한 형태로, 기술, 비즈니스 및 재무 팀들이 협업하여 클라우드 지출의 가치를 극대화하는 운영 모델입니다. 이 모델은 비용 관리를 실시간으로 실행하고, 비용에 대한 투명성을 확보하며, 클라우드 지출에 대한 지속적인 최적화를 가능하게 하는 관행, 원칙 및 프레임워크를 포함합니다. FinOps는 변화하는 비즈니스 요구사항에 맞춰 클라우드 자원을 빠르고 유연하게 조정하는 동시에, 지출의 효율성을 보장하고 비용을 지능적으로 관리하여 기업의 전략적 결정을 효과적으로 수립하도록 지원합니다.

DevOps와 마찬가지로 재무, 운영팀이 서로 협력하기 위한 일련의 문화, 프레임워크 등 기술을 포함하여 좀 더 폭넓은 개념입니다. 차이점이 있다면 개발, 운영팀은 그나마 엔지니어라는 공통점이 있는데 재무와 운영은 서로 백그라운드가 다르니 좀 더 제너럴한 내용이 많이 포함됩니다.

2. 도입 배경과 필요성

클라우드 이전의 On-Premise 데이터 센터 환경에서는 새로운 서버, 스토리지 등 인프라를 구매하기 위해서는 재무팀의 승인을 먼저 받아야 했습니다. 모든 회사가 비슷할 것 같은데 저희 이전 회사도 이 승인을 받기가 매우 어려웠습니다. 예상 Max 사용량에 근거해서 신중하게 Sizing 하고 여러 솔루션 중 가격 경쟁력이 있는 최적의 솔루션을 선택해서 복수 견적을 받는 등 길고 어려운 과정을 거쳐야 했습니다. 시간이 너무 많이 걸리고 복잡하기에 일부 R&D 팀은 흔히 전사 정보 전략 승인을 회피하기 위하여 자체 예산을 사용하는 등 우회하는 경우도 많이 있었습니다.

기업들이 전통적인 온-프레미스 구조에서 탄력적이고 확장 가능한 클라우드 서비스로 전환함에 따라, 이전에는 예측 가능했던 IT 지출이 변동성이 크고 복잡한 구조로 바뀌었습니다. 이 변화는 기존의 비용 관리 접근 방식으로는 효과적으로 대응할 수 없는 새로운 도전이었습니다. 클라우드를 사용하면서 IT 비용이 기존의 투자 방식이 아니라(CapEx)가 이제 매월 사용하는 만큼 부과되는 비용(OpEx)으로 변경되었습니다. 재무팀에서는 어느날 갑자기 비용 폭탄을 맞게 되는 난감한 상황이 발생하기도 합니다. 계획을 중시하는 부서라 예산을 책정해야 하는데 예산 잡기가 어렵습니다.

IT 비용이 증가하면 흔히 재무팀에서는 ‘회사가 어려우니 10% 이상 비용을 줄여라’라 그러고 기술팀은 ‘비용을 줄였다가 장애, 보안 사고나면 어떻할꺼냐?’ 라면서 상호 서로 의사 소통이 쉽지 않습니다. 또한 투자 호황인 코로나 시기를 지나고 환율이 급증하면서 클라우드 비용이 가만히 앉아서 20% 이상 오르게 되면서 FinOps, 비용 절감에 대한 관심이 많이 높아졌습니다. 물론, 비용을 통제하는 것은 외부 환경 변화에 관련없이 모든 조직이 매일해야 하는 필수 과제라 생각합니다.

3. FinOps 주요 메트릭

FinOps를 실제 업무에 도입하기 위한 구체적인 방안으로 중앙집중식 클라우드 비용 관리 체계 구축, 실시간 모니터링 및 알림 시스템 도입, 모든 자원의 태그 할당 등 여러 가지가 있습니다. 이러한 방안을 도입하는 기본 원칙으로 데이터에 기반한 의사 결정이 중요합니다. FinOps는 재무팀, 사업팀, 개발팀, 운영팀 등 서로 다른 배경을 가지는 Cross-Function 팀 간 커뮤니케이션이 중요한데, 데이터 기반으로 의사 결정을 하겠다는 중요한 원칙입니다.

바른 FinOps 의사 결정을 위한 데이터의 근간이 되는 주요 메트릭(지표)은 클라우드 비용 효율성, 사용률, 예산 준수 등 다양한 측면을 포함할 수 있습니다. 주요 메트릭을 알아보겠습니다.

클러스터의 Capacity 대비 Request 비율은?

EKS 노드의 전체 할당 가능한 자원(Capacity) 대비 현재 전체 파드의 Request 할당 비율을 측정합니다. 해당 비율이 70% 이상 되는 것을 권고합니다. 클러스터 노드 스케일 아웃 용도로 카펜터를 사용하면 카펜터가 자동으로 파드의 자원 요청량(Request)에 맞는 최적의 노드를 할당하고 자원의 여유가 있으면 노드를 줄이는(Consolidation 옵션) 작업을 진행하여 70% 이상 만족하기에 용이합니다. 개인적으로 EKS 환경은 카펜터를 꼭 사용하는 것을 권고합니다.

아래와 같이 eks-node-viewer(혹은 그라파나, 데이터독 등)등의 도구를 이용하면 편리하게 해당 수치를 확인할 수 있습니다.


<테스트 클러스터 환경으로 Request 비율이 높지 않습니다.>

실제 사용량 대비 Request는 적절하게 설정되었는가?

흔히 자원 요청량(Request) 설정 시 실제 사용량에 근거하지 않고 일단 서비스 안정성을 이유로 대부분의 파드에 여유있게 임의로 1Core, 1Gi 등의 설정을 합니다. 그리고 사용량을 모니터링 하지 않고 잊어버리고 합니다.

파드의 자원 요청량(Request) 설정은 비용과 직결되므로 실제 사용량에 근거하여 Request를 설정하는 것이 중요합니다. 1Core 설정을 하였는데 실제 사용량은 0.1Core도 안되는 경우가 매우 빈번하게 발생합니다. Kubecost, KRR(Kubernetes Resource Recommender) 등의 도구를 사용하면 이러한 문제점을 해결하는데 도움이 됩니다. 각 개별 운영 환경에 적합한 기준으로 자원 Request 기준을 설정할 수 있는데, 예를 들어 CPU – 최근 1주일(혹은 1달) 실제 사용량의 Percentile 90%를 기준, Memory – 최근 사용량의 Max + 10% 여유 등으로 Request 값을 조정하여 실제 적용할 수 있습니다. 이렇게 실제 사용량에 근거하여 자원 요청량을 수정하여 노드 최적화가 가능합니다. 필자 역시, 이러한 Right Sizing 작업으로 EC2 비용을 20% 이상 절약할 수 있었습니다. 

참고로 CPU는 Request만 설정하고 Limit는 설정하지 않고(Burstable 설정) Memory는 Request/Limit 동일하게 설정(Guaranteed)하여 운영 중입니다. CPU는 시간 Base로 사용하는 자원이라 Limit을 별도로 설정하지 않는 것이 성능에 유리하였습니다. (초기 기동 시 Spike 발생하여 Readiness Probe Fail 나는 문제 해결 등)

RI/SP(Savings Plan) Utilization

RI/SP Utilization은 예약한 인스턴스가 실제로 얼마나 사용되고 있는지를 나타내는 비율입니다. 즉, 예약 인스턴스를 구입한 후 실제로 이를 활용하는 정도를 수치로 나타냅니다. 예약 인스턴스는 일정 기간 동안 미리 결제를 함으로써 할인된 가격으로 컴퓨팅 용량을 확보하는 방식인데, 구매한 모든 예약 인스턴스를 완전히 활용하지 않으면 예상한 비용 절감 효과를 얻지 못할 수 있습니다. 따라서, RI/SP Utilization이 높을수록 예약 인스턴스의 투자 대비 효율이 높다고 볼 수 있습니다. 90% ~ 100% 유지하는 것을 권고합니다.

RI/SP Coverage (예약 인스턴스 커버리지)

Coverage는 전체 사용 가능한 인스턴스 중 예약 인스턴스로 커버되는 비율을 말합니다. 이는 단순히 몇 개의 인스턴스가 예약되었는지를 넘어서, 사용 중인 전체 인스턴스 중 예약 인스턴스가 차지하는 비중을 의미합니다. 이 메트릭은 조직이 예약 인스턴스를 충분히 활용하여 할인 혜택을 극대화하고 있는지를 평가하는 데 사용됩니다. 예약 인스턴스로 커버될 수 있는 부분이 많을수록 전체 비용 절감 효과가 크다고 볼 수 있습니다. 회사마다 다를 수 있으나 필자는 대략 70% 정도를 유지하면서 매분기 유휴 인스턴스 삭제, 인스턴스 타입 조정 등의 여유를 가집니다.

Utilization과 Coverage 예를 들면, 회사가 10개의 인스턴스를 사용하고 있고 이 중 5개가 예약 인스턴스라면 RI Coverage는 50%입니다. 만약 이 5개의 예약 인스턴스가 전체 시간의 80% 동안만 사용된다면 RI Utilization은 80%가 됩니다. 실제 적용 현황을 기준으로 MSP(Managed Service Provider) 혹은 CSP(Cloud Service Provider)에서 제공하는 비용 관련 레포트를 활용하면 실제 적용 현황을 파악할 수 있습니다.

이 외 Spot Instance 비율, 유휴 자원(EBS, Load Balancer 등 전체 자원 포함), 태그 자원 비율, Cost Optimizer/Trust Advisor 준수 등 활용할 수 있는 다양한 메트릭이 있습니다. 모든 권고 사항을 한번에 적용하기는 어렵습니다. 한번에 적용할 수 없고 한번에 적용하면 서비스 장애 등의 부작용이 발생하므로 단계별로 적용하는 것을 권고합니다.

이러한 메트릭들을 모니터링하고 해당 메트릭을 기준으로 시스템을 최적화하는 것은 클라우드 비용을 효율적으로 관리하고 재무적으로 건전한 클라우드 운영 환경을 조성하는 데 중요합니다. FinOps 팀은 이 메트릭들을 정기적으로 검토하여 비용 절감 기회를 식별하고 비용을 최적화할 수 있습니다.

그럼 FinOps 적용 시 활용할 수 있는 Kubecost 도구를 실습으로 알아보겠습니다.

4. FinOps 활용 도구 – Kubecost

Kubecost는 쿠버네티스 클러스터에서 발생하는 비용을 모니터링하고 최적화하는 오픈 소스 도구(OpenCost도 사용 가능)입니다. Kubecost는 개발자와 운영팀(혹은 재무팀)이 리소스 사용량과 비용을 실시간으로 이해하고, 비용 효율적인 인프라를 구축하도록 지원합니다.

기존 VM 환경에서 컨테이너, 쿠버네티스 환경으로 이전하면서 VM 단위로 비용을 추적하고 과금하기가 어렵습니다. 단일 VM(워커 노드)에 여러 개의 컨테이너가 실행되고 해당 컨테이너는 특정 VM에 종속되는 것이 아니고 여러 VM에 컨테이너가 실행할 수 있습니다. 이러한 제약 조건에서 Kubecost 등의 도구를 사용하면 Request 할당량 기준으로 비용 모니터링이 가능하여 비용 가시성이 향상됩니다.

주요 이점은 다음과 같습니다.

  • 비용 가시성과 투명성 제공
  • 리소스 사용량 분석을 통한 최적화 방안 도출
  • 예산 초과 방지를 위한 비용 알림 설정

그럼 실습으로 자세한 사항을 알아보겠습니다. 헬름을 이용하여 Kubecost를 설치합니다.

(jerry-test:default)kubecost$ helm repo add kubecost https://kubecost.github.io/cost-analyzer/
"kubecost" has been added to your repositories
(jerry-test:default)kubecost$ helm pull kubecost/cost-analyzer --version 1.107.0
(jerry-test:default)kubecost$ tar xvfz cost-analyzer-1.107.0.tgz 
(jerry-test:default)kubecost$ rm -rf cost-analyzer-1.107.0.tgz 
(jerry-test:default)kubecost$ mv cost-analyzer cost-analyzer-1.107.0
(jerry-test:default)kubecost$ cd cost-analyzer-1.107.0/
(jerry-test:default)cost-analyzer-1.107.0$ mkdir ci
(jerry-test:default)cost-analyzer-1.107.0$ cp values-eks-cost-monitoring.yaml ci/my-values.yaml

기존 헬름 설치 방법과 동일합니다. 버전은 설치 시점의 최신 버전을 사용해도 괜찮으나 필자의 테스트 환경과 동일하게 구성하려면 ‘1.107.3’ 버전을 사용합니다. 설치 시 위와 같이 ‘–version 1.107.0’(23년 11월 기준) 버전을 명시합니다.

기본으로 제공되는 헬름 Values.yaml 파일에서 Kubecost에서 제공하는 eks 환경에 적합하게 수정한 ‘values-eks-cost-monitoring’ 기반으로 ci 디렉토리에 my-values.yaml 파일을 생성합니다.

my-values.yaml

global:
  prometheus:
    enabled: true  # If false, Prometheus will not be installed -- Warning: Before changing this setting, please read to understand this setting https://docs.kubecost.com/install-and-configure/install/custom-prom

  grafana:
    enabled: false
    proxy: false

# Define persistence volume for cost-analyzer
persistentVolume:
  size: 32Gi
  dbSize: 32.0Gi
  enabled: true # Note that setting this to false means configurations will be wiped out on pod restart.
  # storageClass: "-" #
  # existingClaim: kubecost-cost-analyzer # a claim in the same namespace as kubecost

ingress:
  enabled: false
  # className: nginx
  annotations:
    kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  paths: ["/"] # There's no need to route specifically to the pods-- we have an nginx deployed that handles routing
  hosts:
    - cost-analyzer.local
  tls: []
  #  - secretName: cost-analyzer-tls
  #    hosts:
  #      - cost-analyzer.local

prometheus:
  server:
    image:
      repository: public.ecr.aws/kubecost/prometheus
      tag: v2.35.0     
  kube-state-metrics:
    disabled: false
  nodeExporter:
    enabled: false

global.prometheus.enabled: true
Kubecost 용도의 별도의 Prometheus를 설치합니다. 기 설치한 Prometheus를 사용할 수 있으나 편의를 위하여 Kubecost에서 제공하는 Prometheus를 사용합니다.

global.grafana.enabled: false
프로메테우스는 설치하지만 그라파나는 기존 설치한 것을 사용하므로 추가로 그라파나를 설치하지는 않습니다.

ingress.enabled: false
테스트 환경이라 ingress 설정을 하지 않았습니다. ingress를 사용하지 않고 kube-proxy를 사용하여 어드민 페이지에 접속합니다. 하지만 운영 환경에서는 인그레스를 설정하여 개발팀에서도 쉽게 접속하도록 변경합니다.


prometheus.kube-state-metrics.disabled: false
prometheus.nodeExporter.enabled: false
클러스터 모니터링은 기존 설치한 프로메테우스를 사용하므로 추가로 kube-state-metrics, nodeExporter 등을 설치하지 않습니다.

설정이 완료되어 Kubecost를 설치합니다.

(jerry-test:default)cost-analyzer-1.107.0$ helm install kubecost --namespace kubecost --create-namespace -f ci/my-values.yaml .
NAME: kubecost
LAST DEPLOYED: Sat Nov  4 13:01:40 2023
NAMESPACE: kubecost
STATUS: deployed
REVISION: 1
NOTES:
--------------------------------------------------
Kubecost 1.107.0 has been successfully installed.

WARNING: ON EKS v1.23+ INSTALLATION OF EBS-CSI DRIVER IS REQUIRED TO MANAGE PERSISTENT VOLUMES. LEARN MORE HERE: https://docs.kubecost.com/install-and-configure/install/provider-installations/aws-eks-cost-monitoring#prerequisites

Please allow 5-10 minutes for Kubecost to gather metrics.

When configured, cost reconciliation with cloud provider billing data will have a 48 hour delay.

When pods are Ready, you can enable port-forwarding with the following command:

    kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 9090

Then, navigate to http://localhost:9090 in a web browser.

Having installation issues? View our Troubleshooting Guide at http://docs.kubecost.com/troubleshoot-install

네임스페이스를 변경하고 헬름 상태를 확인합니다.

(jerry-test:default)cost-analyzer-1.107.0$ k ns kubecost
Context "jerry-test" modified.
Active namespace is "kubecost".
(jerry-test:kubecost)cost-analyzer-1.107.0$ helm ls
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
kubecost        kubecost        1               2023-11-04 13:01:40.119878 +0900 KST    deployed        cost-analyzer-1.107.0   1.107.0 

정상으로 파드가 실행됩니다.

(jerry-test:kubecost)cost-analyzer-1.107.0$ k get pod -o wide
NAME                                          READY   STATUS    RESTARTS   AGE   IP              NODE                                              NOMINATED NODE   READINESS GATES
kubecost-cost-analyzer-69b954f664-9cfrg       2/2     Running   0          89s   10.110.27.194   ip-10-110-22-92.ap-northeast-2.compute.internal   <none>           <none>
kubecost-prometheus-server-74bcb9c878-xlc4f   1/1     Running   0          89s   10.110.30.53    ip-10-110-22-92.ap-northeast-2.compute.internal   <none>           <none>

서비스 이름을 이용하여 kube-proxy를 실행합니다.

(jerry-test:kubecost)cost-analyzer-1.107.0$ k get svc
NAME                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
kubecost-cost-analyzer       ClusterIP   172.20.72.193   <none>        9003/TCP,9090/TCP   2m11s
kubecost-prometheus-server   ClusterIP   172.20.79.230   <none>        80/TCP              2m11s
(jerry-test:kubecost)cost-analyzer-1.107.0$ k port-forward svc/kubecost-cost-analyzer 9090:9090
Forwarding from 127.0.0.1:9090 -> 9090
Forwarding from [::1]:9090 -> 9090

처음 실행하면 충분한 데이터가 수집되지 않아 실제 적용하기 어렵습니다. 하지만 1주일 정도 지나면 의미있는 데이터를 확인할 수 있습니다. 아래 예시는 테스트 클러스터 환경에서 각 파드 별 적절한 Resource Request를 추천하는 기능입니다.

Resource Request 할당 시 실제 사용량에 근거하지 않고 서비스 안정성을 위하여 임의로 크게 할당하는 경우가 많은데 아래와 같이 실제 사용량에 근거하여 추천하는 사용량을 확인할 수 있습니다.

권고하는 Request 기준을 아래와 같이 각자의 환경에 맞게 적절하게 조정하면 보다 안정적이고 비용 효과적으로 운영할 수 있습니다.

쿠버네티스 환경에서는 애플리케이션이 여러 노드에 분산되어 실행되어 각 부서 별 비용 할당하기가 어렵습니다. 이 경우 각 부서 별로 네임스페이스를 구분하고 각 네임스페이스에서 사용하는 리소스를 기준으로 비용을 할당할 수 있습니다. Kubecost를 이용하면 아래와 같이 각 네임스페이스 별 비용 확인이 편리합니다.

Kubecost는 Kubernetes 클러스터의 비용 관리 및 최적화를 위한 강력한 도구입니다. 이는 클러스터 리소스 사용량을 실시간으로 모니터링하고, 비용을 투명하게 보여주어 조직이 클라우드 지출을 효과적으로 관리할 수 있도록 합니다. Kubecost는 네임스페이스, 레이블, 또는 사용자 정의 필터를 통해 세분화된 비용 데이터를 제공합니다. 이 도구는 비용 절감을 위한 권장 사항을 제공하며, 불필요한 자원 사용을 최소화하는 데 도움을 줍니다. 전반적으로 Kubecost는 Kubernetes 환경에서 비용 효율성과 예산 관리의 투명성을 높이는 중요한 솔루션입니다.

이번 장은 FinOps를 알아보았습니다. 작년부터 경기가 안 좋아지면서 부쩍 관심이 증가한 것 같습니다.

해당 기술 블로그에 질문이 있으시면 언제든지 문의해 주세요. 직접 답변해 드립니다.
k8sqna@jennifersoft.com

Next

Contact Us

안녕하세요? 제니퍼소프트입니다.
기술 문의의 경우 질문자의 회사/이름/연락처를 본문에 기술해 주셔야만 원할한 지원이 가능합니다.
보내주신 문의 사항을 검토하여 빠른 시일 내에 답변해 드리겠습니다.

  • Chris
  • Irene

메일을 보냈습니다.

메일 전송이 완료되었습니다.
빠른 시일 내에 답변드리겠습니다.
감사합니다.
제니퍼소프트 웹사이트는 쿠키를 사용합니다. 쿠키에 대한 자세한 정보 및 삭제 방법은 제니퍼소프트의 개인정보처리방침을 참고하시기 바라며 본 사이트를 계속해서 이용하는 것은 제니퍼소프트의 쿠키 사용에 동의함을 의미합니다.