Tại Sao Chi Phí Kubernetes Lại Tăng Lúc Nào Không Hay
Bạn deploy vài microservice, thêm một staging cluster, rồi sáu tháng sau hóa đơn cloud tự nhiên tăng gấp đôi mà chẳng ai hay. Không ai thay đổi kiến trúc một cách có chủ đích. Resource request được đặt quá thận trọng, các namespace nhàn rỗi cứ tích lại mà không ai chú ý, và cả đội không có cái nhìn rõ ràng về workload nào đang thực sự ngốn tiền.
Khả năng quan sát chi phí là một trong những kỹ năng phân biệt một DevOps engineer chủ động với người luôn bị bất ngờ trước hóa đơn cloud hàng tháng. Bạn có thể không có alert nào đỏ và uptime 100% trên mọi panel Grafana — mà vẫn hoàn toàn mù tịt về việc hóa đơn AWS 8.000 đô/tháng đang chạy vào đâu.
OpenCost lấp đầy khoảng trống đó. Đây là dự án open-source thuộc CNCF sandbox, cung cấp dữ liệu chi phí theo từng namespace và workload mà không bị vendor lock-in hay phải trả 500 đô/tháng cho một SaaS subscription.
So Sánh Các Hướng Tiếp Cận: Cách Các Đội Thường Xử Lý Giám Sát Chi Phí Kubernetes
Có ba hướng tiếp cận phổ biến, mỗi cái có ưu nhược điểm riêng:
1. Công Cụ Native của Cloud Provider
AWS Cost Explorer, GCP Billing Reports và Azure Cost Management đều cho bạn thấy tổng chi tiêu của cluster. Vấn đề là độ chi tiết — chúng báo cáo chi phí node EC2, nhưng không thể phân tách theo namespace, deployment hay label. Bạn thấy hóa đơn, nhưng không thấy chi tiết từng khoản.
2. Nền Tảng FinOps Thương Mại
Các công cụ như Kubecost (bản thương mại), CloudHealth hay Apptio Cloudability cung cấp báo cáo phân bổ chi phí rất sâu. Chúng hoạt động tốt. Nhưng cái giá phải trả là: Kubecost Pro bắt đầu từ khoảng 500 đô/tháng cho cluster cỡ vừa, còn CloudHealth thì lên đến hàng nghìn đô. Với các đội nhỏ đang cố tìm ra lãng phí mà chưa định lượng được, đó là một bài toán khó thuyết phục.
3. OpenCost (Open Source)
OpenCost được Kubecost open-source vào năm 2022 và hiến tặng cho CNCF. Nó chạy bên trong cluster của bạn, scrape các metric từ Prometheus, và áp dụng giá cloud thực tế vào mức tiêu thụ tài nguyên thực của bạn. API gọn gàng, UI nhẹ, chạy miễn phí. Dữ liệu không rời khỏi hạ tầng của bạn, và tích hợp native với Grafana.
Ưu và Nhược Điểm của OpenCost
Ưu Điểm
- Hoàn toàn miễn phí và open source — giấy phép Apache 2.0, không giới hạn usage hay phí theo số người dùng
- Phân bổ chi phí theo namespace và workload — chi phí được tách theo deployment, daemonset, statefulset, label hoặc annotation
- Hoạt động trên mọi cloud hoặc on-prem — hỗ trợ AWS, GCP, Azure và định giá tùy chỉnh cho bare metal
- Dự án CNCF sandbox — cộng đồng active, Helm chart được bảo trì tốt, tài liệu đầy đủ
- Dashboard Grafana có sẵn — dashboard dựng sẵn có thể tải về trên Grafana.com
- Native với Prometheus — nếu bạn đã chạy kube-prometheus-stack, tích hợp chỉ mất khoảng 10 phút
Nhược Điểm
- Không có cảnh báo anomaly tích hợp sẵn — bạn cần tự viết Prometheus alerting rules để phát hiện chi phí tăng đột biến
- Đối chiếu hóa đơn cloud cần cấu hình thêm — để khớp các khoản giảm giá và giá reserved instance thực tế cần truy cập cloud billing API
- UI đủ dùng nhưng còn tối giản — Kubecost UI thương mại giàu tính năng hơn đáng kể; OpenCost chỉ đáp ứng những nhu cầu cơ bản
- Nên dùng persistent storage để lưu lịch sử — nếu không, lịch sử chi phí sẽ mất khi pod khởi động lại
Cấu Hình Được Khuyến Nghị
Với hầu hết các đội, stack bốn thành phần này đáp ứng được 90% nhu cầu thực tế:
- OpenCost — engine tính chi phí và UI
- kube-prometheus-stack — Prometheus + Grafana (nếu chưa triển khai)
- Dashboard Grafana cho OpenCost — import từ Grafana.com
- Persistent Volume cho Prometheus — để lịch sử chi phí không bị mất khi pod khởi động lại
Nếu bạn đã chạy Prometheus trong cluster, hãy bỏ qua Bước 1 và đi thẳng vào Bước 2.
Hướng Dẫn Triển Khai
Bước 1: Cài đặt kube-prometheus-stack (bỏ qua nếu đã cài)
OpenCost phụ thuộc vào Prometheus để lấy metrics. Helm chart của cộng đồng là cách nhanh nhất:
# Thêm Helm repo
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# Cài vào namespace monitoring
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set prometheus.prometheusSpec.retention=15d \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=20Gi
Tham số retention=15d giữ lại 15 ngày metrics — đủ để phân tích xu hướng chi phí theo tuần một cách có ý nghĩa. Điều chỉnh dung lượng storage tùy theo quy mô cluster; 20Gi là mức hợp lý cho cluster từ 10–30 node.
Bước 2: Cài đặt OpenCost
OpenCost có Helm chart riêng, triển khai cost engine kèm theo một UI nhẹ:
# Thêm Helm repo của OpenCost
helm repo add opencost https://opencost.github.io/opencost-helm-chart
helm repo update
# Tạo file values
cat > opencost-values.yaml << 'EOF'
opencost:
exporter:
cloudProviderApiKey: "" # Để trống để dùng giá on-demand không có giảm giá
ui:
enabled: true
prometheus:
internal:
enabled: false # Dùng prometheus bên ngoài đã cài ở trên
external:
enabled: true
url: "http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090"
EOF
# Cài đặt
helm install opencost opencost/opencost \
--namespace opencost \
--create-namespace \
-f opencost-values.yaml
Chú ý định dạng URL Prometheus — nó dùng DNS service của Kubernetes. Nếu tên service hoặc namespace Prometheus của bạn khác, hãy cập nhật URL trước khi cài đặt.
Bước 3: Kiểm Tra Deployment
# Kiểm tra các pod đang chạy
kubectl get pods -n opencost
# Kết quả mong đợi:
# NAME READY STATUS RESTARTS AGE
# opencost-xxxxxxxxx-xxxxx 2/2 Running 0 2m
# Kiểm tra log OpenCost để phát hiện lỗi kết nối Prometheus
kubectl logs -n opencost deployment/opencost -c opencost
Tìm dòng Prometheus connection successful trong log. Lỗi connection refused hầu như luôn có nghĩa là URL Prometheus trong file values cần được chỉnh lại.
Bước 4: Truy Cập Giao Diện OpenCost
# Port-forward UI về máy local của bạn
kubectl port-forward -n opencost service/opencost-ui 9090:9090
Mở http://localhost:9090. Sau vài phút, bạn sẽ thấy dữ liệu chi phí được phân tách theo namespace. OpenCost tự backfill dữ liệu lịch sử từ Prometheus, nên bạn sẽ có ngay ước tính chi phí kéo dài 15 ngày về trước — toàn bộ khoảng thời gian retention đã cấu hình.
Bước 5: Truy Vấn Chi Phí Qua OpenCost API
HTTP API là điểm mạnh thực sự của OpenCost khi cần tự động hóa. Bạn có thể viết script tạo báo cáo chi phí, đẩy dữ liệu vào Slack, hoặc tích hợp vào dashboard nội bộ:
# Port-forward API
kubectl port-forward -n opencost service/opencost 9003:9003
# Truy vấn chi phí 7 ngày gần nhất, tổng hợp theo namespace
curl -s "http://localhost:9003/allocation/compute?window=7d&aggregate=namespace" | \
python3 -m json.tool | head -80
# Truy vấn chi phí tổng hợp theo label deployment
curl -s "http://localhost:9003/allocation/compute?window=24h&aggregate=label:app" | \
python3 -m json.tool
Tham số aggregate là chìa khóa để phân tích chi tiết. Nhóm theo namespace, controller, pod, node, hoặc bất kỳ label tùy chỉnh nào đội bạn đang dùng. Nhóm theo label là thứ giúp bạn gắn chi phí trực tiếp vào từng nhóm sản phẩm cụ thể.
Bước 6: Import Dashboard Grafana
OpenCost cung cấp các dashboard Grafana chính thức. Hãy port-forward Grafana trước:
# Port-forward Grafana
kubectl port-forward -n monitoring service/kube-prometheus-stack-grafana 3000:80
Mở http://localhost:3000 (thông tin đăng nhập mặc định: admin/prom-operator), vào Dashboards → Import, và nhập dashboard ID 15714. Chọn Prometheus instance của bạn làm data source khi được hỏi.
Bước 7: Cấu Hình Giá Cloud Provider (Tùy Chọn nhưng Nên Làm)
Mặc định, OpenCost dùng giá on-demand từ API của cloud provider. Với cluster trên AWS, bạn có thể lấy số liệu chính xác hơn bằng cách truyền vào cấu hình billing của mình:
cat > aws-config.json << 'EOF'
{
"provider": "AWS",
"description": "Cấu hình AWS Provider",
"AWS_ACCESS_KEY_ID": "access-key-của-bạn",
"AWS_SECRET_ACCESS_KEY": "secret-key-của-bạn",
"awsSpotDataBucket": "",
"awsSpotDataRegion": "ap-northeast-1",
"projectID": "123456789"
}
EOF
# Tạo secret từ file config
kubectl create secret generic opencost-aws-config \
--from-file=aws-config.json=aws-config.json \
-n opencost
Cập nhật opencost-values.yaml để tham chiếu secret này, sau đó chạy helm upgrade để áp dụng.
Nên Xem Gì Đầu Tiên
Ba con số đáng kiểm tra ngay khi dashboard vừa load xong:
- Chi phí idle theo namespace — một namespace request 4 CPU nhưng chỉ dùng 400m đang lãng phí 90% ngân sách compute; đây là những cơ hội right-sizing nhanh nhất
- Chi phí theo loại controller — DaemonSet chạy trên mọi node, nên một DaemonSet phình to với 500m CPU request trên cluster 20 node sẽ ngốn tới 10 CPU core trên toàn cluster; hãy kiểm tra kỹ chúng
- Xu hướng chi phí theo thời gian — mức tăng dần đều thường có nghĩa là resource request đang bị đẩy lên từng sprint, khi dev thêm buffer an toàn mà không bao giờ cắt bớt phần cũ
Một Số Kinh Nghiệm Từ Thực Tế
Một số vấn đề gần như xuất hiện ở mọi cluster production khi bạn có được khả năng quan sát chi phí thực sự.
Namespace staging hầu như luôn là thủ phạm lớn nhất. Developer copy config production rồi quên scale down resource request — tìm thấy một staging pod đang claim 2 CPU và 4Gi RAM trong khi thực tế chỉ dùng 200m CPU và 512Mi là chuyện xảy ra thường xuyên hơn bạn nghĩ. Hãy bắt đầu từ đó. Chỉnh lại resource request cho staging có thể cắt giảm 15–30% chi phí của namespace đó chỉ trong một buổi chiều.
Hãy cảnh báo theo tốc độ tăng chi phí, không phải theo giá trị tuyệt đối. Ngưỡng tuyệt đối sẽ lỗi thời khi sản phẩm bạn scale lên. Mức tăng 30% so với tuần trước ở bất kỳ namespace nào là đáng điều tra, bất kể baseline là bao nhiêu — tín hiệu đó vẫn có giá trị dù bạn đang tiêu 200 đô/tháng hay 20.000 đô/tháng cho cluster.
Tổng hợp theo label thay đổi hoàn toàn cách các cuộc thảo luận về chi phí diễn ra. Khi engineering manager có thể thấy chi phí hạ tầng của đội mình trên cùng một Grafana instance với SLO và error rate, các buổi họp ngân sách sẽ chuyển từ ước tính sang số liệu thực. Sự thay đổi về nhận thức đó thường quan trọng hơn bất kỳ phát hiện tối ưu đơn lẻ nào.

