ค่าใช้จ่ายของ Cloud Infrastructure มักสูงเกินจำเป็นเพราะการตั้ง resource เกินกว่าที่ใช้งานจริง (over-provisioning) หรือปล่อยให้ server/disk/bandwidth ที่ไม่ได้ใช้ทำงานเปล่า ๆ การทำ Cost Optimization ด้วยการ Monitor Resource Usage อย่างเป็นระบบช่วยให้ทีมสามารถปรับขนาด VPS ให้เหมาะกับ workload จริง ลดค่าใช้จ่ายได้ 20-50% โดยไม่กระทบ performance
Workshop นี้จะสอนการตั้ง monitoring stack ที่เน้น cost optimization บน Cloud VPS ตั้งแต่การเก็บ metric การใช้ CPU/RAM/Disk/Network, การคำนวณ right-sizing, การหา idle resources, จนถึงการสร้าง dashboard ที่ตอบโจทย์ทีม finance และ DevOps
ทำไม Cost Optimization ถึงสำคัญ
ในหลายองค์กร ค่าใช้จ่าย Cloud เป็นค่าใช้จ่ายอันดับต้น ๆ ของฝ่าย IT การขาดข้อมูลเรื่อง resource usage ทำให้ทีมเลือกแผน VPS ใหญ่เกินจำเป็น “เผื่อไว้” โดยไม่รู้ว่าจริง ๆ ใช้แค่ 20% ของที่ซื้อมา เมื่อมีระบบ monitor ที่ดีจะเห็นได้ทันทีว่าเครื่องใด over-provisioned และสามารถย่อแผนลง (downsize) ได้โดยไม่เสี่ยง
4 Dimension ของ Resource Cost
- CPU: ค่าใช้จ่ายหลัก — ควร utilization เฉลี่ย 40-70% (ต่ำกว่า 20% = over-provisioned, สูงกว่า 85% = เสี่ยง)
- Memory (RAM): ถ้าใช้ประจำต่ำกว่า 50% แสดงว่าใหญ่เกินไป
- Disk: SSD/NVMe ค่าใช้จ่ายสูง — ต้องรู้ว่าเต็มจริงหรือแค่จอง
- Network (Bandwidth/Egress): มักเป็น hidden cost — traffic ออกต่างภูมิภาคแพงกว่าใน region เดียวกัน
Step 1: ติดตั้ง node_exporter เก็บ Resource Metrics
เริ่มจากติดตั้ง Prometheus node_exporter บน VPS ทุกเครื่องเพื่อเก็บ metric พื้นฐาน:
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
tar xvf node_exporter-1.7.0.linux-amd64.tar.gz
sudo mv node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/
sudo tee /etc/systemd/system/node_exporter.service <<EOF
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=prometheus
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
Step 2: PromQL สำหรับตรวจ Right-Sizing
Query เหล่านี้ช่วยระบุเครื่องที่ over-provisioned (ซื้อใหญ่เกินไป) โดยดู P95 ย้อนหลัง 7 วัน:
# CPU usage P95 ต่อเครื่อง (7 วัน)
quantile_over_time(0.95,
(1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])))[7d:5m]
)
# Memory usage P95 ต่อเครื่อง (7 วัน)
quantile_over_time(0.95,
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)[7d:5m]
)
# เครื่องที่ CPU P95 ต่ำกว่า 25% = over-provisioned
(
quantile_over_time(0.95,
(1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])))[7d:5m]
)
) < 0.25
# Disk space ที่จองไว้แต่ใช้ไม่ถึง 40%
(node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes < 0.4
Step 3: หา Idle / Zombie Servers
เครื่องที่ยังเปิดอยู่แต่ไม่มี traffic เข้าเลย = “zombie” ต้องสอบถามทีมและปิดถ้าไม่จำเป็น query ต่อไปนี้หา VPS ที่ network activity ต่ำมากใน 24 ชั่วโมงที่ผ่านมา:
# Network traffic เฉลี่ย 24 ชม. (bytes/sec) ต่ำกว่า 10KB/s
avg_over_time(
rate(node_network_receive_bytes_total{device!~"lo|veth.*"}[5m])[24h:5m]
) < 10240
# Zero load (LoadAvg 1min เฉลี่ย < 0.05) นาน 6 ชม.
avg_over_time(node_load1[6h]) < 0.05
Step 4: สร้าง Grafana Dashboard สำหรับ Cost Review
Dashboard นี้ทีมควรนั่งดูอย่างน้อยเดือนละครั้ง เพื่อหา server ที่ควร downsize หรือปิด มี panel หลัก 5 ตัว:
- Top 10 Over-Provisioned: ตาราง CPU P95 < 25%
- Memory Waste: เครื่องที่ใช้ RAM < 50% ต่อเนื่อง
- Idle Detection: เครื่องที่ network และ load ต่ำมาก
- Disk Usage %: ดูว่าเครื่องใดยังใช้ disk ต่ำ < 40%
- Cost Projection: คำนวณการประหยัดถ้า downsize ทั้งหมด
Step 5: Alert สำหรับ Unused Resources
ตั้ง alert ให้ Prometheus เตือนเมื่อพบ resource ที่ไม่ถูกใช้เกิน 7 วันติดต่อกัน:
groups:
- name: cost-optimization
rules:
- alert: OverProvisionedCPU
expr: |
quantile_over_time(0.95,
(1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])))[7d:5m]
) < 0.20
for: 24h
labels:
severity: info
category: cost
annotations:
summary: "{{ $labels.instance }} CPU P95 < 20% ติดต่อกัน 7 วัน"
action: "พิจารณา downsize"
- alert: IdleServer
expr: |
avg_over_time(rate(node_network_receive_bytes_total[5m])[24h:5m]) < 10240
and avg_over_time(node_load1[6h]) < 0.05
for: 12h
labels:
severity: info
category: cost
annotations:
summary: "{{ $labels.instance }} ไม่มี activity เกิน 12 ชม."
- alert: UnusedDiskSpace
expr: |
(node_filesystem_size_bytes - node_filesystem_used_bytes) / node_filesystem_size_bytes > 0.65
for: 7d
labels:
severity: info
category: cost
annotations:
summary: "{{ $labels.instance }}:{{ $labels.mountpoint }} ใช้ disk ต่ำกว่า 35%"
Step 6: Right-Sizing Decision Framework
เมื่อมีข้อมูลครบแล้ว ให้ใช้ decision table นี้ในการพิจารณาว่าควร downsize หรือไม่:
| CPU P95 | RAM P95 | Network | คำแนะนำ |
|---|---|---|---|
| < 20% | < 50% | ต่ำ | Downsize 2 tier |
| 20-40% | < 60% | ปกติ | Downsize 1 tier |
| 40-70% | 50-75% | ปกติ | เหมาะสมแล้ว |
| > 70% | > 75% | สูง | Upsize หรือ scale out |
Step 7: Automation — Scheduled Right-Sizing Report
สร้าง script Python ที่ดึงข้อมูลจาก Prometheus API และสร้างรายงานอัตโนมัติส่งเข้า Slack ทุกวันจันทร์:
import requests
from datetime import datetime
PROM = "http://prometheus:9090"
def query(q):
r = requests.get(f"{PROM}/api/v1/query", params={"query": q})
return r.json()["data"]["result"]
over_cpu = query(
'quantile_over_time(0.95, '
'(1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])))[7d:5m]) < 0.25'
)
report = [f"Cost Review — {datetime.now():%Y-%m-%d}"]
report.append(f"\n* Over-provisioned CPU: {len(over_cpu)} เครื่อง")
for m in over_cpu[:10]:
cpu_pct = float(m["value"][1]) * 100
report.append(f" - {m['metric']['instance']} CPU P95 = {cpu_pct:.1f}%")
# ส่งเข้า Slack
requests.post(
"https://hooks.slack.com/services/XXX/YYY/ZZZ",
json={"text": "\n".join(report)}
)
Best Practices เพิ่มเติม
- Tag ทุก VPS: ใส่ label เช่น env=prod/staging, team=backend, project=X เพื่อหา cost center ได้ถูก
- Review monthly: จัด cost review ทุกเดือนก่อนขึ้นบิล
- Auto-shutdown non-prod: ปิด staging/dev ตอนกลางคืนและวันหยุดประหยัดได้ 40-60%
- Retention policy: เก็บ metric ย้อนหลัง 30-90 วันเพื่อดู trend ตามฤดู
- Budget Alert: ตั้ง alert เมื่อค่าใช้จ่ายเดือนแตะ 80% ของ budget
ข้อควรระวัง
ก่อน downsize ต้องดูข้อมูลย้อนหลังอย่างน้อย 7 วัน เพื่อคลุม workload pattern ทั้งสัปดาห์ บาง service มี burst ช่วงเช้า-เย็น หรือ load สูงในช่วง month-end การดูแค่ 24 ชั่วโมงอาจทำให้ย่อผิดขนาดและกระทบ production
สรุป
Cost Optimization ผ่าน Resource Monitoring ไม่ใช่กิจกรรมครั้งเดียว แต่เป็นกระบวนการต่อเนื่องที่ต้องใช้ข้อมูลในการตัดสินใจ การมี Prometheus + Grafana dashboard ที่ตอบโจทย์ cost และ automation ที่ส่งรายงานสม่ำเสมอจะทำให้ทีมสามารถปรับขนาด resource ได้อย่างมีประสิทธิภาพ ลดค่าใช้จ่ายโดยไม่กระทบ uptime
สิ่งสำคัญคือการสร้าง culture ที่ทีมทุกคน (dev, ops, finance) เห็นข้อมูล cost เดียวกัน และมี review cadence ที่แน่นอน เพื่อไม่ให้ค่าใช้จ่าย cloud บานปลายโดยไม่รู้ตัว

