이 글은 가시다님과 함께하는 AEWS 3기의 내용을 정리한 것입니다
이번 포스팅에서는 kubecost를 설치하고 사용하는 방법을 워크샵을 통해 알아보고자 합니다.
일부 명령어는 워크샵에서 사용하는 것을 바로 적용할 경우 안되는게있어 개인적으로 커스텀하였습니다.
워크샵 정보
https://www.eksworkshop.com/docs/observability/kubecost/
Cost visibility with Kubecost | EKS Workshop
Gain cost visibility and insights for teams using Amazon Elastic Kubernetes Service with Kubecost.
www.eksworkshop.com
kubecost란?
간략하게 kubecost를 소개하면 kubernetes 클러스터의 비용을 모니터링하고 최적화하는 오픈소스 솔루션입니다. 다양한 필터를 통해 관리하고 비용을 시각화 및 리포팅까지 해주는 귀중한 툴입니다.
주요기능은 다음과 같습니다.
- 실시간 비용 모니터링 – Kubernetes 리소스(CPU, 메모리, 스토리지 등) 사용량 기반 비용 분석
- 비용 최적화 제안 – 불필요한 리소스 낭비 감지 및 최적화 방안 제공
- 팀 및 네임스페이스별 비용 할당 – 워크로드별 비용 분배 및 태깅 지원
- 클라우드 네이티브 통합 – AWS, GCP, Azure 등 다양한 클라우드 환경과 연동 가능
- Prometheus 기반 데이터 수집 – Prometheus 및 Grafana와 통합하여 강력한 시각화 지원
실습 준비
실습에서는 다음 내용을 필요로 합니다.
사전 설정을 준비하려면 깃허브에서 코드를 다운받아 테라폼으로 설치하면됩니다.
- AWS EKS Cluster
- EBS CSI Driver
EBS CSI Driver가 없으신 분은 아래 명령어로 설치하시기 바랍니다!!!
aws eks describe-addon-versions \
--addon-name aws-ebs-csi-driver \
--kubernetes-version 1.31 \
--query "addons[].addonVersions[].[addonVersion, compatibilities[].defaultVersion]" \
--output text
# ISRA 설정 : AWS관리형 정책 AmazonEBSCSIDriverPolicy 사용
eksctl create iamserviceaccount \
--name ebs-csi-controller-sa \
--namespace kube-system \
--cluster ${CLUSTER_NAME} \
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
--approve \
--role-only \
--role-name AmazonEKS_EBS_CSI_DriverRole
# ISRA 확인
eksctl get iamserviceaccount --cluster ${CLUSTER_NAME}
# Amazon EBS CSI driver addon 배포(설치)
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
eksctl create addon --name aws-ebs-csi-driver --cluster ${CLUSTER_NAME} --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_EBS_CSI_DriverRole --force
kubectl get sa -n kube-system ebs-csi-controller-sa -o yaml | head -5
# 확인
eksctl get addon --cluster ${CLUSTER_NAME}
kubectl get deploy,ds -l=app.kubernetes.io/name=aws-ebs-csi-driver -n kube-system
kubectl get pod -n kube-system -l 'app in (ebs-csi-controller,ebs-csi-node)'
kubectl get pod -n kube-system -l app.kubernetes.io/component=csi-driver
# ebs-csi-controller 파드에 6개 컨테이너 확인
kubectl get pod -n kube-system -l app=ebs-csi-controller -o jsonpath='{.items[0].spec.containers[*].name}' ; echo
ebs-plugin csi-provisioner csi-attacher csi-snapshotter csi-resizer liveness-probe
이렇게 EBS CSI controller를 설치하고 EBS를 통해 Storage Class를 반드시 생성해야합니다.
cat <<EOF | kubectl apply -f -
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp3
annotations:
storageclass.kubernetes.io/is-default-class: "true"
allowVolumeExpansion: true
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
allowAutoIOPSPerGBIncrease: 'true'
encrypted: 'true'
fsType: xfs
EOF
제가 이 도전과제를 선택한 이유는 kubecost를 주변에서 많이 추천해서 사용해보고 싶었습니다.
아무래도 쿠버네티스는 비용예측이 쉽지 않고, 지속해서 변동성을 가지고 있기 때문에 kubecost가 비용을 체크하는데 큰 도움이 될 것입니다.
kubecost는 말 그대로 비용 가시성과 통찰력을 실시간으로 제공할 수 있는 툴입니다.
이를 통해서 네임스페이스, 클러스터, 파드, 조직 등 다양한 관점에서 비용을 추적하고 평가할 수 있도록 설계되어 있습니다.
무엇보다 다중 클러스터 환경이나 테넌트별 비용 분석이 필요한 경우에도 유용하다고 하니 정말 안쓸이유가 없습니다.
kubecost는 2019년부터 시작했다고하는데요 OpenCost 기반으로 CNCF SandBox 프로젝트로 승인되어 AWS에서 적극지원하고 있다고 합니다.
(참고) CDK Observability Accelerator Add-on
참고로 CDK Observability Accelerator를 사용한다면 kubecost addon을 사용할 수 있습니다. 근데 Accelerator 많이 사용하시나요? 저는 아직까지는 사용하는 분은 못봐서 혹시 사용하신다면 경험을 듣고싶습니다. addon으로 설치가 너무 간단해서 여기서 확인하시면 됩니다.
설치는 이렇게 npm으로 하고
npm install @kubecost/kubecost-eks-blueprints-addon
사용은 그냥 바로 import 시키면 됩니다.
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import * as blueprints from '@aws-quickstart/eks-blueprints';
import { KubecostAddOn } from '@kubecost/kubecost-eks-blueprints-addon';
const app = new cdk.App();
const addOn = new KubecostAddOn();
const blueprint = blueprints.EksBlueprint.builder()
.version("auto")
.addOns(addOn)
.build(app, 'my-stack-name');
자 이제 다시 워크숍으로 돌아옵시다.
워크숍의 명령어가 바로 적용되지 않아 제가 나름대로 수정한 내용임을 참고해주세요!!
일단 public ecr에 로그인 해줍니다. 기본적으로 us-east-1을 그냥 사용해주시면 됩니다. 그리고 가끔 버전 정보가 조회되지 않거나 입력이 안되는 경우가 있으므로 helm show 명령어로 최신 버전을 조회할 수 있습ㄴ디ㅏ.
aws ecr-public get-login-password \
--region us-east-1 | helm registry login \
--username AWS \
--password-stdin public.ecr.aws
helm show chart oci://public.ecr.aws/kubecost/cost-analyzer

