🎯 Mục tiêu bài học
Hiểu và áp dụng các chiến lược tối ưu chi phí Kubernetes trong cloud: Spot instances, right-sizing, node consolidation, và cost visibility tools.
1. Tại sao K8s thường tốn kém hơn mong đợi?
- Over-provisioning: requests/limits set quá cao so với actual usage
- Idle nodes: nodes không được sử dụng hiệu quả (utilization < 30%)
- Kube-system overhead: daemonsets (Cilium, logging agents) chiếm resource
- PVs không dùng: PersistentVolumes của environments đã xóa vẫn tính tiền
- Load balancers: mỗi LoadBalancer Service = 1 cloud LB ($18-30/tháng)
- Data transfer: cross-AZ traffic giữa pods tốn tiền
2. Spot/Preemptible Instances
# Karpenter NodePool với spot instances
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: spot-workers
spec:
template:
spec:
nodeClassRef:
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"] # chỉ dùng spot
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"] # diversify instance families
- key: karpenter.k8s.aws/instance-generation
operator: Gt
values: ["3"]
disruption:
budgets:
- nodes: 20% # tối đa 20% nodes bị replace cùng lúc
# Workloads chịu được spot interruption cần: # 1. Toleration spot taint # 2. PodDisruptionBudget # 3. Graceful shutdown (terminationGracePeriodSeconds)spec: tolerations:
- key: karpenter.sh/capacity-type value: spot effect: NoSchedule
terminationGracePeriodSeconds: 60 # handle SIGTERM trước khi spot terminate
3. Karpenter Node Consolidation
# Karpenter tự động consolidate: dồn pods vào ít nodes hơn
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: general
spec:
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 1m # remove sau 1 phút nếu underutilized
# budgets: giới hạn số nodes bị disrupt cùng lúc
budgets:
- nodes: "10%" # tối đa 10% nodes trong 1 lần
- nodes: "0" # không consolidate trong giờ cao điểm
schedule: "0 8 * * 1-5" # cron: 8am-5pm weekdays
duration: 9h
# Xem consolidation hoạt động kubectl get nodes -w # Nodes được terminate tự động khi utilization thấpThống kê Karpenter
kubectl get nodeclaims kubectl get nodepools -o wide
Force consolidation
kubectl annotate nodepool general karpenter.sh/do-not-consolidate=false
4. Right-sizing với VPA và Goldilocks
# Goldilocks: dashboard show VPA recommendations cho tất cả deployments helm repo add fairwinds-stable https://charts.fairwinds.com/stable helm install goldilocks fairwinds-stable/goldilocks \ --namespace goldilocks \ --create-namespaceEnable namespace để Goldilocks monitor
kubectl label namespace production goldilocks.fairwinds.com/enabled=true
Port-forward Goldilocks dashboard
kubectl port-forward -n goldilocks svc/goldilocks-dashboard 8080:80
Dashboard hiện thị:
- Current requests/limits
- Recommended requests/limits
- Potential savings
5. Kubecost — Cost Visibility
# Cài Kubecost helm repo add kubecost https://kubecost.github.io/cost-analyzer/ helm install kubecost kubecost/cost-analyzer \ --namespace kubecost \ --create-namespace \ --set kubecostToken=xxx \ # free tier available --set prometheus.enabled=truePort-forward Kubecost UI
kubectl port-forward -n kubecost svc/kubecost-cost-analyzer 9090 & echo "Kubecost: http://localhost:9090"
Kubecost phân tích:
- Cost per namespace, deployment, pod
- Efficiency score (requests vs actual usage)
- Idle resource cost
- Recommendations
# Kubecost API: lấy cost data programmatically
curl "http://localhost:9090/model/allocation?window=7d&aggregate=namespace" | jq
# Output:
# {
# "production": {
# "cpuCost": 45.20,
# "memoryCost": 12.80,
# "pvCost": 5.60,
# "networkCost": 2.10,
# "totalCost": 65.70
# }
# }
6. Giảm Load Balancer Costs
# Thay nhiều LoadBalancer Services bằng 1 Ingress Controller # Trước: mỗi service có 1 LB kubectl get services --all-namespaces | grep LoadBalancer # production service-a LoadBalancer $18/month # production service-b LoadBalancer $18/month # staging service-c LoadBalancer $18/monthSau: 1 Gateway/Ingress cho tất cả
Gateway API: 1 Gateway → nhiều HTTPRoutes
Ingress: 1 nginx-ingress-controller → nhiều Ingresses
Internal services: dùng ClusterIP (không có LB)
Chỉ dùng LoadBalancer cho edge services cần external access
7. PersistentVolume Cleanup
# Tìm PVs không được bind (Released hoặc Available) kubectl get pv | grep -E "Released|Available"Tìm PVCs không được dùng (không có pod nào dùng)
kubectl get pvc -A | grep -v Running
Script: xóa PVCs không dùng trong namespaces đã xóa
kubectl get pv | grep Released | awk '{print $1}' | while read pv; do kubectl delete pv $pv done
Dùng reclaimPolicy: Delete (default cho EBS/GCE PD)
Khi PVC xóa → PV tự động xóa → không tốn tiền
reclaimPolicy: Retain → PV còn lại (cần manual delete)
8. Optimize Cross-AZ Traffic
# Topology Aware Routing: ưu tiên route traffic trong cùng AZ
apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
service.kubernetes.io/topology-mode: "Auto" # K8s 1.27+
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: my-app
# Topology Spread: đảm bảo replicas phân bổ đều trên AZ # Kết hợp với Topology Aware Routing: # → Requests được serve bởi pod cùng AZ với client # → Giảm cross-AZ data transfer costsVerify topology-aware routing
kubectl describe endpoints my-service
Hints được thêm vào EndpointSlice
kubectl get endpointslice -l kubernetes.io/service-name=my-service -o yaml | grep hints
9. Cost Optimization Summary
Strategy Savings Potential Complexity
──────────────────────────────────────────────────────
Spot instances 50-80% Medium
Right-sizing (VPA) 20-40% Low
Node consolidation 15-30% Low (Karpenter)
Reduce LoadBalancers $18/LB/month Low
Delete idle PVs Varies Low
Cross-AZ optimization 5-15% Medium
Reserved instances 30-60% Low (commit upfront)
ARM64/Graviton nodes 20-30% vs x86 Medium
Tóm tắt
- Spot instances: 50-80% savings cho fault-tolerant workloads
- Karpenter consolidation: tự động dồn pods, xóa nodes idle
- Goldilocks + VPA: right-size resources dựa trên actual usage
- Kubecost: visibility vào cost per team/namespace/deployment
- 1 Gateway thay nhiều LoadBalancers: tiết kiệm đáng kể
- Topology Aware Routing: giảm cross-AZ traffic costs