13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] 클라우드 비용 최적화

  • [k8s] Cluster Autoscaler에서 Karpenter로 마이그레이션 결정 기준 및 전환 전략

    [k8s] Cluster Autoscaler에서 Karpenter로 마이그레이션 결정 기준 및 전환 전략

    [Kubernetes] Cluster Autoscaler에서 Karpenter로 마이그레이션: 언제, 어떻게 전환할까요?

    안녕하세요, 13년차 서버실 지킴이입니다. 오늘은 Kubernetes(쿠버네티스) 환경에서 노드 오토스케일링(Auto Scaling)을 고민하는 분들을 위한 이야기를 해볼까 합니다. 특히 EKS (Amazon Elastic Kubernetes Service)를 운영하면서 Cluster Autoscaler (CA)의 한계를 느끼고 Karpenter로의 마이그레이션을 고민하는 분들이라면, 제가 직접 겪었던 경험과 삽질 끝에 얻은 노하우가 도움이 될 거예요.

    클라우드 환경에서 Kubernetes 클러스터를 운영하다 보면, 워크로드(Workload)의 변화에 따라 노드를 유연하게 늘리고 줄이는 것이 정말 중요합니다. 비용 최적화는 물론이고, 서비스 안정성에도 직결되거든요. 처음에는 Cluster Autoscaler(클러스터 오토스케일러)가 만능인 줄 알았는데, 막상 써보니 아쉬운 점들이 꽤 있더라고요. 특히 급작스러운 트래픽 증가나 스팟 인스턴스(Spot Instance) 활용 시 Karpenter가 보여주는 퍼포먼스는 저를 깜짝 놀라게 했습니다.

    오늘은 Cluster Autoscaler에서 Karpenter로의 전환을 언제 고려해야 하는지, 그리고 실제 전환은 어떻게 진행해야 하는지에 대한 저만의 결정 기준과 전략을 솔직하게 공유해 드릴게요. 삽질 과정도 가감 없이 보여드릴 테니, 함께 살펴보시죠!

    Karpenter가 도입된 Kubernetes 클러스터의 노드 오토스케일링 아키텍처 개요도

    Cluster Autoscaler와 Karpenter: 핵심 개념 차이

    본격적인 마이그레이션 이야기를 하기 전에, 두 오토스케일링 도구가 어떻게 다른지 간단히 짚고 넘어갈게요. 쉽게 말해 접근 방식 자체가 다릅니다.

    Cluster Autoscaler (CA): 그룹 기반 오토스케일링

    • 작동 방식: Cluster Autoscaler는 AWS Auto Scaling Group (ASG)을 기반으로 작동합니다. 즉, 미리 정의된 ASG의 최소/최대 인스턴스 개수 범위 내에서 노드를 추가하거나 줄이죠.
    • 장점: 비교적 설정이 간단하고, 오랫동안 사용되어 안정성이 검증되었습니다. 기존 EC2 인스턴스 관리 방식에 익숙하다면 접근하기 쉽습니다.
    • 단점:
      • 느린 스케일 아웃(Scale Out) 속도: ASG가 새 인스턴스를 프로비저닝(Provisioning)하는 데 시간이 걸립니다. 워크로드 요청이 급증할 때 노드 부족 현상이 생길 수 있어요.
      • 비효율적인 리소스 활용: 특정 파드(Pod)에 필요한 리소스 타입을 정확히 맞추기 어렵습니다. ASG는 특정 인스턴스 타입이나 몇 가지 인스턴스 타입 묶음으로 구성되니까요. 이 때문에 kube-scheduler (쿠베 스케줄러)가 파드를 노드에 배치하지 못하는 ‘스케줄링 불가(unschedulable)’ 상태가 발생할 수 있습니다.
      • 스팟 인스턴스 활용 제약: 스팟 인스턴스를 활용하더라도, ASG의 인스턴스 풀(Pool)이 제한적이라 유연성이 떨어집니다.

    Karpenter: 파드 기반 오토스케일링

    • 작동 방식: Karpenter는 스케줄링되지 않은 파드를 직접 감지하고, 해당 파드에 가장 적합한 EC2 인스턴스를 직접 프로비저닝합니다. ASG를 거치지 않고 EC2 RunInstances API를 직접 호출해서 노드를 띄우는 거죠.
    • 장점:
      • 압도적인 스케일 아웃 속도: 필요한 노드를 거의 실시간으로 생성하기 때문에 워크로드 변화에 매우 빠르게 대응합니다. 제가 직접 써보니 CA보다 훨씬 빨랐습니다.
      • 최적의 리소스 활용: 파드가 요구하는 CPU, 메모리, GPU 등 리소스에 맞춰 가장 효율적인 EC2 인스턴스 타입을 선택합니다. 스팟 인스턴스 활용도 극대화해서 비용 절감 효과가 커요.
      • 단순한 관리: ASG를 직접 관리할 필요 없이, Karpenter의 Provisioner (프로비저너) 설정 하나로 노드 프로비저닝 정책을 관리할 수 있습니다.
    • 단점:
      • 초기 학습 곡선: 새로운 개념과 설정이 필요해서 처음에는 좀 낯설 수 있습니다.
      • 클라우드 종속성: 현재는 AWS EKS에 특화되어 있습니다 (다른 클라우드 지원도 개발 중이지만, 현재로선 AWS가 주력입니다).

    Karpenter로의 마이그레이션 결정 기준: 언제 전환해야 할까요?

    제가 13년차 인프라 엔지니어로서 여러 환경을 경험해보니, 마이그레이션은 항상 신중해야 하더라고요. 무조건 좋다고 따라가는 것보다, 우리 서비스에 어떤 이점이 있을지 명확히 파악하는 게 중요합니다. 다음 질문들에 해당한다면 Karpenter로의 전환을 적극적으로 고려해볼 때입니다.

    • 잦은 스케일링 이벤트와 느린 노드 확장 속도에 불만이 있다:

      특히 이벤트 기반(Event-driven) 서비스나 예측 불가능한 트래픽 패턴을 가진 서비스라면 CA의 스케일 아웃 속도가 병목이 될 수 있습니다. "파드가 Pending(대기) 상태인데 노드가 왜 이렇게 늦게 뜨지?" 라는 질문을 자주 하셨다면 Karpenter가 답이 될 수 있습니다.

    • 클라우드 비용 최적화가 시급하다:

      CA는 ASG가 정해준 인스턴스 타입 내에서만 노드를 띄우다 보니, 파드의 리소스 요구사항과 정확히 일치하는 인스턴스를 찾기 어렵습니다. Karpenter는 파드에 딱 맞는 최적의 인스턴스를 찾아 스팟 인스턴스까지 적극적으로 활용하기 때문에, 불필요한 리소스 낭비를 줄여줍니다. 저희 홈랩에서도 스팟 인스턴스 활용률이 훨씬 높아지면서 비용이 꽤 절감됐습니다.

    • 노드 타입 관리가 복잡하다고 느낀다:

      CA를 사용하면 다양한 워크로드를 위해 여러 ASG를 만들고 관리해야 할 때가 많습니다. Karpenter는 Provisioner (프로비저너) 하나로 다양한 인스턴스 타입을 유연하게 관리할 수 있어 운영 부담이 줄어듭니다.

    • 특정 리소스(GPU, 고성능 CPU 등) 요구사항이 있는 파드가 많다:

      머신러닝(Machine Learning) 워크로드처럼 특정 GPU나 고성능 CPU를 요구하는 파드들이 있다면, Karpenter가 해당 파드에 맞는 노드를 즉시 프로비저닝해서 스케줄링 효율을 극대화할 수 있습니다.

    Karpenter로의 전환 전략: 실전 구현

    이제 Karpenter로 마이그레이션하는 실제 과정을 단계별로 살펴보겠습니다. 저는 EKS 환경을 기준으로 설명드릴게요.

    단계 1: Karpenter 설치 및 IAM 권한 설정

    Karpenter는 AWS API를 직접 호출해서 EC2 인스턴스를 생성하고 관리해야 하므로, 적절한 IAM(Identity and Access Management) 권한이 필수입니다. 공식 문서에 따라 IAM Role과 Service Account를 생성하고, Karpenter 컨트롤러를 설치합니다. 이 부분은 공식 문서가 워낙 잘 되어 있어서 그대로 따라가시면 됩니다. 핵심은 Karpenter가 EC2, IAM, SSM 등의 리소스에 접근할 수 있는 권한을 부여하는 것입니다.

    설치 후에는 Karpenter Controller Pod가 잘 뜨는지 확인해야 합니다.

    kubectl get pods -n karpenter
    # 예시 출력:
    # NAME                         READY   STATUS    RESTARTS   AGE
    # karpenter-controller-xxxxx   1/1     Running   0          5m
    

    단계 2: Provisioner 설정

    Karpenter의 핵심은 바로 Provisioner 리소스입니다. 어떤 종류의 노드를, 어떤 조건으로 생성할지 여기에 정의합니다. 처음에는 너무 복잡하게 생각하지 마시고, 가장 기본적인 설정으로 시작하는 것을 추천합니다.

    Karpenter Provisioner YAML 설정 예시와 주요 파라미터 설명

    Karpenter Provisioner YAML 설정 예시와 주요 파라미터 설명

    apiVersion: karpenter.sh/v1beta1
    kind: Provisioner
    metadata:
      name: default
    spec:
      # Karpenter가 사용할 AMI Family를 정의합니다. EKS 최신 Optimized AMI를 사용하세요.
      # (예: AL2, AL2023, Bottlerocket, Ubuntu)
      # Karpenter는 여기에 지정된 AMI Family의 최신 EKS Optimized AMI를 자동으로 선택합니다.
      # official EKS AMIs: https://docs.aws.amazon.com/eks/latest/userguide/retrieve-ami-id.html
      amiFamily: AL2 # Amazon Linux 2 (EKS Optimized AMI) 또는 AL2023
    
      # 인스턴스 프로비저닝에 대한 요구사항을 정의합니다.
      # 여기서는 amd64 아키텍처의 온디맨드 또는 스팟 인스턴스를 사용하도록 설정했습니다.
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand", "spot"] # 스팟 인스턴스 활용을 적극 권장합니다!
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ["c", "m", "r"] # 컴퓨팅, 메모리, 범용 인스턴스 카테고리
        - key: karpenter.k8s.aws/instance-family
          operator: In
          values: ["c5", "c6i", "m5", "m6i", "r5", "r6i"] # 자주 사용하는 인스턴스 패밀리
        - key: karpenter.k8s.aws/instance-size
          operator: NotIn
          values: ["nano", "micro"] # 너무 작은 인스턴스는 제외
    
      # 노드가 어떤 서브넷(Subnet)에 생성될지 태그(Tag)로 정의합니다.
      # EKS 클러스터가 사용하는 서브넷 태그와 일치해야 합니다.
      subnetSelector:
        karpenter.sh/discovery: "your-eks-cluster-name" # EKS 클러스터 이름으로 교체
    
      # 노드가 어떤 보안 그룹(Security Group)을 사용할지 태그로 정의합니다.
      securityGroupSelector:
        karpenter.sh/discovery: "your-eks-cluster-name" # EKS 클러스터 이름으로 교체
    
      # 노드에 적용될 테인츠(Taints)를 정의합니다.
      # 여기에 테인트가 있으면, 해당 테인트를 허용하는 파드만 스케줄링됩니다.
      # - key: my-app
      #   effect: NoSchedule
    
      # 노드 템플릿입니다. SSH 키페어, IAM 인스턴스 프로파일 등을 지정할 수 있습니다.
      providerRef:
        name: default
    
      # 노드 삭제 정책 (consolidation).
      # 기본적으로 파드가 없거나, 더 효율적인 노드로 대체될 수 있으면 노드를 삭제합니다.
      consolidation:
        enabled: true
        # consolidateAfter: 5m # 노드 생성 후 최소 5분은 유지 (선택 사항)
    
      # 노드 TTL(Time To Live) 설정. 노드가 일정 시간 동안 유휴 상태이거나
      # 최대 수명을 넘으면 삭제됩니다.
      ttlSecondsAfterEmpty: 300 # 노드에 파드가 없으면 300초(5분) 후 삭제
      ttlSecondsUntilExpired: 604800 # 노드는 최대 7일(604800초)까지만 유지 (수명 관리)
    
    ---
    apiVersion: karpenter.k8s.aws/v1beta1
    kind: AWSNodeTemplate
    metadata:
      name: default
    spec:
      # Karpenter가 사용할 IAM 인스턴스 프로파일을 지정합니다.
      # EKS 노드에 필요한 권한이 포함된 프로파일이어야 합니다.
      # 보통 `eksctl create iamserviceaccount` 등으로 생성됩니다.
      instanceProfile: "KarpenterNodeInstanceProfile-your-cluster-name" # 실제 프로파일 이름으로 교체
    
      # SSH 키페어를 지정하여 노드에 SSH 접속이 가능하도록 합니다. (선택 사항)
      # sshName: your-ssh-key-name
    
      # 노드에 추가적인 태그를 붙일 수 있습니다.
      tags:
        environment: production
        managed-by: karpenter
        karpenter.sh/cluster-name: "your-eks-cluster-name" # 클러스터 이름으로 교체
    

    위 YAML을 적용하면 Karpenter가 이제 파드를 감지하고 노드를 프로비저닝할 준비가 됩니다. 여기서 중요한 포인트는 requirements 섹션입니다. 어떤 인스턴스 타입을 사용할지, 스팟(Spot)을 쓸지 온디맨드(On-Demand)를 쓸지 등 Karpenter의 동작 방식을 결정하는 핵심 설정입니다. 저는 스팟 인스턴스를 적극적으로 활용해서 비용을 절감하는 방향으로 설정했습니다.

    단계 3: Cluster Autoscaler (CA) 노드 그룹 점진적 비활성화

    Karpenter가 잘 작동하는지 확인하면서, 기존 CA가 관리하던 노드 그룹(ASG)을 점진적으로 스케일 다운(Scale Down)해야 합니다. 한 번에 모든 노드 그룹을 비활성화하면 서비스 중단 위험이 있으니, 워밍업(Warm-up) 기간을 두는 것이 좋습니다.

    1. 새로운 파드를 배포하거나 기존 파드를 재시작하여 Karpenter가 새 노드를 잘 띄우는지 관찰합니다.
    2. Karpenter가 프로비저닝한 노드가 충분히 확보되었다고 판단되면, CA가 관리하는 ASG의 desired capacity를 0으로 설정합니다.
    3. ASG의 최소/최대 인스턴스 수도 0으로 설정하여 CA가 더 이상 노드를 관리하지 않도록 합니다.
    # EKS 노드 그룹 목록 확인 (eksctl 사용 예시)
    eksctl get nodegroup --cluster your-eks-cluster-name
    
    # 특정 노드 그룹의 desired capacity를 0으로 설정
    # (eksctl 명령은 ASG도 함께 조정합니다)
    eksctl scale nodegroup --cluster your-eks-cluster-name --name your-nodegroup-name --nodes 0 --nodes-min 0 --nodes-max 0
    
    # 또는 AWS CLI로 ASG 직접 수정 (ASG 이름 확인 필요)
    # aws autoscaling update-auto-scaling-group --auto-scaling-group-name your-asg-name --desired-capacity 0 --min-size 0 --max-size 0
    

    이렇게 하면 CA가 관리하던 노드들은 서서히 드레인(Drain)되고 종료되며, Karpenter가 그 역할을 완전히 넘겨받게 됩니다. 이 과정에서 파드들이 새로운 Karpenter 노드로 잘 재스케줄링되는지 꼼꼼히 확인해야 합니다.

    주의사항 및 트러블슈팅: 삽질 경험

    제가 Karpenter를 도입하면서 겪었던 몇 가지 삽질 경험과 주의사항을 공유합니다. 이걸 미리 아셨다면 여러분은 저보다 훨씬 적게 고생하실 거예요. 😅

    • ⚠️ IAM 권한은 정말 중요합니다!

      Karpenter가 EC2 인스턴스를 직접 다루기 때문에 IAM 권한이 조금만 잘못되어도 노드가 뜨지 않습니다. 특히 ec2:RunInstances, ec2:TerminateInstances, iam:PassRole 등의 권한이 제대로 부여되었는지 반드시 확인하세요. 저는 iam:PassRole을 빼먹어서 한참 헤맸습니다. Karpenter Controller 로그를 확인하면 어떤 권한이 부족한지 명확하게 나옵니다.

      # Karpenter Controller 로그 확인
      kubectl logs -f -n karpenter $(kubectl get pods -n karpenter -l app.kubernetes.io/name=karpenter -o name)
      
    • Pod Disruption Budget (PDB) 고려:

      Karpenter는 노드 통합(Consolidation) 기능을 통해 불필요한 노드를 효율적으로 제거합니다. 이때 PDB (Pod Disruption Budget)가 설정된 파드들은 Karpenter의 노드 종료 작업을 방해할 수 있습니다. PDB가 너무 엄격하면 Karpenter가 노드를 줄이지 못하고 비용이 낭비될 수 있으니, 워크로드의 특성에 맞춰 PDB를 적절히 설정해야 합니다.

    • Initial Scale-up Delay (초기 스케일업 지연) 착시:

      Karpenter는 ASG를 사용하지 않고 바로 EC2 인스턴스를 띄우기 때문에, 처음 노드가 올라올 때까지의 시간이 CA보다 오히려 길게 느껴질 수 있습니다. 하지만 이는 인스턴스 부팅 및 EKS 클러스터 조인(Join) 과정이 포함되기 때문이고, 실제 “스케줄링되지 않은 파드”를 “노드에 할당”하는 과정은 훨씬 빠릅니다. 이 차이를 이해하고 인내심을 가져야 합니다. 🙂

    • Spot Instance Interruptions (스팟 인스턴스 중단) 대비:

      Karpenter는 스팟 인스턴스를 적극 활용하여 비용을 절감하지만, 스팟 인스턴스는 언제든지 AWS에 의해 중단될 수 있습니다. 중요한 스테이트풀(Stateful) 워크로드에는 스팟 인스턴스를 사용하지 않거나, 중단에 강한 아키텍처(예: 분산 시스템, 재시작 가능한 작업)를 구성하는 것이 중요합니다.

    검증 및 결과 확인

    Karpenter 마이그레이션이 성공적으로 이루어졌는지 확인하는 방법은 다음과 같습니다.

    1. 노드 상태 확인: kubectl get nodes 명령으로 노드가 잘 뜨고 준비(Ready) 상태인지 확인합니다. Karpenter가 띄운 노드에는 특정 레이블(Label)이나 태그가 붙어있으니 쉽게 구분할 수 있습니다.
      kubectl get nodes -l karpenter.sh/provisioner-name=default
      # 예시 출력:
      # NAME                                           STATUS   ROLES    AGE   VERSION
      # ip-10-0-x-x.ap-northeast-2.compute.internal    Ready    <none>   5m    v1.28.x
      
    2. 파드 스케줄링 확인: 새로운 파드를 배포하거나, 기존 파드의 리소스 요청을 늘려서 Karpenter가 노드를 빠르게 프로비저닝하고 파드를 스케줄링하는지 확인합니다.
    3. Karpenter Provisioner 상태 확인:
      kubectl describe provisioner default
      # 이 명령을 통해 Karpenter가 어떤 노드를 프로비저닝하고 있는지,
      # 그리고 어떤 이벤트가 발생했는지 상세히 볼 수 있습니다.
      
    4. AWS EC2 콘솔 확인: EC2 콘솔에서 인스턴스가 Karpenter에 의해 생성되고 종료되는 것을 직접 관찰합니다. 태그를 통해 Karpenter가 관리하는 인스턴스인지 쉽게 알 수 있습니다.
    5. 비용 모니터링: AWS Cost Explorer를 통해 마이그레이션 전후의 비용 변화를 모니터링합니다. 특히 스팟 인스턴스 활용률이 높아지면서 비용이 얼마나 절감되었는지 확인하는 것이 중요합니다.
    Karpenter 도입 후 EKS 클러스터의 노드 및 파드 스케일링 성능 대시보드

    Karpenter 도입 후 EKS 클러스터의 노드 및 파드 스케일링 성능 대시보드

    Cluster Autoscaler vs. Karpenter: 비교 및 선택 기준

    제가 경험한 바를 바탕으로 두 오토스케일러의 핵심 차이점을 표로 정리해봤습니다. 어떤 상황에서 어떤 도구가 더 유리한지 판단하는 데 도움이 될 거예요.

    구분 Cluster Autoscaler (CA) Karpenter
    작동 방식 Auto Scaling Group (ASG) 기반 스케줄링되지 않은 파드 직접 감지, EC2 API 호출
    노드 프로비저닝 속도 상대적으로 느림 (ASG의 인스턴스 생성 시간) 매우 빠름 (파드 요구사항에 맞춰 즉시 생성)
    리소스 효율성 ASG 인스턴스 타입 내에서 선택, 비효율 가능성 파드 요구사항에 가장 적합한 인스턴스 선택, 높은 효율성
    비용 최적화 ASG 설정에 의존, 스팟 활용 제한적 스팟 인스턴스 적극 활용, 비용 절감 효과 큼
    관리 복잡성 여러 ASG 관리 필요 Provisioner 리소스 하나로 관리, 단순함
    주요 사용 사례 워크로드 변동이 적고 안정적인 환경, 온디맨드 위주 잦은 스케일링, 비용 최적화, 스팟 인스턴스 적극 활용 환경
    트러블슈팅 난이도 ASG 문제, CA 로그 Karpenter Controller 로그, IAM 권한, Provisioner 설정
    Kubernetes Cluster Autoscaler와 Karpenter의 주요 특징 및 마이그레이션 결정 기준 비교

    Kubernetes Cluster Autoscaler와 Karpenter의 주요 특징 및 마이그레이션 결정 기준 비교

    마무리하며: 더 나은 클러스터 운영을 위한 선택

    Cluster Autoscaler에서 Karpenter로의 마이그레이션은 단순히 도구를 바꾸는 것을 넘어, Kubernetes 클러스터의 리소스 관리 효율성과 비용 최적화를 한 단계 끌어올리는 중요한 결정입니다. 제가 직접 경험해보니, 특히 워크로드 변동성이 크고 스팟 인스턴스 활용을 통해 비용을 절감하고자 하는 환경이라면 Karpenter가 단연코 훌륭한 선택지였습니다.

    물론 새로운 도구를 도입하는 데는 초기 설정과 학습 비용이 따릅니다. 하지만 Karpenter가 제공하는 유연성과 효율성을 고려하면 충분히 투자할 가치가 있다고 생각합니다. 이 글이 여러분의 Karpenter 마이그레이션 여정에 작은 등불이 되었기를 바랍니다. 혹시 더 궁금한 점이나 제가 겪지 못했던 다른 삽질 경험이 있다면 댓글로 공유해주세요. 함께 배우고 성장하는 것이 인프라 엔지니어의 숙명이 아니겠습니까! 다음번에는 Karpenter의 고급 기능이나 다른 클라우드 환경에서의 활용 방안에 대해서도 이야기해볼 수 있으면 좋겠네요. 🎉

  • [Cloud] FinOps 클라우드 비용 관리 베스트 프랙티스 체크리스트 10가지

    [Cloud] FinOps 클라우드 비용 관리 베스트 프랙티스 체크리스트 10가지

    [Cloud] FinOps 클라우드 비용 관리 베스트 프랙티스 체크리스트 10가지

    FinOps 클라우드 비용 최적화 이야기를 하면 아직도 많은 팀이 “일단 쓰고 나중에 정산하자” 모드로 들어가더라고요. 저도 처음엔 그랬습니다. 서비스는 잘 돌아가는데 월말 청구서를 보면 식은땀이 나는 거죠. 특히 멀티 클라우드나 Kubernetes(쿠버네티스, 컨테이너 오케스트레이션) 환경까지 섞이면 누가 왜 돈을 쓰는지 한눈에 안 보입니다. 그래서 오늘은 제가 홈랩과 실무에서 계속 다듬어 온 클라우드 비용 관리 기준을 체크리스트 형태로 정리해보겠습니다. 운영팀, 플랫폼팀, 개발팀이 같이 볼 수 있게 최대한 실전형으로 풀어볼게요.

    이 글은 거창한 이론보다 바로 적용 가능한 FinOps 전략에 집중했습니다. 쉽게 말해, 비용을 줄이는 것만이 아니라 비용 거버넌스를 만들어서 팀이 반복적으로 같은 실수를 하지 않게 만드는 방법이죠. 혹시 청구서가 예측보다 자꾸 커지거나, Reserved Instances(예약 인스턴스)나 Savings Plans(절감 약정) 같은 약정형 할인은 들어봤는데 어디서부터 손대야 할지 막막하셨다면 딱 이 순서대로 보시면 됩니다.

    FinOps 클라우드 비용 최적화 전체 운영 흐름 다이어그램

    비용 데이터 수집, 태깅, 예산, 알림, 최적화, 리뷰까지 이어지는 FinOps 운영 흐름을 한눈에 보여주는 이미지입니다.

    FinOps를 쉽게 말하면 무엇인가

    FinOps(Financial Operations, 재무 중심 클라우드 운영)는 클라우드 사용량과 비용을 기술팀이 직접 이해하고, 재무팀과 함께 최적화하는 운영 방식이에요. 쉽게 말해 “누가 얼마나 쓰는지 보이게 만들고, 그걸 근거로 빠르게 행동하는 문화”에 가까워요. 여기서 중요한 건 단순 절감이 아니라는 거죠. 돈을 덜 쓰는 게 아니라, 필요한 곳에는 제대로 쓰고 낭비는 줄이는 것이 진짜 핵심이거든요.

    제가 직접 해보니 FinOps는 툴 하나 깔면 끝나는 일이 아니었어요. Cost Explorer(비용 탐색), Budgets(예산), 태그 정책, 대시보드, 리뷰 회의까지 다 이어져야 효과가 나더라고요. 처음엔 이게 뭔가 싶었는데, 한 번 체계가 잡히면 “이번 달 왜 20% 늘었지?”를 감으로 추측하지 않아도 돼요. 이거 진짜 편합니다.

    FinOps 클라우드 비용 최적화 체크리스트 10가지

    아래 10가지는 제가 실제로 우선순위를 두는 항목들이에요. 한 번에 다 하려고 하면 지칩니다. 그래서 가시성 확보 → 거버넌스 정착 → 구매 최적화 → 지속 점검 순서로 가는 걸 추천드려요.

    체크 항목 핵심 질문 우선순위
    1. 태그 표준화 누가 어떤 비용을 쓰는지 구분 가능한가? 매우 높음
    2. 계정/프로젝트 분리 환경별 비용이 섞이지 않는가? 매우 높음
    3. 예산과 알림 월말 전에 이상 징후를 잡는가? 매우 높음
    4. 유휴 자원 정리 안 쓰는 리소스가 계속 과금되는가? 높음
    5. 권한/사이즈 적정화 과한 스펙을 기본값처럼 쓰고 있지 않은가? 높음
    6. 약정형 할인 검토 상시 부하는 할인 구매 대상으로 관리하는가? 높음
    7. 스토리지 수명주기 오래된 데이터 보관 정책이 있는가? 중간
    8. Kubernetes 비용 배분 네임스페이스 단위 비용 추적이 되는가? 중간
    9. 대시보드와 리뷰 루틴 숫자를 정기적으로 함께 보는가? 매우 높음
    10. 자동화된 정책 집행 규칙 위반을 자동으로 막는가? 높음

    1. 태그(Tag, 리소스 분류용 메타데이터) 표준을 먼저 만드세요

    비용 최적화의 시작은 거의 항상 태그였어요. 태그가 없으면 비용 배분이 안 되고, 비용 배분이 안 되면 책임 소재도 흐려지죠. 최소한 owner, service, environment, cost-center 정도는 강제하는 편이 좋아요. 저도 예전엔 태그를 권장만 했었는데, 결과는 뻔했습니다. 아무도 안 넣어요 ㅎㅎ 그래서 지금은 생성 단계에서 빠지면 경고가 뜨거나 배포 파이프라인에서 막히게 해둬요.

    2. 계정(Account, 클라우드 계정)과 프로젝트를 용도별로 분리하세요

    개발, 스테이징, 운영을 한 계정에 다 넣어두면 비용이 섞여서 해석이 어려워져요. 특히 운영 이슈 대응 중 임시 리소스를 만들었다가 그대로 남아버리는 경우가 많거든요. 환경 분리는 보안에도 좋고, 클라우드 비용 관리에도 바로 도움이 돼요. 청구서를 볼 때 “이 증가는 운영 때문인가, 테스트 때문인가”가 바로 보여야 합니다.

    3. 예산(Budget, 목표 지출 한도)과 알림을 월초에 설정하세요

    월말에 놀라는 구조를 끊어야 해요. 예산은 금액 기준만 보지 말고, 예측 비용(forecast)과 전월 대비 증가율도 같이 보면 좋아요. 제 경험상 50%, 80%, 100% 세 구간 알림이 실무에서 제일 쓸 만했습니다.

    4. 유휴 자원(Idle Resource) 정리를 정기 작업으로 돌리세요

    안 붙은 EBS 볼륨, 멈춘 줄 알았는데 스냅샷이 계속 쌓이는 디스크, 더 이상 안 쓰는 로드밸런서, 오래된 퍼블릭 IP 같은 것들이 생각보다 커요. 한 건은 작아 보여도 쌓이면 월 비용을 계속 갉아먹어요. 제가 홈랩에서 제일 많이 삽질한 것도 이 부분이었어요. “이 정도야 얼마 안 하겠지” 했는데, 그런 게 제일 무섭더라고요.

    5. Right-sizing(라이트사이징, 적정 사양 조정)을 습관으로 만드세요

    CPU와 메모리를 넉넉하게 주는 건 마음은 편하지만 비용은 절대 안 편해요. 실제 사용량 기반으로 인스턴스 타입과 데이터베이스 스펙을 줄이는 게 중요합니다. 여기서 중요한 포인트! 평균값만 보지 말고 피크 시간대와 주간 패턴도 같이 봐야 해요. 평균 10% 사용률만 보고 줄였다가 월요일 오전에 장애 나는 경우, 생각보다 흔하니까요.

    6. 약정형 할인은 상시 부하에만 적용하세요

    Reserved Instances(예약 인스턴스), Savings Plans(절감 약정) 같은 할인 도구는 강력해요. 다만 변동성이 큰 워크로드에 무턱대고 적용하면 오히려 관리가 꼬여요. 저는 최소 2~3개월 이상 안정적으로 유지되는 상시 부하를 먼저 분류하고, 그중에서 베이스라인 사용량만 할인 대상으로 잡는 편이에요. 공격적으로 사기보다 보수적으로 시작하는 게 덜 아파요.

    7. 스토리지 수명주기(Lifecycle, 데이터 보관 단계)를 정의하세요

    오브젝트 스토리지(Object Storage, 객체 스토리지)는 싸 보이지만, 오래된 로그와 백업이 쌓이면 또 얘기가 달라져요. 접근 빈도에 따라 Standard, Infrequent Access, Archive 계층으로 나누고, 자동 전환 정책을 두면 좋아요. 특히 로그 보존 기간은 법적 요구사항과 운영 현실을 같이 봐야 해요.

    8. Kubernetes 비용은 네임스페이스 단위로 보세요

    Kubernetes 환경에서는 노드 비용만 보면 감이 안 와요. 네임스페이스(namespace), 팀, 서비스 기준으로 비용을 나눠 봐야 누가 비효율적인 요청(requests)과 제한(limits)을 잡고 있는지 드러나거든요. 실제로 써보니까 클러스터 전체 비용만 보는 팀은 최적화가 잘 안 되더라고요. 공용 리소스처럼 느껴져서 책임감이 흐려져요.

    9. 대시보드와 주간 리뷰를 운영 루틴에 넣으세요

    FinOps는 보고서로 끝나면 실패할 확률이 높아요. 비용 대시보드를 만들어도 아무도 안 보면 의미가 없거든요. 그래서 저는 주간 운영 회의에 비용 변화 5분 슬롯을 꼭 넣어요. 전주 대비 급증 서비스, 미태깅 리소스, 예상 초과 예산만 짧게 확인해도 효과가 꽤 커요.

    10. 정책 위반은 자동화로 막으세요

    태그 없는 리소스 생성 금지, 특정 리전(region) 제한, 고가 인스턴스 승인 절차 같은 건 사람이 매번 체크하기 어려워요. Policy as Code(정책의 코드화)나 IaC(코드형 인프라) 파이프라인 검증을 붙이면 비용 거버넌스가 훨씬 안정돼요. 사람이 기억해서 지키는 규칙은 오래 못 가요. 자동화가 진짜 답이에요.

    실전 구현: 바로 적용하는 FinOps 전략

    이제 체크리스트를 실제 운영으로 옮겨보겠습니다. 아래 예시는 AWS 기준 명령을 포함하지만, 구조 자체는 다른 클라우드에도 그대로 응용할 수 있어요. 제가 직접 해보니 처음부터 완벽한 대시보드보다 태그, 예산, 미사용 자원 탐지 세 가지만 먼저 굴리는 게 효과가 가장 빨랐습니다.

    1. 필수 태그 사전 정의: owner, service, environment, cost-center
    2. 주요 계정 또는 프로젝트별 예산 생성: 운영/개발 분리
    3. 일일 비용 수집 자동화: API 또는 비용 리포트 기반
    4. 주간 리뷰 루틴 고정: 증가 원인과 조치 확인
    5. 약정형 할인 검토: 상시 부하만 선별
    # 최근 7일 비용을 서비스 단위로 확인하는 예시
    aws ce get-cost-and-usage \
      --time-period Start=2026-06-23,End=2026-06-30 \
      --granularity DAILY \
      --metrics UnblendedCost \
      --group-by Type=DIMENSION,Key=SERVICE

    위 명령은 가장 단순한 출발점이에요. 서비스 단위 비용 추이를 보고, 급증한 항목이 있으면 거기서 다시 태그나 계정 기준으로 파고드는 식이죠. 처음엔 이 숫자를 어디에 써야 하나 싶었는데, 막상 주간 리포트에 붙여보면 팀 대화가 달라집니다.

    requiredTags:
      - owner
      - service
      - environment
      - cost-center
    rules:
      denyUntaggedResources: true
      blockHighCostInstanceTypes: false
      allowedEnvironments:
        - dev
        - staging
        - prod

    이 YAML은 개념 예시예요. 실제 구현은 Terraform(테라폼, IaC 도구), OPA(Open Policy Agent, 정책 엔진), 클라우드 정책 서비스 등 팀 환경에 맞게 바꾸시면 돼요. 핵심은 “태그는 권장”이 아니라 “태그 없으면 불편하거나 생성 불가” 상태로 만드는 거예요.

    FinOps 클라우드 비용 관리 태그 정책과 예산 알림 설정 이미지

    필수 태그 정책, 예산 임계치, 알림 연결 구조를 함께 보여주는 설정 예시 이미지입니다.

    import csv
    from collections import defaultdict
    
    cost_by_service = defaultdict(float)
    
    with open("cost_report.csv", newline="", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for row in reader:
            service = row.get("service", "unknown")
            amount = float(row.get("cost", 0) or 0)
            cost_by_service[service] += amount
    
    for service, amount in sorted(cost_by_service.items(), key=lambda x: x[1], reverse=True):
        print(f"{service}: {amount:.2f}")

    비용 리포트 CSV만 있어도 이런 식으로 빠르게 합계를 낼 수 있어요. 고급 BI 도구가 없어도 돼요. 작은 팀일수록 이런 단순 자동화가 오히려 오래 가더라고요.

    Kubernetes와 IaC에서 자주 놓치는 포인트

    Kubernetes에서는 requests/limits를 과하게 잡아놓고 실제 사용률은 낮은 경우가 많아요. HPA(Horizontal Pod Autoscaler, 수평 자동 확장)만 믿고 requests는 크게 유지하면 노드가 비효율적으로 채워지거든요. 여기서 꼭 같이 봐야 하는 게 네임스페이스별 비용, 미사용 PersistentVolume(영구 볼륨), 과도한 로그 적재량이에요.

    # 네임스페이스 라벨과 리소스 현황 확인 예시
    kubectl get ns --show-labels
    kubectl top pod -A
    kubectl get pvc -A

    IaC 관점에서는 기본 태그(default tags)를 모듈 레벨에서 강제하는 게 가장 편했어요. 서비스마다 직접 넣게 하면 결국 빠져요. 이전 글에서 다뤘던 IaC 표준화 내용과도 연결되는데, 이건 다음 글에서 Terraform 모듈 기준으로 더 깊게 다뤄볼 예정이에요.

    ⚠️ 실제로 자주 겪는 문제와 트러블슈팅

    여기서부터는 제가 진짜 많이 부딪힌 부분이에요. 삽질 좀 했습니다 ㅎㅎ 미리 알고 가시면 시간 꽤 아끼실 거예요.

    • 태그는 있는데 비용 배분이 이상한 경우: 생성 이후에 태그를 붙인 리소스는 비용 반영 시점이 늦을 수 있어요. 그래서 태그는 생성 시점 강제가 가장 안전해요.
    • 예산 알림이 너무 많이 오는 경우: 계정 전체 예산만 두면 잡음이 커요. 환경 또는 제품군 기준으로 쪼개야 의미 있는 알림이 돼요.
    • 개발용 리소스가 밤새 계속 켜져 있는 경우: 스케줄 기반 종료 자동화를 붙이는 편이 훨씬 나아요. 사람은 자주 잊거든요.
    • 약정형 할인 적용 후 체감이 없는 경우: 실제 상시 사용량보다 많이 구매했을 수 있어요. 온디맨드 사용 패턴과 베이스라인을 먼저 다시 봐야 합니다.
    • Kubernetes 비용이 팀별로 안 보이는 경우: 네임스페이스, 라벨, 클러스터 공용 비용 배분 기준이 먼저 정리되어야 해요.

    특히 비용 알림은 너무 많이 오면 아무도 안 보게 돼요. 보안 알림이든 비용 알림이든 마찬가지더라고요. 그래서 신호 대 잡음비를 높이는 게 중요해요. 진짜 대응해야 할 것만 오게 만들어야 하거든요.

    검증: 무엇을 보면 잘되고 있다고 판단할까

    FinOps 클라우드 비용 최적화가 잘 굴러가는지는 생각보다 간단한 지표로 확인할 수 있어요. 제가 보는 핵심은 네 가지예요. 첫째, 미태깅 리소스 비율이 줄어드는가. 둘째, 예산 초과를 월말이 아니라 중간에 잡는가. 셋째, 유휴 자원 정리 주기가 실제로 돌고 있는가. 넷째, 상시 부하에 대한 할인 적용률이 안정적으로 유지되는가입니다.

    1. 미태깅 리소스 비율 감소
    2. 주간 비용 증가 원인 파악 시간 단축
    3. 개발/운영 환경별 비용 분리 정확도 향상
    4. 유휴 자원 정리 후 재발 방지 자동화 적용
    FinOps 클라우드 비용 최적화 결과 대시보드 이미지

    서비스별 비용 증감, 예산 임계치, 미태깅 리소스 현황을 함께 보여주는 결과 대시보드 이미지입니다.

    실제로 써보니까 대시보드가 화려할 필요는 없었어요. 오히려 이번 주 뭐가 늘었는지, 왜 늘었는지, 누가 액션할지가 바로 보이는 구성이 제일 좋더라고요. 드디어 됐다! 싶은 순간이 이때 와요. 숫자가 회의용 장식이 아니라 운영 도구가 되는 거죠.

    비교로 보는 우선 적용 순서

    영역 빠른 효과 구현 난이도 추천 시점
    태그 표준화 높음 중간 가장 먼저
    예산/알림 높음 낮음 즉시
    유휴 자원 정리 높음 낮음 즉시
    라이트사이징 중간 중간 데이터 확보 후
    약정형 할인 중간~높음 중간 패턴 안정화 후
    정책 자동화 장기적으로 매우 높음 중간~높음 기본 체계 수립 후

    정리와 다음 단계

    오늘 정리한 체크리스트의 핵심은 하나예요. 클라우드 비용 관리는 절감 이벤트가 아니라 운영 체계라는 거예요. 태그, 예산, 유휴 자원 정리, 리뷰 루틴 이 네 가지만 먼저 제대로 굴려도 팀 분위기가 달라져요. 그리고 그 위에 약정형 할인, Kubernetes 비용 배분, 정책 자동화를 차근차근 얹으면 돼요.

    저도 처음엔 FinOps를 재무팀이 보는 숫자 정도로만 생각했었는데, 실제로는 인프라 운영 성숙도를 보여주는 지표에 더 가깝더라고요. 그래서 FinOps 클라우드 비용 최적화는 비용을 아끼는 기술이면서 동시에 운영을 더 예측 가능하게 만드는 기술이에요. 혹시 지금 바로 하나만 시작하신다면, 오늘 안에 예산 알림부터 걸어보세요. 가장 빨리 체감된답니다.

    FinOps 클라우드 비용 관리 체크리스트 10가지 요약 인포그래픽

    태그, 예산, 유휴 자원, 라이트사이징, 할인 전략까지 10가지 체크리스트를 한 장으로 요약한 이미지입니다.

    자주 묻는 질문

    Q1. 작은 팀도 FinOps 전략이 필요한가요?

    필요해요. 오히려 작은 팀일수록 한두 번의 비용 급증이 크게 느껴져요. 복잡한 조직 체계보다 보이는 대시보드와 간단한 규칙이 더 중요합니다.

    Q2. 멀티 클라우드가 아니어도 비용 거버넌스가 필요한가요?

    네. 단일 클라우드라도 서비스가 늘어나면 비용 구조가 금방 복잡해져요. 비용 거버넌스는 규모보다 습관의 문제에 가까워요.

    Q3. 가장 먼저 줄이기 쉬운 비용은 무엇인가요?

    보통은 유휴 자원과 과한 사양이에요. 안 쓰는 디스크, 오래된 스냅샷, 과도한 인스턴스 크기부터 보시면 성과가 빨리 나더라고요.

    이전 글에서 다룬 모니터링 표준화 내용과 함께 보시면 더 연결이 잘 돼요. 다음 글에서는 Terraform 기준으로 태그 강제와 비용 검증 파이프라인을 정리해보겠습니다.