지금은 이렇게 2.6.3 버전입니다.

kubecost는 다음과 같이 cost-analyzer, forecasting, prometheus-server로 이뤄져있습니다.
처음에 말했듯 StorageClass를 반드시 먼저 설치하셔야 합니다. helm에서는 PVC만 만들기 때문에 SC가 없으면 PV가 생성되지 못합니다. 그러면 pod가 안뜹니다.

이제 우리가 콘솔에 접근하기 편하도록 LB를 만들어 외부접속을 허용해보겠습니다.
서비스를 로드밸런서 타입으로 변경합니다.
export KUBECOST_SERVER=$(kubectl get svc -n kubecost kubecost-cost-analyzer -o json | jq --raw-output '.status.loadBalancer.ingress[0].hostname'):9090
echo "Kubecost URL: http://$KUBECOST_SERVER"

다음과 같이 콘솔화면이 잘 뜨는것을 확인할 수 있습니다.
잠깐 돌리니까 벌써부터 비용 계산을 시작했네요.

실습에서는 로드밸런서가 잘 접근되는지 확인할 수 있는 명령어도 제공하고 있습니다.
curl --head -X GET --retry 20 --retry-all-errors --retry-delay 15 \
--connect-timeout 5 --max-time 10 \
http://$KUBECOST_SERVER

자 이제 본격적으로 Kubecost를 통해 비용을 측정하고 줄이는 방법을 알아봅시다.
Cost Allocation (비용 할당)
Cost Allocation 메뉴에서는 다음 내용을 살펴봅니다.
- namespace
- deployment
- pod
- labels
그런데 제가 Filter에서 살펴보면 Cluster, Node 등 정말 다양한 방법으로 필터링이 가능합니다.

