ค่าผ่านทางของ AKS — 91 pod ที่ไม่ใช่ของเรา จอง 6 cores ใช้จริง 0.6
ไล่ทีละตัวว่า Azure วางอะไรไว้ใน cluster เราบ้าง จองเท่าไหร่ ใช้จริงเท่าไหร่ ปิดได้ไหม และปิดที่ไหน — พร้อม 3 เรื่องที่ vendor ไม่เคยบอก และคำถามที่ควรถามกลับ
อัปเดต: 2026-08-23
ที่มา: เราไม่เคยได้รับคำอธิบายจาก vendor ว่าของพวกนี้คืออะไร เปิดไว้ทำไม ปิดได้ไหม — เลยไม่กล้าแตะ แต่มันกิน resource เยอะจนกระทบการวางแผนจำนวนเครื่อง เอกสารนี้ไล่ดูทีละตัวจากของจริง
วิธีเก็บข้อมูล:
kubectl get pods -A -o json+kubectl top+az aks showบนaks-SupperApp-dev· 23/08/2026
ตัวเลขเดียวที่ต้องจำ
Azure จองไว้ 6.0 cores แต่ใช้จริง 0.6–1.2 cores
จองเกินการใช้จริงราว 5–10 เท่า แล้วแต่จังหวะที่วัด
และเพราะ cluster-autoscaler ตัดสินใจจำนวนเครื่องจาก “ที่ที่จอง” ไม่ใช่ “ที่ที่ใช้” ตัวเลข 6.0 cores นี้จึงเป็นตัวกำหนดว่าเราต้องจ่ายค่าเครื่องกี่เครื่อง
⚠️ ตัวเลขการใช้จริงเป็น snapshot และแกว่งแรง — วัด 2 รอบห่างกัน 1 นาทีได้ 629m แล้ว 1,176m (
ama-logsแกว่ง 434m→173m) · ทิศทาง “จองเกินหลายเท่า” แข็ง แต่อย่าอ้างตัวเลขเดียวเป็น fact
1. cluster เราประกอบด้วยอะไรบ้าง
| ชั้น | pod | CPU ที่จอง | RAM ที่จอง | สัดส่วน CPU |
|---|---|---|---|---|
| พื้นฐาน Azure / Kubernetes | 91 | 6,007m | 13.2 GiB | 43% |
| เครื่องมือที่เราเลือกติดตั้งเอง | 22 | 4,800m | 8.7 GiB | 35% |
| แอปของเราจริง (dev + uat) | 44 | 2,900m | 6.6 GiB | 21% |
| รวม | 157 | 13,707m | 28.5 GiB |
🔑 ของ Azure กินที่มากกว่าแอปทั้ง dev และ uat รวมกัน 2 เท่า และคิดเป็น 31% ของกำลังทั้ง cluster (19,300m บน 5 เครื่อง)
2. ไล่ทีละตัว — 91 pod นั้นคืออะไร
เรียงจากที่จองมากไปน้อย · DS = ต้องมี 1 ชุดต่อเครื่อง (โตตามจำนวนเครื่อง) · คงที่ = มีจำนวนตายตัว
| Workload | ชนิด | pod | CPU จอง | CPU ใช้ | RAM จอง | RAM ใช้ | คืออะไร |
|---|---|---|---|---|---|---|---|
ama-logs | DS | 5 | 850m | 185m | 2,900Mi | 1,338Mi | เก็บ log ส่ง Log Analytics |
kube-proxy | DS | 5 | 500m | 11m | 0 | 488Mi | แกน K8s |
retina-agent | DS | 5 | 500m | 5m | 1,000Mi | 250Mi | network observability (basic mode) — ดู §3.1 |
microsoft-defender-collector-ds | DS | 5 | 400m | 41m | 800Mi | 352Mi | Defender for Containers |
ama-metrics-node | DS | 5 | 350m | 104m | 1,000Mi | 1,459Mi | Managed Prometheus |
ama-metrics | คงที่ | 2 | 340m | 74m | 1,100Mi | 1,079Mi | Managed Prometheus |
metrics-server | คงที่ | 2 | 316m | 14m | 308Mi | 147Mi | แกน K8s (HPA ใช้) |
azure-ip-masq-agent | DS | 5 | 250m | 5m | 180Mi | 25Mi | แกนเครือข่าย |
azure-npm | DS | 5 | 250m | 5m | 1,500Mi | 372Mi | บังคับใช้ NetworkPolicy |
cloud-node-manager | DS | 5 | 250m | 5m | 250Mi | 417Mi | แกน K8s |
gatekeeper-controller | คงที่ | 2 | 200m | 29m | 512Mi | 197Mi | Azure Policy |
azure-cns | DS | 5 | 200m | 10m | 1,250Mi | 113Mi | แกนเครือข่าย (CNI) |
azure-wi-webhook | คงที่ | 2 | 200m | 6m | 40Mi | 36Mi | Workload Identity (เราใช้กับ KeyVault) |
coredns | คงที่ | 2 | 200m | 28m | 140Mi | 127Mi | DNS ของ cluster |
csi-azurefile-node | DS | 5 | 200m | 17m | 400Mi | 252Mi | 🔴 Azure File driver — ไม่มี PVC ไหนใช้เลย |
ama-logs-rs | คงที่ | 1 | 170m | 6m | 280Mi | 225Mi | Log Analytics |
aks-secrets-store-csi-driver | DS | 5 | 165m | 17m | 540Mi | 226Mi | ดึง secret จาก KeyVault (เราใช้) |
csi-azuredisk-node | DS | 5 | 150m | 5m | 300Mi | 129Mi | Azure Disk (เราใช้ 3 PVC) |
microsoft-defender-publisher-ds | DS | 5 | 150m | 10m | 160Mi | 195Mi | Defender |
gatekeeper-audit | คงที่ | 1 | 100m | 2m | 256Mi | 91Mi | Azure Policy |
aks-secrets-store-provider-azure | DS | 5 | 80m | 9m | 250Mi | 58Mi | KeyVault CSI |
konnectivity-agent | คงที่ | 2 | 40m | 25m | 40Mi | 40Mi | อุโมงค์ไป control plane |
azure-policy | คงที่ | 1 | 30m | 1m | 50Mi | 22Mi | Azure Policy |
azure-policy-webhook | คงที่ | 1 | 30m | 1m | 50Mi | 12Mi | Azure Policy |
microsoft-defender-collector-misc | คงที่ | 1 | 30m | 1m | 32Mi | 8Mi | Defender |
coredns-autoscaler | คงที่ | 1 | 20m | 1m | 10Mi | 56Mi | ปรับจำนวน coredns |
konnectivity-agent-autoscaler | คงที่ | 1 | 20m | 1m | 10Mi | 56Mi | ปรับจำนวน konnectivity |
ama-metrics-operator-targets | คงที่ | 1 | 11m | 7m | 60Mi | 186Mi | Managed Prometheus |
ama-metrics-ksm | คงที่ | 1 | 5m | 4m | 50Mi | 33Mi | Managed Prometheus |
| รวม | 91 | 6,007m | 629m | 13,468Mi | 7,989Mi |
3. 🔴 3 เรื่องที่ไม่มีใครเคยอธิบายให้เราฟัง
ข้อ 3.2 กับ 3.3 เป็นข้อเท็จจริงที่ verify แล้ว · ข้อ 3.1 ถูกลดระดับจาก “ข้อกล่าวหา” เป็น “คำถาม” หลัง review เพราะคำอธิบายอยู่ใน config ของเราเอง
3.1 retina-agent รันอยู่ 5 ชุด ทั้งที่ฟีเจอร์ที่ “น่าจะเป็นเจ้าของ” ปิดอยู่
az aks show --query networkProfile.advancedNetworking
{ "enabled": false, "observability": { "enabled": false }, "security": { "enabled": false } }
แต่บน cluster: retina-agent DaemonSet 5 pod จอง 500m + 1,000Mi ใช้จริง 5m · label kubernetes.azure.com/managedby: aks = Azure วางเอง ลบด้วย kubectl แล้วมันกลับมา
⚠️ แก้ไข 23/08 หลัง review: ฉบับแรกเขียนข้อนี้ในรูป “Azure บอกว่าปิดแต่ยังรัน” ซึ่ง สรุปเกินหลักฐาน — คำอธิบายที่ไม่ใช่ความผิดใครอยู่ใน config ของเราเอง:
retina-config→enablePodLevel: false, plugin แค่[dropreason, packetforward, linuxutil]= retina basic mode ซึ่งสอดคล้องกับ ACNS ปิด ไม่ได้ขัดกันama-metrics-settings-configmap→networkobservabilityRetina = trueและเราเปิด Managed Prometheus อยู่ (azureMonitorProfile.metrics.enabled = true)→ retina basic น่าจะมาพร้อม Managed Prometheus ไม่ใช่ advancedNetworking · ยังไม่ได้พิสูจน์เหตุ-ผล (scrape setting อาจเป็น default เฉยๆ) แต่พอที่จะไม่ควรเอาไปยิงใส่ vendor ในรูปข้อกล่าวหา
คำถามที่ถูกต้องคือ “retina basic ผูกกับ Managed Prometheus ใช่ไหม ปิดเฉพาะ retina โดยยังคง Prometheus ไว้ได้ไหม” ไม่ใช่ “ทำไมของที่ปิดแล้วยังรัน”
3.2 csi-azurefile-node รัน 5 ชุด ทั้งที่ไม่มีใครใช้ Azure File เลย
PVC ทั้งหมดใน cluster มี 3 อัน ใช้ managed-csi (Azure Disk) ทั้งหมด — ไม่มีอันไหนเป็น Azure File
security/dependency-track-data managed-csi
security/sonarqube-data managed-csi
security/sonarqube-extensions managed-csi
จอง 200m + 400Mi เพื่อ driver ที่ไม่มีงานทำ · ตัวนี้ปิดได้จริงด้วย az aks update --disable-file-driver
3.3 Azure Policy 16 ข้อ อยู่ใน dryrun ทั้งหมด — รายงานอย่างเดียว ไม่บล็อกอะไร
azurepolicy-k8sazurev1serviceallowedports dryrun ละเมิด 76 จุด
azurepolicy-k8sazurev2containerallowedimages dryrun ละเมิด 71 จุด
azurepolicy-k8sazurev2blockautomounttoken dryrun ละเมิด 60 จุด
...รวม 16 constraint ทั้งหมด dryrun
จอง 360m + 868Mi (5 pod) เพื่อทำหน้าที่ “รายงานว่ามีอะไรผิดกฎ” ซึ่งมีการละเมิดค้างอยู่ 431 จุด และไม่มีใครแก้
คำถามคือ มีใครอ่านรายงานนี้ไหม ถ้าไม่มี = จ่ายค่า audit ที่ไม่มีใครดู · ถ้ามี = ต้องเอาไปเข้า security uplift ไม่ใช่ปิดทิ้ง
4. ⚠️ ปิดจากใน cluster ไม่ได้ — ต้องปิดที่ระดับ Azure
DaemonSet ส่วนใหญ่ติด label addonmanager.kubernetes.io/mode: Reconcile = แก้หรือลบด้วย kubectl แล้ว AKS จะสร้างกลับทันที
| ปิดได้ที่ไหน | รายการ |
|---|---|
az aks disable-addons / az aks update | Container Insights · Managed Prometheus · Defender · Azure Policy · Azure File driver |
| ปิดไม่ได้เลย | kube-proxy · azure-cns · azure-ip-masq-agent · cloud-node-manager · coredns · konnectivity · metrics-server · csi-azuredisk |
| ยังไม่ชัด — ต้องถาม | retina-agent (น่าจะผูกกับ Managed Prometheus ดู §3.1) |
🔑 สัญชาตญาณที่ว่า “ไม่กล้าปิด” ถูกต้องแล้ว — และความจริงคือส่วนใหญ่ปิดเองจากใน cluster ไม่ได้ด้วยซ้ำ ต้องไปปิดที่ตัว AKS resource ซึ่งกระทบทั้ง cluster (dev + uat พร้อมกัน)
5. ตารางตัดสินใจ — ถ้าจะปิด ปิดอะไรได้บ้าง
| # | Addon | pod | CPU คืน | RAM คืน | เสียอะไร | ใครตัดสิน |
|---|---|---|---|---|---|---|
| 1 | Azure File CSI driver | 5 | 200m | 400Mi | ไม่เสียอะไร — ไม่มี PVC ใช้ · ถ้าวันหลังต้องใช้ค่อยเปิดกลับ | 🟢 ทีมเรา |
| 2 | Azure Policy + gatekeeper | 5 | 360m | 868Mi | รายงาน compliance (ตอนนี้ dryrun ไม่บล็อกอะไร) | 🟡 security owner |
| 3 | Container Insights (ama-logs) | 6 | 1,020m | 3,180Mi | log ของ container ใน Azure Monitor · ลดบิล Log Analytics ~$208/เดือนด้วย | 🟡 ทีม + คนที่ใช้ log |
| 4 | Microsoft Defender | 11 | 580m | 992Mi | security monitoring · ลดบิล ~$66/เดือน | 🔴 security owner ไม่ใช่เรื่อง cost |
| 5 | Managed Prometheus (ama-metrics) | 9 | 706m | 2,210Mi | 🔴 Grafana จะไม่มีข้อมูล — UAT tracing/metrics พึ่งตัวนี้ | 🔴 อย่าปิด |
| 6 | Retina | 5 | 500m | 1,000Mi | ⚠️ อาจผูกกับ Managed Prometheus (ข้อ 5 ที่บอกว่าอย่าปิด) — ต้องถามก่อน | ❓ ถาม vendor |
| รวมถ้าปิดข้อ 1–4 + 6 | 32 | 2,660m | 6.3 GiB |
🔴 อ่านหัวข้อถัดไปก่อนใช้เลข 2,660m — เกือบทั้งหมดเป็น DaemonSet ซึ่ง autoscaler ไม่นับแล้ว · ผลจริงต่อจำนวน node = 260m
🔴 แก้ไขสำคัญ (23/08 หลัง review) — 2,660m ไม่ได้ แปลว่าลด node ได้
ฉบับแรกเขียนว่า “2,660m ที่จะได้คืน ≈ เท่ากับที่ต้องตัดพอดีเพื่อลง 4→3 เครื่อง” — ผิด และเป็นการเทียบข้ามหน่วย 2 ชั้น
| ชั้นที่ | ปัญหา | เหลือเท่าไหร่ |
|---|---|---|
| ตั้งต้น | ตัวเลขในตารางข้างบน = request ทั้ง cluster | 2,660m |
| 1 | 720m อยู่บน system node (sysnpz1 ตั้ง min=max=1) — คืนที่ตรงนั้นไม่ทำให้ node ลด | 1,940m |
| 2 | ใน 1,940m นั้น 1,680m เป็น DaemonSet และเราเปิด ignoreDaemonsetsUtilization: true ไปแล้ว = autoscaler ตัด DaemonSet ออกจากการคิด utilization ไปเรียบร้อย | 260m |
ผลจริงต่อตัวเลขที่ autoscaler ใช้ตัดสิน = 260m ไม่ใช่ 2,660m
เล็กกว่าที่เขียนไว้ 10 เท่า · คิดเป็น 1.7% ของ user pool
และ 260m นั้นมาจาก Azure Policy ล้วน (gatekeeper-controller + gatekeeper-audit + azure-policy + webhook — เป็น non-DaemonSet ทั้งหมด) ซึ่งเป็นชิ้นที่ต้องผ่าน security owner
ทำไมถึงพลาด — และบทเรียน
ignoreDaemonsetsUtilization: true เป็น flag ที่เราเปิดเองเมื่อ 22/08 เพื่อปลดล็อกการยุบ node (และมันได้ผล ยุบไป 1 เครื่องแล้ว)
ผลข้างเคียงที่ไม่ได้คิดถึงตอนเขียนเอกสารนี้: พอ autoscaler เลิกนับ DaemonSet การไปลด DaemonSet ก็ไม่มีผลต่อการตัดสินใจของมันอีกต่อไป — ซึ่ง addon ของ Azure ส่วนใหญ่ (ama-logs, retina, defender, csi-azurefile) เป็น DaemonSet ทั้งนั้น
เป็นความผิดพลาดชนิดเดียวกับที่เอกสาร 21/08 เคยทำ (เทียบ pod-level กับ node-level ข้ามหน่วย) — ก่อนบวกตัวเลขไปเทียบกับเกณฑ์ ต้องถามก่อนว่าเกณฑ์นั้นนับอะไรบ้าง
แล้วสรุปควรทำอะไร
| เป้าหมาย | lever ที่ถูกต้อง |
|---|---|
| ลดจำนวน node | 🔴 ไม่ใช่ addon — ตัวที่ให้ผลจริงคือ app-routing (non-DaemonSet บน user pool ~2,000–2,500m) ดู หน้า AKS scale-down §5.2 |
| ลดบิลเป็นเงินสด | Container Insights + Defender ยังเป็นเหตุผลที่ใช้ได้ — แต่เป็นคนละเรื่องกับจำนวน node (ดูหมายเหตุเรื่องตัวเลขเงินด้านล่าง) |
| ความสะอาด | Azure File CSI (ไม่มีใครใช้) และ Azure Policy dryrun (ไม่มีใครอ่าน) — ทำเพราะมันไม่ควรอยู่ ไม่ใช่เพราะจะได้ node คืน |
ประโยคเดิมที่ว่า “จัดการ addon ให้ผลมากกว่าการไล่ปรับ pod ของเราเองทั้งหมดรวมกัน” — กลับด้าน ในแง่จำนวน node ของเราเองให้ผลมากกว่าราว 10 เท่า
⚠️ ตัวเลขเงินในตารางข้างบนมาจากไหน
$208 และ $66 ไม่ใช่เลขที่วัดใหม่วันนี้ — มาจาก Cost Review 21/08 ซึ่งรายงาน Azure Monitor ทั้งบรรทัด = $211.41/เดือน และ Defender ทั้งบรรทัด = $74.82/เดือน
🔴 ทั้งสองบรรทัดเป็นของที่ใช้ร่วมกัน — omsagent และ defender ชี้ workspace เดียวกัน (log-SupperApp-dev) ซึ่งรับทั้ง dev และ uat → ปิดบน cluster นี้ไม่ได้ลบทั้งบรรทัด
และเอกสารต้นทางเองประเมินส่วนที่กู้คืนได้จริงไว้แค่ ”~$30–60 · ปานกลาง — ยังไม่ verify” พร้อมทิ้งคำถามค้างว่ายังไม่เคย query สัดส่วนจริง
ห้ามเอา $208 + $66 = $274 ไปผูกกับ commitment เรื่อง budget — ตัวเลขที่มีหลักฐานรองรับคือ $30–60 · ถ้าจะใช้เลขใหญ่ต้อง query Cost Management แยก meter
ContainerInsights/ContainerLogV2ของ cluster นี้ก่อน
6. คำถามที่ควรถาม vendor
retina-agentผูกอยู่กับอะไร —advancedNetworking.enabled = falseแต่ama-metrics-settings-configmapมีnetworkobservabilityRetina = trueและเราเปิด Managed Prometheus อยู่ · ปิดเฉพาะ retina โดยยังคง Managed Prometheus ไว้ได้ไหม และมันจอง 500m/1GiB เพื่อ basic mode คุ้มไหมcsi-azurefile-nodeจำเป็นต้องรันทุก node ไหม ในเมื่อไม่มี PVC ที่เป็น Azure File เลย ·--disable-file-driverมีผลข้างเคียงอะไรกับ cluster ที่รันอยู่- ทำไม addon ทุกตัวตั้ง resource request สูงกว่าการใช้จริง 9.5 เท่า · ค่าพวกนี้ปรับได้ไหม หรือ Azure บังคับ · ถ้าปรับไม่ได้ vendor แนะนำให้ sizing node ยังไง
azure-npmจอง 1.5 GiB เพื่อบังคับใช้ NetworkPolicy 8 อัน (ทั้งหมดเป็นของ ArgoCD) — จำเป็นไหมสำหรับ non-prod- มีเอกสารรายการ addon ที่ Azure เปิดให้เป็น default พร้อมบอกว่าตัวไหนปิดได้/ปิดไม่ได้ไหม — เราไม่เคยได้รับ
7. ที่ยังไม่ได้ยืนยัน
- ตัวเลข
kubectl topเป็น snapshot ณ 23/08 และแกว่งแรง — วัด 2 รอบห่างกัน 1 นาทีได้ platform total 629m แล้ว 1,176m · ยังไม่ได้ดู P95 ย้อนหลัง - 🔴 การจัดหมวดในข้อ 1 มีข้อโต้แย้ง —
app-routing-system3,000m ถูกนับเป็น “เครื่องมือที่เราเลือกติดตั้งเอง” (62% ของก้อนนั้น) แต่จริงๆ เป็น AKS managed addon (ingressProfile.webAppRouting.enabled = true, CRdefaultเป็นของ Azure) · ถ้านับเป็น platform สัดส่วนกลายเป็น 66 / 13 / 21 ซึ่งยิ่งหนุนข้อสรุปของเอกสารนี้ แต่เลข 43% เอาไปนำเสนอเป็น fact ไม่ได้ถ้าไม่บอกเกณฑ์แบ่ง - ยังไม่ได้พิสูจน์ว่า
retina-agentผูกกับ Managed Prometheus จริง (§3.1 เป็นความสอดคล้อง ไม่ใช่เหตุ-ผล) - ยังไม่ได้ทดสอบว่าปิด addon ตัวไหนแล้ว pod หายจริงภายในกี่นาที และมีผลข้างเคียงอะไร
- ยังไม่ได้ตรวจว่ามีใครอ่านรายงาน Azure Policy / log ใน Log Analytics จริงหรือไม่ — เป็นคำถามเชิงองค์กร ไม่ใช่เชิงเทคนิค
- ยังไม่ได้ปิดอะไรทั้งสิ้น เอกสารนี้เป็นการสำรวจเพื่อให้ตัดสินใจได้ ไม่ใช่บันทึกการลงมือ