optimize-cloud-costs
정보
이 Claude Skill은 개발자들이 Kubecost와 같은 도구를 사용하여 Kubernetes 클라우드 비용을 최적화하도록 돕습니다. 가시성 확보와 권장 사항을 제공하며, 오버 프로비저닝과 리소스 불일치 문제를 해결하기 위해 오토스케일링, 스팟 인스턴스, 할당량 설정을 구현합니다. 클라우드 비용이 비례하는 가치 없이 증가하거나 쇼백(showback)을 통해 내부 비용 책임성을 확립해야 할 때 사용하세요.
빠른 설치
Claude Code
추천npx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/optimize-cloud-costsClaude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요
문서
Optimize Cloud Costs
Implement cost optimization for Kubernetes clusters to cut cloud spend.
When Use
- Cloud costs growing without business value increase
- Need cost allocation visibility by team, app, environment
- Resource requests/limits not aligned with actual usage
- Manual scaling causes over-provisioning, waste
- Want spot/preemptible instances for non-critical workloads
- Need showback or chargeback for internal cost allocation
- Establishing FinOps culture with cost awareness, accountability
Inputs
- Required: Kubernetes cluster with workloads running
- Required: Cloud provider billing API access
- Required: Metrics server or Prometheus for resource metrics
- Optional: Historical usage data for trend analysis
- Optional: Cost allocation requirements (by namespace, label, team)
- Optional: SLOs for performance constraints
- Optional: Budget limits or cost reduction targets
Steps
See Extended Examples for complete configuration files and templates.
Step 1: Deploy Cost Visibility Tools
Install Kubecost or OpenCost for cost monitoring and allocation.
Install Kubecost:
# Add Kubecost Helm repository
helm repo add kubecost https://kubecost.github.io/cost-analyzer/
helm repo update
# Install Kubecost with Prometheus integration
helm install kubecost kubecost/cost-analyzer \
--namespace kubecost \
--create-namespace \
--set kubecostToken="your-token-here" \
--set prometheus.server.global.external_labels.cluster_id="production-cluster" \
--set prometheus.nodeExporter.enabled=true \
--set prometheus.serviceAccounts.nodeExporter.create=true
# For existing Prometheus, configure Kubecost to use it
helm install kubecost kubecost/cost-analyzer \
--namespace kubecost \
--create-namespace \
--set prometheus.enabled=false \
--set global.prometheus.fqdn="http://prometheus-server.monitoring.svc.cluster.local" \
--set global.prometheus.enabled=true
# Verify installation
kubectl get pods -n kubecost
kubectl get svc -n kubecost
# Access Kubecost UI
kubectl port-forward -n kubecost svc/kubecost-cost-analyzer 9090:9090
# Open http://localhost:9090
Configure cloud provider integration:
# kubecost-cloud-integration.yaml
apiVersion: v1
kind: Secret
metadata:
name: cloud-integration
namespace: kubecost
type: Opaque
stringData:
# For AWS
cloud-integration.json: |
{
"aws": [
{
"serviceKeyName": "AWS_ACCESS_KEY_ID",
"serviceKeySecret": "AWS_SECRET_ACCESS_KEY",
"athenaProjectID": "cur-query-results",
"athenaBucketName": "s3://your-cur-bucket",
"athenaRegion": "us-east-1",
"athenaDatabase": "athenacurcfn_my_cur",
"athenaTable": "my_cur"
}
]
}
---
# For GCP
apiVersion: v1
kind: Secret
metadata:
name: gcp-key
namespace: kubecost
type: Opaque
data:
key.json: <base64-encoded-service-account-key>
---
# For Azure
apiVersion: v1
kind: ConfigMap
metadata:
name: azure-config
namespace: kubecost
data:
azure.json: |
{
"azureSubscriptionID": "your-subscription-id",
"azureClientID": "your-client-id",
"azureClientSecret": "your-client-secret",
"azureTenantID": "your-tenant-id",
"azureOfferDurableID": "MS-AZR-0003P"
}
Apply cloud integration:
kubectl apply -f kubecost-cloud-integration.yaml
# Verify cloud costs are being imported
kubectl logs -n kubecost -l app=cost-analyzer -c cost-model --tail=100 | grep -i "cloud"
# Check Kubecost API for cost data
kubectl port-forward -n kubecost svc/kubecost-cost-analyzer 9090:9090 &
curl http://localhost:9090/model/allocation\?window\=7d | jq .
Got: Kubecost pods running. UI shows cost breakdown by namespace, deployment, pod. Cloud provider costs importing (may take 24-48 hours for initial sync). API returning allocation data.
If fail:
- Check Prometheus running and accessible:
kubectl get svc -n monitoring prometheus-server - Verify cloud credentials have billing API access
- Review cost-model logs:
kubectl logs -n kubecost -l app=cost-analyzer -c cost-model - Ensure metrics-server or Prometheus node-exporter collecting resource metrics
- Check for network policies blocking access to cloud billing APIs
Step 2: Analyze Current Resource Utilization
Identify over-provisioned resources and optimization opportunities.
Query resource utilization:
# Get resource requests vs usage for all pods
kubectl top pods --all-namespaces --containers | \
awk 'NR>1 {print $1,$2,$3,$4,$5}' > current-usage.txt
# Compare requests to actual usage
cat <<'EOF' > analyze-utilization.sh
#!/bin/bash
echo "Pod,Namespace,CPU-Request,CPU-Usage,Memory-Request,Memory-Usage"
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
kubectl get pods -n $ns -o json | jq -r '
.items[] |
select(.status.phase == "Running") |
{
name: .metadata.name,
namespace: .metadata.namespace,
containers: [
.spec.containers[] |
{
name: .name,
cpuReq: .resources.requests.cpu,
memReq: .resources.requests.memory
}
]
} |
"\(.name),\(.namespace),\(.containers[].cpuReq // "none"),\(.containers[].memReq // "none")"
' 2>/dev/null
done
EOF
chmod +x analyze-utilization.sh
./analyze-utilization.sh > resource-requests.csv
# Get actual usage from metrics server
kubectl top pods --all-namespaces --containers > actual-usage.txt
Use Kubecost recommendations:
# Get right-sizing recommendations via API
curl "http://localhost:9090/model/savings/requestSizing?window=7d" | jq . > recommendations.json
# Extract top wasteful resources
jq '.data[] | select(.totalRecommendedSavings > 10) | {
cluster: .clusterID,
# ... (see EXAMPLES.md for complete configuration)
Create utilization dashboard:
# grafana-utilization-dashboard.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: utilization-dashboard
namespace: monitoring
# ... (see EXAMPLES.md for complete configuration)
Got: Clear view of current resource requests vs actual usage. Pods with <30% utilization (over-provisioned) identified. List of optimization opportunities with estimated savings. Dashboard showing utilization trends over time.
If fail:
- Ensure metrics-server running:
kubectl get deployment metrics-server -n kube-system - Check Prometheus has node-exporter metrics:
curl http://prometheus:9090/api/v1/query?query=node_cpu_seconds_total - Verify pods running long enough for meaningful data (at least 24 hours)
- Check gaps in metrics collection: review Prometheus retention and scrape intervals
- For Kubecost, ensure it has collected at least 48 hours of data
Step 3: Implement Horizontal Pod Autoscaling (HPA)
Configure automatic scaling based on CPU, memory, or custom metrics.
Create HPA for CPU-based scaling:
# hpa-cpu.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
namespace: production
# ... (see EXAMPLES.md for complete configuration)
Deploy and verify HPA:
kubectl apply -f hpa-cpu.yaml
# Check HPA status
kubectl get hpa -n production
kubectl describe hpa api-server-hpa -n production
# Monitor scaling events
kubectl get events -n production --field-selector involvedObject.kind=HorizontalPodAutoscaler --watch
# Generate load to test autoscaling
kubectl run load-generator --rm -it --image=busybox -- /bin/sh -c \
"while true; do wget -q -O- http://api-server.production.svc.cluster.local; done"
# Watch replicas scale
watch kubectl get hpa,deployment -n production
Got: HPA created showing current/target metrics. Pods scale up under load. Pods scale down when load decreases (after stabilization window). Scaling events logged. No thrashing (rapid scale up/down cycles).
If fail:
- Verify metrics-server running:
kubectl get apiservice v1beta1.metrics.k8s.io - Check deployment has resource requests set (HPA requires this)
- Review HPA events:
kubectl describe hpa api-server-hpa -n production - Ensure target deployment not at max replicas
- For custom metrics, verify metrics adapter installed and configured
- Check HPA controller logs:
kubectl logs -n kube-system -l app=kube-controller-manager | grep horizontal-pod-autoscaler
Step 4: Configure Vertical Pod Autoscaling (VPA)
Auto-adjust resource requests based on actual usage patterns.
Install VPA:
# Clone VPA repository
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
# Install VPA
./hack/vpa-up.sh
# Verify installation
kubectl get pods -n kube-system | grep vpa
# Check VPA CRDs
kubectl get crd | grep verticalpodautoscaler
Create VPA policies:
# vpa-policies.yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-server-vpa
namespace: production
# ... (see EXAMPLES.md for complete configuration)
Deploy and monitor VPA:
kubectl apply -f vpa-policies.yaml
# Check VPA recommendations
kubectl get vpa -n production
kubectl describe vpa api-server-vpa -n production
# View detailed recommendations
kubectl get vpa api-server-vpa -n production -o jsonpath='{.status.recommendation}' | jq .
# Monitor VPA-initiated pod updates
kubectl get events -n production --field-selector involvedObject.kind=VerticalPodAutoscaler --watch
# Compare recommendations to current requests
kubectl get deployment api-server -n production -o json | \
jq '.spec.template.spec.containers[].resources.requests'
Got: VPA providing recommendations or auto-updating resource requests. Recommendations based on percentile usage patterns (typically P95). Pods restarted with new requests when using Auto/Recreate mode. No conflicts between HPA and VPA (HPA for replicas, VPA for resources per pod).
If fail:
- Ensure metrics-server has sufficient data (VPA needs several days for accurate recommendations)
- Check VPA components running:
kubectl get pods -n kube-system | grep vpa - Review VPA admission controller logs:
kubectl logs -n kube-system -l app=vpa-admission-controller - Verify webhook registered:
kubectl get mutatingwebhookconfigurations vpa-webhook-config - Don't use VPA and HPA on same metric (CPU/memory) — causes conflicts
- Start with "Off" mode to review recommendations before enabling auto updates
Step 5: Leverage Spot/Preemptible Instances
Configure workload scheduling on cost-effective spot instances.
Create node pools with spot instances:
# For AWS (via Karpenter)
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: spot-provisioner
spec:
# ... (see EXAMPLES.md for complete configuration)
Configure workloads for spot instances:
# spot-workload.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: batch-processor
namespace: production
# ... (see EXAMPLES.md for complete configuration)
Deploy and monitor spot usage:
kubectl apply -f spot-workload.yaml
# Monitor spot node allocation
kubectl get nodes -l node-type=spot
# Check workload distribution
# ... (see EXAMPLES.md for complete configuration)
Got: Workloads scheduled on spot nodes. Significant cost reduction (typically 60-90% vs on-demand). Graceful handling of spot interruptions with pod rescheduling. Monitoring shows spot interruption rate and successful recovery.
If fail:
- Verify spot instance availability in your region/zones
- Check node labels and taints match workload tolerations
- Review Karpenter logs:
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter - Ensure workloads stateless or have proper state management for interruptions
- Test interruption handling: manually cordon and drain spot node
- Monitor interruption rate — too high? Consider fallback to on-demand nodes
Step 6: Implement Resource Quotas and Budget Alerts
Set hard limits and alerting for cost control.
Create resource quotas:
# resource-quotas.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
# ... (see EXAMPLES.md for complete configuration)
Configure budget alerts:
# kubecost-budget-alerts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: budget-alerts
namespace: kubecost
# ... (see EXAMPLES.md for complete configuration)
Apply and monitor:
kubectl apply -f resource-quotas.yaml
kubectl apply -f kubecost-budget-alerts.yaml
# Check quota usage
kubectl get resourcequota -n production
kubectl describe resourcequota production-quota -n production
# ... (see EXAMPLES.md for complete configuration)
Got: Resource quotas enforcing limits per namespace. Pod creation blocked when quota exceeded. Budget alerts firing when thresholds breached. Cost spike detection working. Regular reports sent to stakeholders.
If fail:
- Verify ResourceQuota and LimitRange applied:
kubectl get resourcequota,limitrange -A - Check pods failing due to quota:
kubectl get events -n production | grep quota - Review Kubecost alert configuration:
kubectl logs -n kubecost -l app=cost-analyzer | grep alert - Ensure Prometheus has Kubecost metrics:
curl http://prometheus:9090/api/v1/query?query=kubecost_monthly_cost - Test alert routing: verify email/Slack webhook configuration
Checks
- Kubecost or OpenCost deployed and showing accurate cost data
- Cloud provider billing integration working (costs match actual bills)
- Resource utilization analysis identifies over-provisioned workloads
- HPA scaling pods based on load (verified with load test)
- VPA providing recommendations or auto-adjusting resource requests
- Spot instances handling interruptions gracefully
- Resource quotas enforcing limits per namespace
- Budget alerts firing when thresholds exceeded
- Monthly cost trending downward or staying within budget
- Showback reports generated for teams/projects
- No performance degradation from cost optimizations
- Documentation updated with optimization practices
Pitfalls
-
Aggressive Right-Sizing: Don't immediately apply VPA recommendations. Start with "Off" mode, review suggestions for week, gradually apply. Sudden changes cause OOMKills or CPU throttling.
-
HPA + VPA Conflict: Never use HPA and VPA on same metric (CPU/memory). Use HPA for horizontal scaling, VPA for per-pod resource tuning, or HPA on custom metrics + VPA on resources.
-
Spot Without Fault Tolerance: Only run fault-tolerant, stateless workloads on spot. Never databases, stateful services, or single-replica critical services. Always use PodDisruptionBudgets.
-
Insufficient Monitoring Period: Cost optimization decisions need historical data. Wait at least 7 days before making changes, 30 days for VPA recommendations, 90 days for trend analysis.
-
Ignoring Burst Requirements: Setting limits too low based on average usage causes throttling during traffic spikes. Use P95 or P99 percentiles, not average, for capacity planning.
-
Network Egress Costs: Compute costs visible in Kubecost, but egress (data transfer) can be significant. Monitor cross-AZ traffic, use topology-aware routing, consider data transfer costs in architecture.
-
Storage Overlooked: PersistentVolume costs often forgotten. Audit unused PVCs, right-size volumes, use volume expansion instead of over-provisioning, implement PV cleanup policies.
-
Quota Too Restrictive: Quotas too low block legitimate growth. Review quota usage monthly, adjust based on actual needs, communicate limits to teams before enforcement.
-
False Savings from Wrong Metrics: CPU/memory as sole optimization metric misses I/O, network, storage costs. Consider total cost of ownership, not just compute.
-
Chargeback Before Trust: Implementing chargeback before teams understand and trust cost data causes friction. Start with showback (informational), build culture of cost awareness, then move to chargeback.
See Also
deploy-to-kubernetes- Application deployment with appropriate resource requestssetup-prometheus-monitoring- Monitoring infrastructure for cost metricsplan-capacity- Capacity planning based on cost and performancesetup-local-kubernetes- Local development to avoid cloud costswrite-helm-chart- Templating resource requests and limitsimplement-gitops-workflow- GitOps for cost-optimized configurations
GitHub 저장소
연관 스킬
railway-docs
문서이 스킬은 Railway의 기능, 작동 방식 또는 특정 문서 URL에 대한 질문에 답하기 위해 최신 Railway 문서를 가져옵니다. 개발자들이 Railway의 공식 소스로부터 정확하고 최신 정보를 직접 받을 수 있도록 보장합니다. 사용자가 Railway의 작동 방식을 묻거나 Railway 문서를 참조할 때 사용하세요.
n8n-code-python
문서이 Claude Skill은 n8n의 Code 노드에서 Python 코드를 작성할 때 전문적인 지침을 제공하며, 특히 Python 표준 라이브러리 사용과 n8n의 특수 구문인 `_input`, `_json`, `_node` 작업에 중점을 둡니다. 이는 개발자가 n8n 내에서 Python의 제한 사항을 이해하도록 돕고, 대부분의 워크플로에는 JavaScript 사용을 권장하면서도 특정 데이터 변환 요구사항에 대한 Python 솔루션을 제안합니다.
archon
문서Archon 스킬은 REST API를 통해 RAG 기반 시맨틱 검색과 프로젝트 관리를 제공합니다. 이 스킬을 사용하여 문서 검색, 계층적 프로젝트/태스크 관리, 문서 업로드 기능을 갖춘 지식 검색을 수행할 수 있습니다. 외부 문서를 검색할 때는 다른 소스를 사용하기 전에 항상 Archon을 최우선으로 활용하세요.
n8n-code-javascript
문서이 Claude Skill은 n8n의 Code 노드에서 JavaScript 코드 작성에 대한 전문적인 지침을 제공합니다. `$input`/`$json` 변수, HTTP 헬퍼, DateTime 처리와 같은 필수적인 n8n 특정 구문을 다루며 일반적인 오류를 해결합니다. Code 노드에서 사용자 정의 JavaScript 처리가 필요한 n8n 워크플로우를 개발할 때 활용하세요.