Aggregate - 집합체 만들기
그리고 날짜 옆에 Aggregate 버튼이 있는데, 이걸 통해서 구분을 나눌 수 있습니다. 예를 들면 지금 pod이죠,

이런식으로 파드 별로 세분화해서 볼 수 있습니다.

그리고 이걸 multi aggregation을 선택하면 다중으로 선택이 가능한데, pod와 node를 선택해봤습니다. 그럼 파드와 노드가 모두 구분되어 보이는 것을 확인할 수 있습니다.

보고서 만들기
이렇게 점3개 버튼을 누른뒤에 Download로 report를 만들 수 있습니다.

pdf로 뽑아봤는데요. 기존에 설정한 aggregate설정 값으로 필터링 되어서 나옵니다. 정말 보고서 자체도 퀄리티가 괜찮다고 생각됩니다.
네임스페이스 별로 뽑아봤습니다.

이 외에도 실제 네임스페이스나 파드등 여러 리소스들을 선택하면 이와같이 CPU, GPU, RAM 등 어디에 비용이 많이 부과되는지 알수있으며 신기한건 LB에 대한 과금도 판별해낸다는 겁니다. 지금 아무래도 kubecost가 Service 타입중 LB도 있다보니 0.04 달러의 비용이 부과되는걸 확인할 수 있습니다.

이러한 뷰들은 어떤 부분을 최적화할 수 있는지 확인하고 관리할 수 있습니다. 좀 더 확장하면 네임스페이스 별로 서비스나 팀을 나눌 수도 있고, 멀티 클러스터의 비용도 효과적으로 관리할 수 있을 것입니다.
Assets
다음은 Asset입니다. 이는 kubecost에 prometheus가 같이 있기 때문에 가능한 것으로 보입니다.
인스턴스의 자원부터 시작해서 다양한 리소스의 정보를 확인할 수 있고, 이것들의 비용이 어떻게 되는지 알 수 있습니다.

근데 진짜 생각보다 정보가 너무 자세하고 많아서 놀라웠습니다.

Cloud Cost Explorer
아마 클라우드 비용 Explorer들을 추가하여 한눈에 볼 수 있도록 통합형 서비스를 제공하는 것 같습니다.
점점 확장성이 매우 좋다고 느껴집니다.

이 외에도 External Costs / Efficiency 등이 추가되었습니다.
External Costs의 경우 공식문서에서는 Beta 버전이며 Datadog이 추가가능하다고 밝히고 있습니다.


Savings
Savings에서는 비용 절감에 대한 인사이트를 제공합니다.

아래는 컨테이너 사이즈가 적절한지 리소스 사용량에 대한 분석자료인데 정말 훌륭하다고 생각이 듭니다.

Alerts
알림 기능은 슬렉이랑 Teams 연동이 가능합니다. 클러스터 헬스 체크도 가능하기 때문에 유용하다고 생각됩니다.

Amazon Managed Service 연동하기
워크샵의 마지막 부분은 Amazon Managed Service for Prometheus(AMP)를 연동하여 사용하는 방법을 가이드하고 있습니다.
GPT의 도움을 받아서 이 둘의 차이를 살펴보았는데요. 기본적으로 AWS에 통합하여 워크로드 확장성을 고려한다면 AMP를 사용해볼 수 있을 것같고, 일반적인 경우는 기본 Prometheus만 사용해도 충분하다는 생각입니다.
확장이 잦고 대규모 클러스터를 사용하고 AWS에 의존적인 회사면 AMP를 한번 써보실 것을 권장합니다.

기본적으로 AMP를 사용하면 prometheus 쿼리 언어를 통해 기본 모니터링 인프라를 자동으로 가져오고 알림을 보낼 수 있다고 합니다. 워크로드 확장성에 대해서도 자동으로 확장합니다. 또한 AWS 보안 서비스에 자동으로 통합되어 접근이 용이하다고 하네요.

