ดับ AKS node ตามเวลา — simulate ว่าช่วยได้จริงเท่าไหร่
จำลองการเปิด-ปิด node ตามตาราง 6 หน้าต่างเวลา × 2 ขนาด cluster บนฐานบิลจริงเดือน ก.ค. — ได้เท่าไหร่ แลกกับ downtime กี่ชั่วโมง และทำไมต่อให้ดับ 24/7 ก็ยังไม่ถึงเป้า $1,062
อัปเดต: 2026-08-23
แยกออกมาจาก ทำไม AKS ไม่ยอมยุบ node — หน้านั้นว่าด้วย ทำยังไงให้ autoscaler ยอมยุบ · หน้านี้ว่าด้วย สั่งดับเครื่องตรงๆ ตามตารางเวลา ซึ่งเป็นคนละกลไกกันสิ้นเชิง
💵 ตัวเลขทั้งหน้าเป็น การจำลองจากบิลจริงเดือน ก.ค. + list price · ยังไม่เคยวัดผลจริงหลังเปลี่ยน
สรุปสั้น
- ได้จริงมากสุดที่สมเหตุสมผล ≈ $408/เดือน (ลด node เหลือ 3 + ดับ 22:00–07:00 ทุกวัน + เสาร์-อาทิตย์เต็ม)
- แต่ต่อให้ดับทิ้ง 24/7 ก็ยังเกิน budget อยู่ ~$349/เดือน — เพราะค่า VM เป็นแค่ 30% ของบิล Dev&SIT ที่เหลือ
- ราคาที่จ่ายคือ dev/uat ใช้ไม่ได้ 273–403 ชั่วโมง/เดือน และ start/stop 26–30 รอบ/เดือน
- ข้อดีที่ lever อื่นไม่มี: ข้ามด่านทั้ง 3 ที่บล็อกแผนปิด pod ได้หมด (
skipNodesWithSystemPods/ ArgoCDselfHeal/ HPA 21 ตัว) เพราะไม่ได้ไปแตะreplicasเลย
1. ฐานที่ใช้จำลอง
จากบิลจริง ก.ค. (cost review §2.1):
| รายการ | ก.ค. จริง |
|---|---|
| Dev&SIT ทั้ง subscription | $2,331.50 |
| ในนั้นเป็นบรรทัด Virtual Machines (6 × D4s_v4) | $920.85 |
| → ราคาต่อ node | $153.48/เดือน ($0.2102/ชม.) |
ตอนนี้เหลือ 4 เครื่อง (user 3 + system 1) → บรรทัด VM ควรอยู่ที่ ~$614/เดือน และ Dev&SIT ทั้งก้อน ~$2,025 (ประมาณการ ยังไม่เห็นบิล)
เป้าที่ต้องไปให้ถึง: $1,062.02 → ยังห่าง ~$963/เดือน
สิ่งที่การดับ node ไปไม่ได้แตะเลย
| รายการ ก.ค. | USD | ดับ node แล้วยังจ่ายไหม |
|---|---|---|
| Virtual Network (private endpoint) | 249.24 | จ่ายเท่าเดิม |
| Azure Monitor / Log Analytics | 211.41 | จ่ายเท่าเดิม (ลดลงบ้างเพราะ log น้อยลง แต่ไม่หาย) |
| Azure DevOps | 170.00 | จ่ายเท่าเดิม — ไม่ใช่ค่า infra ด้วยซ้ำ |
| Azure Grafana | 162.43 | จ่ายเท่าเดิม |
| PostgreSQL | 159.17 | จ่ายเท่าเดิม |
| Storage (~98% เป็น AKS disk) | 105.84 | ยังไม่รู้ — ขึ้นกับว่า stop เป็นการพัก VM หรือปลด node (ดู §5) |
| AKS control plane (tier Standard) | 74.29 | อ้างว่าไม่คิดตอน stopped — ยังไม่ verify |
| Defender / Key Vault / LB / ACR / Redis / Service Bus | ~277 | จ่ายเท่าเดิม |
🔑 บรรทัด VM = 30% ของบิล Dev&SIT ที่เหลืออยู่ · lever นี้จึงมีเพดานของมันเอง ไม่ว่าจะดับหนักแค่ไหน
2. Simulation — ได้เท่าไหร่ต่อหน้าต่างเวลา
สูตร: ประหยัด/เดือน = (จำนวน node × $153.48) × (ชั่วโมงที่ดับต่อสัปดาห์ ÷ 168)
| หน้าต่างเวลา | ชม./สัปดาห์ | สัดส่วน | ที่ 4 node ($614) | ที่ 3 node ($460) |
|---|---|---|---|---|
| 02:00–07:00 ทุกวัน | 35 | 20.8% | $128 | $96 |
| เสาร์-อาทิตย์เต็ม 2 วัน | 48 | 28.6% | $175 | $132 |
| 22:00–07:00 ทุกวัน | 63 | 37.5% | $230 | $173 |
| 22:00–07:00 + เสาร์-อาทิตย์ | 93 | 55.4% | $340 | $255 |
| 20:00–08:00 + เสาร์-อาทิตย์ | 108 | 64.3% | $395 | $296 |
| ดับตลอด 24/7 (เพดานทฤษฎี) | 168 | 100% | $614 | $460 |
🔑 รวมกับการลด node แล้ว ไม่ได้บวกกันตรงๆ
ถ้าทำ right-size ns security + --nginx None จนเหลือ 3 เครื่องก่อน (ประหยัด $153) แล้วค่อยดับตามเวลา ฐานที่เอาไปคูณจะเล็กลงด้วย:
| แผน | ประหยัดรวม/เดือน | Dev&SIT เหลือ | ห่างเป้า $1,062 |
|---|---|---|---|
| ไม่ทำอะไร | — | $2,025 | +$963 |
| ลด node อย่างเดียว (4→3) | $153 | $1,871 | +$809 |
| ดับ 22:00–07:00 อย่างเดียว (ยัง 4 node) | $230 | $1,794 | +$732 |
| ลด node + ดับ 22:00–07:00 | $326 | $1,698 | +$636 |
| ลด node + ดับ 22:00–07:00 + weekend | $408 | $1,616 | +$554 |
| ลด node + ดับ 20:00–08:00 + weekend | $449 | $1,575 | +$513 |
| ดับ 24/7 (สมมติสุดโต่ง ใช้ไม่ได้จริง) | $614 | $1,411 | +$349 |
ถ้าบวกกันตรงๆ แผนแถวที่ 5 ควรได้ $153 + $340 = $493 · ของจริงได้ $408 เพราะเครื่องที่ยุบไปแล้วมันดับซ้ำอีกไม่ได้
🔴 ผลสำคัญที่สุดของการจำลองนี้: ต่อให้ดับทิ้งตลอดเวลา บรรทัด VM หายไปทั้งก้อน ก็ยังเกินเป้าอยู่ $349 ส่วนที่เหลือต้องไปเอาจาก private endpoint ($249 — ต้องให้ Infra team), Log Analytics ($211), Azure DevOps ($170 ซึ่งไม่ใช่ค่า infra และควรย้ายออกจาก budget นี้), Grafana ($162), PostgreSQL ($159)
3. ราคาที่ต้องจ่าย — downtime
| หน้าต่างเวลา | dev/uat ใช้ไม่ได้ | รอบ start/stop ต่อเดือน | $ ที่ประหยัดต่อ 1 ชม.ที่ดับ |
|---|---|---|---|
| 02:00–07:00 ทุกวัน | 152 ชม./เดือน | ~30 | $0.84 |
| 22:00–07:00 ทุกวัน | 273 ชม./เดือน | ~30 | $0.84 |
| 22:00–07:00 + weekend | 403 ชม./เดือน | ~26 | $0.84 |
| 20:00–08:00 + weekend | 468 ชม./เดือน | ~26 | $0.84 |
🔑 ทุกหน้าต่างมีราคาเท่ากันหมดคือ $0.84 ต่อชั่วโมงที่ดับ (ที่ 4 เครื่อง) — เพราะเป็นการคิดตามเวลาตรงๆ
คำถามที่ต้องตอบก่อนเลือกหน้าต่างจึงไม่ใช่ “หน้าต่างไหนคุ้มสุด” แต่คือ “ชั่วโมงไหนที่ตายจริง” · ถ้ามีคนใช้แม้แค่คนเดียวในชั่วโมงนั้น มันแพงกว่า $0.84 แน่นอน
การ start/stop 26–30 รอบ/เดือน หมายถึง pod ทั้ง cluster restart เดือนละ ~30 ครั้ง — ผลข้างเคียงคือ ArgoCD sync พร้อมกันทุก app และ log noise ทุกเช้า
4. 3 แบบที่สั่งดับได้
| แบบ | คำสั่ง | ดับกี่เครื่อง | kubectl ระหว่างนั้น | ประหยัดที่ 22:00–07:00 |
|---|---|---|---|---|
| A. ดับทั้ง cluster ✅ แนะนำ | az aks stop / az aks start | 4 (user 3 + system 1) | ❌ ใช้ไม่ได้ | $230 |
| B. ดับเฉพาะ user pool | az aks nodepool stop --name appnpz1 | 3 | ✅ ยังใช้ได้ | $173 |
| C. scale เป็น 0 | ปิด autoscaler + nodepool scale --node-count 0 | 3 (ถูกลบ ไม่ใช่พัก) | ✅ ยังใช้ได้ | $173 |
- แบบ B จ่ายเพิ่ม $57/เดือน เพื่อแลกกับการที่
kubectlยังใช้ได้ — และ pod ที่ค้างจะPendingทำให้ autoscaler พยายามสร้าง node ใหม่มาชน ต้องปิด autoscaler ก่อน (ยังไม่ได้ทดสอบ) - แบบ C ไม่แนะนำ — ช้าที่สุด และต้องสลับ autoscaler เปิด-ปิดทุกวัน = โอกาสค่า config หลุดสูง
5. 🔴 ตัวกั้นที่ต้องเคลียร์ก่อน
| # | ตัวกั้น | รายละเอียด |
|---|---|---|
| 1 | CronJob sync-employee 01:00 | ตั้ง timeZone: Asia/Bangkok ไว้จริง = 01:00 เวลาไทย อยู่กลางหน้าต่างพอดี · และตั้ง startingDeadlineSeconds: 300 → พลาดแล้วข้ามเลย ไม่ยิงย้อนหลัง · แก้ได้ด้วยการย้ายเวลาไป 21:30 หรือ 07:30 = แก้บรรทัดเดียวใน IaC (ทั้ง dev และ uat) |
| 2 | CI/CD ที่ deploy กลางคืน | pipeline ที่ยิงเข้า dev/uat ตอน cluster ดับ = fail ทั้งชุด · ไล่ดูที่ ADO → Pipelines → Triggers / Scheduled |
| 3 | security scan รายคืน | ถ้าเปิด DAST nightly บน dev แล้วจะชนกัน |
| 4 | คนทำงานดึก / QA | ข้อนี้ไม่ใช่ “scale ลง” แต่ ดับสนิท เข้าไม่ได้เลย — เป็นการตัดสินใจของ Owner ไม่ใช่เรื่องเทคนิค |
ยังไม่รู้ ต้องทดลองก่อน
az aks stop บอกแค่ว่า “A cluster does not accrue charges while it is stopped” แต่ไม่ได้บอกว่าเป็นการพัก VM เดิม หรือปลด node แล้วสร้างใหม่ตอน start ซึ่งเปลี่ยนผล 3 อย่าง:
- บรรทัด Storage $105.84 — node ตั้ง
osDiskType: Managed(ไม่ใช่ ephemeral) ถ้าเป็นการพัก VM ดิสก์ยังคิดเงินต่อ ถ้าปลด node ทิ้งก็หายไปด้วย - เวลา start จริง ถ้าเป็นการสร้างใหม่จะนานกว่ามาก (node + pod ทั้ง cluster schedule ใหม่หมด)
- ข้อมูลบน node หาย — cluster นี้ตั้ง
skipNodesWithLocalStorage=falseไว้เอง แปลว่ามี pod ใช้ local storage อยู่ ต้องไล่ดูว่าตัวไหนทนemptyDirหายไม่ได้
6. วิธีทดลอง 1 รอบก่อนตัดสินใจ
# จับเวลาตอนดับ
az aks stop -g sua-azure-nonprd -n aks-SupperApp-dev
az aks show -g sua-azure-nonprd -n aks-SupperApp-dev --query powerState.code # ต้องได้ "Stopped"
# จับเวลาตอนเปิด — นี่คือตัวเลขที่ต้องรู้ก่อนผูก schedule
az aks start -g sua-azure-nonprd -n aks-SupperApp-dev
kubectl get pods -A --no-headers | awk '$4!="Running" && $4!="Completed"' # ต้องว่างหลังนิ่ง
สิ่งที่ต้องบันทึกจากรอบทดลอง:
- เวลาที่ใช้จริงตั้งแต่สั่ง
startจนทุก podRunning - node ที่ได้กลับมาเป็นเครื่องเดิมหรือเครื่องใหม่ (
kubectl get nodesเทียบชื่อ +AGE) - มี pod ไหนไม่กลับมาเอง / ArgoCD ค้าง
OutOfSyncเพิ่มไหม - หลังจากนั้น 2 วัน ดู Cost Management บรรทัด Storage ว่าเปลี่ยนไหม
ตัวสั่งตามเวลา (ยังไม่มี): Azure Automation runbook / Logic App / ADO pipeline แบบ schedule · identity ต้องมีสิทธิ์ Microsoft.ContainerService/managedClusters/stop/action และ .../start/action
7. ข้อสรุปสำหรับตัดสินใจ
| ถ้า Owner ตอบว่า | ควรทำ |
|---|---|
| ”กลางคืนกับเสาร์อาทิตย์ไม่มีใครแตะจริง” | ลด node ก่อน แล้วดับ 22:00–07:00 + weekend → ~$408/เดือน |
| ”กลางคืนไม่มีใคร แต่เสาร์อาทิตย์บางทีมีคนเข้า” | ลด node + ดับเฉพาะกลางคืน → ~$326/เดือน |
| ”ต้องเข้าได้ตลอด แต่ดึกจริงๆ ไม่มี” | ดับแคบ 02:00–07:00 → ~$96–128/เดือน |
| ”ห้ามดับเด็ดขาด” | เหลือแค่ แผนปิด pod กลางคืน ที่ได้ ~$58 และต้องทำงานย่อย 5 อย่าง |
ไม่ว่าจะเลือกทางไหน ยังต้องหาอีก $500–950/เดือนจากที่อื่นถึงจะเข้า budget — lever นี้ไม่ใช่คำตอบสุดท้าย แต่เป็นก้อนเดียวที่ใหญ่ที่สุดที่ทีมเราสั่งเองได้