위 그림은 Kubecost가 AMP에 통합되는 방식을 그린 이미지로 SigV4 프록시를 통해 AMP를 쿼리합니다. SigV4는 HTTP에서 보낸 AWS API 요청에 인증정보를 추가하는 프로세스로 우리 IAM의 자격증명을 사용할 수 있습니다.
각 단계별로 간단히 설명해보겠습니다.
1. Ingest(데이터 수집)
kubecost의 Cost model이 AWS의 public pricing data 와 AWS Cost & Usage 즉 비용 결제 서비스의 값을 기반으로 쿠버네티스 리소스 사용량에 대한 비용을 계산합니다.
2. Scrape (Prometheus 메트릭 수집)
EKS 클러스터 및 kubecost cost analyzer pod를 활용해 데이터를 수집합니다.
3. rewirte(prometheus가 AMP로 데이터 전송)
수집된 메트릭 데이터를 AMP로 원격 write 합니다. prometheus는 데이터를 로컬 DB에 저장하는 대신 AWS의 AMP 워크스페이스로 전송합니다.
4. Query (AMP에서 데이터 조회)
kubecost의 cost model에 필요한 메트릭 데이터를 AMP에서 쿼리하여 가져오고 비용을 계산합니다.
이때 AWS SigV4 Proxy를 사용해 자격증명으로 인증하며, Prometheus 쿼리언어인 PromQL을 활용합니다.
5. Expose (데이터 시각화 및 대시보드 노출)
최종적으로 프론트엔드 대시보드에 비용 데이터를 시각화하여 보여줍니다.
자 그럼 블로그를 통해서 실습해봅시다.
https://aws.amazon.com/ko/blogs/mt/integrating-kubecost-with-amazon-managed-service-for-prometheus/
Integrating Kubecost with Amazon Managed Service for Prometheus | Amazon Web Services
This blog post was co-written by Linh Lam, Solution Architect, Kubecost Customers can track their Kubernetes control plane and Amazon Elastic Compute Cloud (Amazon EC2) costs using AWS Cost and Usage Reports. However, they often need deeper insights to acc
aws.amazon.com
기본적으로 EBS CSI Controller와 EKS, kubecost를 설치한 상태로 진행합니다.
IRSA 생성
eksctl create iamserviceaccount \
--name kubecost-cost-analyzer \
--namespace kubecost \
--cluster $CLUSTER_NAME --region $REGION \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonPrometheusQueryAccess \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess \
--override-existing-serviceaccounts \
--approve
eksctl create iamserviceaccount \
--name kubecost-prometheus-server \
--namespace kubecost \
--cluster $CLUSTER_NAME --region $REGION \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonPrometheusQueryAccess \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess \
--override-existing-serviceaccounts \
--approve
역할이 잘 만들어졌는지 확인해봅시다.
aws iam list-roles | grep kubecost

잘 만들어진게 확인되면 amp workspace를 생성해봅시다.
aws amp create-workspace --alias kubecost-amp --region <REGION>

생성되면 이렇게 됩니다.

콘솔에서도 잘 만들어진 걸 확인할 수 있습니다.

자 이제 SigV4 인증을 위해서 config파일을 생성합니다.
cat << EOF > config-values.yaml
global:
amp:
enabled: true
prometheusServerEndpoint: http://localhost:8005/workspaces/${AMP_WORKSPACE_ID}
remoteWriteService: https://aps-workspaces.${AWS_REGION}.amazonaws.com/workspaces/${AMP_WORKSPACE_ID}/api/v1/remote_write
sigv4:
region: ${AWS_REGION}
sigV4Proxy:
region: ${AWS_REGION}
host: aps-workspaces.${AWS_REGION}.amazonaws.com
EOF
이제 helm에 해당 config 파일을 반영합니다.
helm upgrade -i kubecost \
oci://public.ecr.aws/kubecost/cost-analyzer --version $VERSION \
--namespace kubecost --create-namespace \
-f https://tinyurl.com/kubecost-amazon-eks \
-f config-values.yaml

APS랑 통신이 되는지는 다음 명령어로 확인가능합니다.
kubectl logs -n kubecost deploy/kubecost-prometheus-server --tail=50
저는 권한 연동이 잘못되었는지 에러가 나와서 해당 역할에 권한을 부여하였습니다.

prometheus에 deployment를 rollout하여 반영합니다.
kubectl rollout restart deployment/kubecost-prometheus-server -n kubecost
잘되네요.

이상으로 kubecost에 대한 도전과제 포스팅을 마칩니다.