- 1. เข้าใจ Docker, Kubernetes และ EKS
- 2. สถาปัตยกรรมหลักของ Amazon EKS
- 3. เลือกวิธีรัน Workload
- 4. คำศัพท์ Kubernetes ที่ควรรู้
- 5. ค่าใช้จ่ายที่ควรรู้ก่อนเริ่ม
- 6. เป้าหมายของ Workshop
- 7. เตรียมเครื่องมือและบัญชี
- 8. เลือก Kubernetes version จากข้อมูลจริง
- 9. สร้าง Cluster ด้วย eksctl
- 10. Deploy เว็บตัวอย่าง
- 11. เปิดเว็บและทดลอง Self-healing
- 12. Scale และ Rolling restart
- 13. เพิ่ม HPA ด้วย Metrics Server
- 14. สิ่งที่ควรเพิ่มเมื่อนำไปใช้จริง
- 15. ปัญหาที่พบบ่อย
- 16. ลบทรัพยากรหลังจบ Workshop
- 17. แนวทางเรียนต่อ
- เอกสารอ้างอิง
บทความสำหรับผู้เริ่มต้นที่มีพื้นฐาน Docker และต้องการเรียนรู้การนำแอปพลิเคชันขึ้น Kubernetes บน AWS ตรวจสอบเอกสารอ้างอิงวันที่ 1 ตุลาคม 2569 (2026) คำสั่ง Workshop ใช้ Bash บน macOS, Linux หรือ WSL

Amazon Elastic Kubernetes Service หรือ Amazon EKS คือบริการ Kubernetes แบบ Managed ของ AWS ช่วยให้ทีมพัฒนาใช้ Kubernetes ได้โดย AWS ดูแล Control Plane ให้ ทีมจึงสามารถใช้ kubectl, Kubernetes manifests และเครื่องมือในระบบนิเวศ Kubernetes เพื่อ Deploy แอปพลิเคชันบน AWS ได้ [1]
ตัวอย่างงานที่นำมารันได้ ได้แก่ Web API, Microservices, Background Workers และงานประมวลผลที่บรรจุเป็น Container การเลือก EKS มีประโยชน์เมื่อทีมต้องการความสามารถของ Kubernetes และพร้อมดูแลการตั้งค่าแอปพลิเคชัน เครือข่าย สิทธิ์ และต้นทุนของระบบ
#1. เข้าใจ Docker, Kubernetes และ EKS
| เทคโนโลยี | หน้าที่ | ตัวอย่าง |
|---|---|---|
| Docker / Container tooling | สร้างและทดสอบ Container image | บรรจุ Web API พร้อม dependencies |
| Container registry | เก็บและแจกจ่าย Image | Amazon ECR หรือ registry อื่น |
| Kubernetes | จัดตารางรัน Container และรักษาสถานะที่ต้องการ | กำหนดให้มี Pod ของ API 3 ชุด |
| Amazon EKS | ให้บริการ Kubernetes Control Plane บน AWS | สร้าง Cluster แล้ว Deploy ด้วย kubectl |
เมื่อประกาศว่า Deployment ต้องมี 3 replicas Kubernetes จะพยายามรักษาจำนวน Pod ตามนั้น หาก Pod หนึ่งหายไป ตัวควบคุมจะสร้าง Pod ทดแทน แต่ความสำเร็จยังขึ้นกับทรัพยากรและการตั้งค่าของระบบ [13]
Container image ไม่ใช่ Cluster: Image คือสิ่งที่นำไปใช้งาน ส่วน Cluster คือระบบที่จัดการการรัน Image หลายชุดบนทรัพยากรประมวลผล
#2. สถาปัตยกรรมหลักของ Amazon EKS
EKS แบ่งแนวคิดออกเป็นสองส่วนสำคัญ
#Control Plane
ทำหน้าที่รับคำสั่ง Kubernetes API จัดตารางงาน และรักษาสถานะของ Cluster AWS ดูแล Control Plane ของ EKS ให้ ส่วนนี้ไม่ใช่เว็บเซิร์ฟเวอร์ที่รับ HTTP requests จากผู้ใช้ของแอปโดยตรง [1]
#Data Plane หรือ Compute
เป็นทรัพยากรที่รัน Pods จริง สามารถเลือกใช้ EC2 ผ่าน Managed Node Groups, AWS Fargate หรือการจัดการโครงสร้างพื้นฐานด้วย EKS Auto Mode ตามความต้องการของงาน [3][4][5]
ตัวอย่างสถาปัตยกรรมเมื่อเผยแพร่เว็บแอปผ่าน Load Balancer:
flowchart TD
Dev["ผู้ดูแล: kubectl / CI/CD"] --> CP["EKS Control Plane"]
CP -. "ควบคุมสถานะและจัดตาราง" .-> Nodes
User["ผู้ใช้เว็บ"] --> LB["AWS Load Balancer"]
LB --> Svc["Kubernetes Service"]
subgraph Nodes["Compute ใน VPC"]
Svc --> P1["Pod A"]
Svc --> P2["Pod B"]
end
Registry["Container Registry"] -. "ดึง Image" .-> P1
Registry -. "ดึง Image" .-> P2
แผนภาพแสดงบทบาทเชิงตรรกะ เส้นทางเครือข่ายจริงขึ้นกับชนิด Load Balancer และ Target Type บางแบบส่งตรงไป Pod IP ได้ ตัวอย่าง Workshop ในบทความนี้ใช้ port-forward จึงไม่ได้สร้าง Load Balancer
#3. เลือกวิธีรัน Workload
ทั้งสามทางเลือกยังใช้ Kubernetes API แต่มีขอบเขตการดูแลโครงสร้างพื้นฐานต่างกัน
| ทางเลือก | ลักษณะการทำงาน | ทีมต้องกำหนดหรือดูแล | เหมาะกับ |
|---|---|---|---|
| Managed Node Groups | AWS ช่วยจัดการวงจรชีวิตของกลุ่ม EC2 nodes | ชนิด Instance, ขนาดกลุ่ม, แผนอัปเดต และระบบเพิ่ม/ลด Node ตาม Workload | ทีมที่ต้องการควบคุม Compute และเรียนรู้โครงสร้าง Node |
| AWS Fargate | รัน Pods โดยไม่ต้องจัดเตรียมกลุ่ม EC2 เอง | Fargate profiles, ทรัพยากรของ Pod และข้อจำกัดของ Workload | งานที่เข้ากับโมเดล Compute ต่อ Pod |
| EKS Auto Mode | AWS ช่วยจัดการ Compute, Scaling และองค์ประกอบเครือข่าย/Storage ที่รองรับ | Workload requirements, NodePools/NodeClasses เมื่อต้องปรับแต่ง และนโยบายแอป | ทีมที่ต้องการลดงานดูแล Data Plane |
Managed Node Groups ช่วยให้ปรับใช้การอัปเดต Node ได้สะดวก แต่ทีมยังต้องวางแผนและสั่งอัปเดตตามความเหมาะสม ส่วนการกำหนด minSize และ maxSize อย่างเดียวไม่ได้ทำให้ Node เพิ่มตาม Pods โดยอัตโนมัติ ต้องมีระบบอย่าง Cluster Autoscaler หรือเลือกแนวทางอื่นที่จัดการ Capacity ให้ [3][14]
Fargate มีข้อจำกัด เช่น ไม่รองรับ DaemonSet และ Privileged containers และ Pods ต้องตรงกับ Fargate profile จึงจะถูกจัดให้รันบน Fargate ตรวจสอบข้อจำกัดล่าสุดก่อนเลือกใช้ [4]
Auto Mode รันบน EC2 และมีค่าบริการจัดการเพิ่มจากราคา EC2 ไม่ใช่ Compute ที่ใช้งานฟรีหรือบริการที่ทำให้ทีมไม่ต้องดูแลแอปพลิเคชัน [5][6]
#4. คำศัพท์ Kubernetes ที่ควรรู้
| คำศัพท์ | ความหมายสำหรับ Workshop |
|---|---|
| Cluster | ระบบ Kubernetes ที่ประกอบด้วย Control Plane และ Compute |
| Node | เครื่องที่รัน Pods ในตัวอย่างนี้เป็น EC2 |
| Pod | หน่วยที่ Kubernetes จัดตารางให้รัน ประกอบด้วย Container อย่างน้อยหนึ่งตัว |
| Deployment | ประกาศจำนวน replicas และวิธีอัปเดต Pods |
| Service | ให้จุดเข้าถึงที่คงที่สำหรับกลุ่ม Pods ที่ตรงกับ selector |
| Namespace | แบ่งพื้นที่ของ Kubernetes resources |
| ConfigMap | เก็บ Configuration ทั่วไป |
| Secret | Resource สำหรับข้อมูลลับ ต้องออกแบบสิทธิ์และการจัดเก็บอย่างเหมาะสม |
| Ingress | ประกาศเส้นทาง HTTP/HTTPS ต้องมี Controller ที่รองรับ |
| HPA | Horizontal Pod Autoscaler เพิ่ม/ลดจำนวน Pods จาก Metrics |
Service แบบ ClusterIP ใช้ภายใน Cluster และการสร้าง Ingress resource เพียงอย่างเดียวไม่ได้รับประกันว่าจะมี Load Balancer หรือ Public URL ต้องมีองค์ประกอบที่ประมวลผล Resource นั้น [12]
#5. ค่าใช้จ่ายที่ควรรู้ก่อนเริ่ม
ราคาหน้า Amazon EKS Pricing ณ วันที่ตรวจสอบระบุค่า Cluster พื้นฐานตามช่วงการรองรับ Kubernetes ดังนี้ [6]
| สถานะเวอร์ชัน Kubernetes | ค่า Cluster ต่อชั่วโมง | ตัวอย่างเมื่อเปิด 730 ชั่วโมง |
|---|---|---|
| Standard support | 0.10 USD | 73 USD |
| Extended support | 0.60 USD | 438 USD |
ตัวเลขต่อเดือนเป็นการคำนวณ ราคา × 730 เพื่ออธิบายวิธีประมาณค่าใช้จ่าย ไม่ใช่ใบเสนอราคา และยังไม่รวม Compute, Storage, ภาษี หรือบริการอื่น
ต้นทุนรวมอาจประกอบด้วย:
- EC2 หรือ Fargate ที่รัน Workload
- EBS volumes, Load Balancer และ Public IPv4
- NAT Gateway และ Data Transfer
- การเก็บ Logs/Metrics และ Container images
- ค่าบริการ Auto Mode หรือความสามารถเพิ่มเติมที่เปิดใช้งาน
แม้ลบ Pods หรือปรับจำนวน Nodes ลง ค่า Cluster ยังคิดตามชั่วโมงตราบใดที่ Cluster ยังอยู่ Workshop นี้ใช้ Node ใน Public Subnet และปิด NAT Gateway เพื่อลดรายการค่าใช้จ่ายของแล็บ แต่ยังมีค่า EKS, EC2, EBS และ Public IPv4 ตามจริง [6][7]
ตั้ง AWS Budget สำหรับบัญชีทดลองและลบทรัพยากรหลังจบกิจกรรม หากต้องการฝึก Kubernetes บนเครื่องส่วนตัวก่อน สามารถใช้ kind หรือ minikube ได้ ซึ่งเป็น Kubernetes ในเครื่องและไม่ได้สร้าง EKS Cluster บน AWS
#6. เป้าหมายของ Workshop
เมื่อทำครบจะสามารถ:
- สร้าง EKS Cluster พร้อม Managed Node Group
- Deploy เว็บ NGINX จำนวน 2 replicas
- เข้าถึงเว็บจากเครื่องผ่าน
port-forward - ทดลอง Scale, สร้าง Pod ทดแทน และ Rolling restart
- ทดลอง HPA เมื่อมี Metrics Server
- ลบ Cluster และตรวจสอบทรัพยากรที่เกี่ยวข้อง
สภาพแวดล้อมตัวอย่าง: Region ap-southeast-1 (Singapore), Managed Node Group 2 Nodes ชนิด t3.medium และเว็บตัวอย่างที่ไม่เก็บข้อมูลถาวร การกำหนดนี้เป็นแล็บเพื่อการเรียนรู้ ต้องออกแบบเครือข่าย สิทธิ์ และความพร้อมใช้งานเพิ่มเติมก่อนใช้งานจริง
#7. เตรียมเครื่องมือและบัญชี
ติดตั้งเครื่องมือตามคู่มือทางการ แล้วตรวจสอบเวอร์ชัน [2]
aws --version
kubectl version --client
eksctl version
เลือก kubectl ที่มีเวอร์ชันเข้ากับ Cluster ตามข้อกำหนดของ Kubernetes/AWS และใช้ eksctl รุ่นที่รองรับเวอร์ชัน EKS ที่เลือก
ใช้ IAM role หรือบัญชีที่องค์กรอนุญาตให้สร้าง EKS, CloudFormation, EC2/VPC และ IAM resources รวมถึง iam:PassRole ตามนโยบายบัญชี หากใช้ IAM Identity Center ให้เข้าสู่ระบบด้วย Profile ที่ตั้งค่าไว้ เช่น:
aws configure sso --profile eks-workshop
aws sso login --profile eks-workshop
export AWS_PROFILE=eks-workshop
ถ้ามี Profile ที่ใช้งานอยู่แล้ว ให้ใช้ Profile นั้นและตรวจสอบตัวตน:
aws sts get-caller-identity
export AWS_REGION=ap-southeast-1
export EKS_CLUSTER=eks-workshop
คำสั่ง get-caller-identity ต้องแสดง Account และ IAM principal ที่ตั้งใจใช้ อย่าใช้ Root account สำหรับ Workshop และอย่านำ Access Key ไปใส่ใน Manifest หรือเผยแพร่ใน Git
#8. เลือก Kubernetes version จากข้อมูลจริง
เวอร์ชันที่เปิดให้สร้างและวันสิ้นสุดการรองรับเปลี่ยนตามเวลา จึงตรวจสอบผ่าน AWS CLI ก่อนแทนการคัดลอกเลขเวอร์ชันเก่าจากบทความ [8]
aws eks describe-cluster-versions \
--region "$AWS_REGION" \
--version-status STANDARD_SUPPORT \
--query 'clusterVersions[].{Version:clusterVersion,Default:defaultVersion,EndOfStandardSupport:endOfStandardSupportDate}' \
--output table
รับ Default version ที่ยังอยู่ใน Standard support มาใช้ในตัวอย่าง:
export EKS_VERSION=$(aws eks describe-cluster-versions \
--region "$AWS_REGION" \
--default-only \
--version-status STANDARD_SUPPORT \
--query 'clusterVersions[0].clusterVersion' \
--output text)
printf 'Selected EKS version: %s\n' "$EKS_VERSION"
ถ้าได้ค่าว่างหรือ None ให้หยุดและตรวจสอบสิทธิ์, Region และ AWS CLI ก่อนสร้าง Cluster หาก eksctl ไม่รองรับเวอร์ชันที่ได้ ให้อัปเดตเครื่องมือหรือเลือกเวอร์ชันอื่นที่ยังอยู่ใน Standard support
#9. สร้าง Cluster ด้วย eksctl
สร้างไฟล์ Configuration จากตัวแปรใน Terminal เดิม:
cat > cluster.yaml <<EOF
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: ${EKS_CLUSTER}
region: ${AWS_REGION}
version: "${EKS_VERSION}"
vpc:
nat:
gateway: Disable
clusterEndpoints:
publicAccess: true
privateAccess: true
managedNodeGroups:
- name: demo-ng
instanceType: t3.medium
desiredCapacity: 2
minSize: 2
maxSize: 4
volumeSize: 20
privateNetworking: false
labels:
purpose: workshop
EOF
managedNodeGroups ระบุการใช้ Managed Node Group ส่วน privateNetworking: false เลือก Public Subnets สำหรับ Node ของแล็บ gateway: Disable ไม่สร้าง NAT Gateway สำหรับ VPC ใหม่นี้ อย่าเปลี่ยน Nodes เป็น Private Subnet โดยปิด NAT แล้วคาดว่าจะดึง Images จากอินเทอร์เน็ตได้ ต้องจัดเส้นทางออกหรือ VPC endpoints ให้เหมาะสม [3][7]
Public Kubernetes API endpoint ยังต้องผ่าน Authentication และ Authorization ในระบบจริงควรจำกัด CIDR หรือใช้ Private endpoint พร้อมช่องทางเครือข่ายของผู้ดูแล
ตรวจไฟล์และสร้าง Cluster:
cat cluster.yaml
eksctl create cluster --config-file cluster.yaml
คำสั่งนี้สร้าง AWS resources และเริ่มมีค่าใช้จ่าย การสร้างใช้เวลาหลายนาที eksctl ใช้ CloudFormation และเขียนข้อมูลเชื่อมต่อ Cluster ลงใน kubeconfig ให้ [9]
ตรวจสถานะ:
aws eks describe-cluster \
--name "$EKS_CLUSTER" \
--region "$AWS_REGION" \
--query 'cluster.{Status:status,Version:version}' \
--output table
kubectl config current-context
kubectl get nodes -o wide
kubectl get pods -n kube-system
คาดหวังว่า Cluster เป็น ACTIVE, มี Nodes 2 ตัวที่เป็น Ready และ System Pods พร้อมใช้งาน หากไม่ได้ใช้เครื่องหรือ IAM principal เดิม สามารถสร้าง kubeconfig ใหม่ได้:
aws eks update-kubeconfig \
--name "$EKS_CLUSTER" \
--region "$AWS_REGION"
การมี kubeconfig ไม่ได้ให้สิทธิ์ Kubernetes เพิ่มโดยอัตโนมัติ ต้องมี EKS access entry/access policy หรือการกำหนดสิทธิ์ที่ Cluster ใช้อยู่ด้วย [10]
#10. Deploy เว็บตัวอย่าง
สร้างไฟล์ app.yaml ดังนี้ ตัวอย่างนี้เขียนขึ้นสำหรับแล็บ โดยใช้ NGINX image และ Service ภายใน Cluster
apiVersion: v1
kind: Namespace
metadata:
name: eks-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-web
namespace: eks-demo
spec:
replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:
app: demo-web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: demo-web
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: demo-web
topologyKey: kubernetes.io/hostname
containers:
- name: web
image: nginx:stable-alpine
ports:
- name: http
containerPort: 80
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 500m
memory: 128Mi
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: demo-web
namespace: eks-demo
spec:
type: ClusterIP
selector:
app: demo-web
ports:
- name: http
port: 80
targetPort: http
จุดสำคัญของ Manifest:
replicas: 2ขอให้มี Pod สองชุดrequestsเป็นทรัพยากรที่ใช้ในการจัดตาราง และ CPU request เป็นฐานของ HPA แบบ CPU utilizationreadinessProbeตรวจว่า Pod พร้อมรับ Traffic หรือไม่livenessProbeตรวจสุขภาพ Container และอาจทำให้ Container ถูก Restart เมื่อไม่ผ่านmaxUnavailable: 0ให้ RollingUpdate พยายามรักษาจำนวน Pod ที่พร้อมใช้งาน- Pod anti-affinity เป็นการให้ความสำคัญกับการกระจาย Pods คนละ Node ไม่ใช่การรับประกันการกระจายข้าม Availability Zones
nginx:stable-alpine เป็น Tag ที่เปลี่ยน Image ปลายทางได้ ใช้เพื่อความง่ายของแล็บ ใน Production ควร Pin เวอร์ชันหรือ Digest ของ Image ที่ผ่านการตรวจสอบแล้ว
นำขึ้น Cluster และรอ Deployment:
kubectl apply -f app.yaml
kubectl rollout status deployment/demo-web -n eks-demo --timeout=180s
kubectl get deployment,pods,service -n eks-demo -o wide
ผลที่คาดหวัง: Deployment มี READY เป็น 2/2, Pods อยู่ในสถานะ Running และ Service เป็น ClusterIP
#11. เปิดเว็บและทดลอง Self-healing
เปิด Terminal แรก:
kubectl port-forward -n eks-demo service/demo-web 8080:80
เปิด http://localhost:8080 หรือใช้ Terminal อีกหน้าต่าง:
curl -I http://localhost:8080
ควรได้รับ HTTP 200 OK และเห็นหน้า Welcome ของ NGINX เมื่อเปิดใน Browser port-forward นี้ใช้เพื่อทดสอบจากเครื่องผู้ดูแล ไม่ใช่ Public URL ของเว็บ และเลือกส่งต่อไป Pod ตัวหนึ่ง ไม่ได้ทดสอบการกระจาย Load ของ Load Balancer
เพื่อดูการสร้าง Pod ทดแทน ให้กด Ctrl+C หยุด port-forward ก่อน แล้วลบ Pod เพียงตัวเดียว:
POD_NAME=$(kubectl get pods -n eks-demo -l app=demo-web \
-o jsonpath='{.items[0].metadata.name}')
kubectl delete pod "$POD_NAME" -n eks-demo
kubectl get pods -n eks-demo -w
Deployment/ReplicaSet จะสร้าง Pod ใหม่เพื่อรักษาจำนวน replicas กด Ctrl+C เมื่อสังเกตครบ และรัน port-forward ใหม่หากต้องการดูเว็บต่อ
สิ่งที่ทดสอบคือการสร้าง Pod ทดแทน ไม่ใช่การกู้ข้อมูลถาวรหรือการรับประกันว่าเว็บจะไม่มี Downtime ในทุกสถานการณ์
#12. Scale และ Rolling restart
เพิ่มจำนวน Pod ด้วยตนเอง:
kubectl scale deployment/demo-web -n eks-demo --replicas=4
kubectl rollout status deployment/demo-web -n eks-demo --timeout=180s
kubectl get pods -n eks-demo -o wide
ลดกลับเหลือสองชุด:
kubectl scale deployment/demo-web -n eks-demo --replicas=2
จำนวน Pods และจำนวน Nodes เป็นคนละเรื่อง การ Scale Deployment ไม่ได้เพิ่ม EC2 ให้อัตโนมัติ หาก Capacity ไม่พอ Pods อาจอยู่ในสถานะ Pending
ทดลอง Rolling restart โดยใช้ Image เดิม:
kubectl rollout restart deployment/demo-web -n eks-demo
kubectl rollout status deployment/demo-web -n eks-demo --timeout=180s
kubectl rollout history deployment/demo-web -n eks-demo
นี่เป็นการสร้าง Pods ใหม่จาก Pod template เพื่อฝึกดู Rollout การปล่อยแอปเวอร์ชันใหม่จริงต้องเปลี่ยน Image หรือ Configuration ที่เกี่ยวข้อง และมีการตรวจสอบผลการทำงาน
#แบบฝึกหัดเสริม: จำลอง Image ที่ดึงไม่ได้ แล้ว Rollback
ใช้เฉพาะ Deployment ตัวอย่างของแล็บ คำสั่งถัดไปตั้ง Image tag ที่ไม่มีอยู่เพื่อให้เห็น Failure โดยตั้งใจ:
kubectl set image deployment/demo-web \
web=nginx:eks-workshop-invalid-tag -n eks-demo
kubectl get pods -n eks-demo
kubectl describe deployment demo-web -n eks-demo
รอแล้วจะเห็น Pod ใหม่มีปัญหา ErrImagePull หรือ ImagePullBackOff ขณะที่ RollingUpdate ที่กำหนดไว้พยายามรักษา Pods เดิม จากนั้นกู้กลับ:
kubectl rollout undo deployment/demo-web -n eks-demo
kubectl rollout status deployment/demo-web -n eks-demo --timeout=180s
Rollback นี้ย้อน Pod template ของ Deployment ไม่ได้ย้อน Database migration หรือข้อมูลที่แอปเปลี่ยนไป [13]
#13. เพิ่ม HPA ด้วย Metrics Server
HPA แบบ CPU ต้องมี Resource Metrics ที่ใช้งานได้ และ Container ต้องมี CPU request Metrics Server ไม่ได้ถูกติดตั้งโดยค่าเริ่มต้นใน EKS และสามารถติดตั้งผ่าน Community add-on ของ EKS ได้ [15]
ตรวจสอบก่อนว่ามี Metrics Server อยู่แล้วหรือไม่:
kubectl get deployment metrics-server -n kube-system
หากมีอยู่แล้ว ให้ตรวจว่าใช้งานได้และข้ามการติดตั้ง หากยังไม่มี ให้ดู Add-on version ที่เข้ากับ Cluster:
aws eks describe-addon-versions \
--addon-name metrics-server \
--kubernetes-version "$EKS_VERSION" \
--region "$AWS_REGION" \
--query 'addons[].addonVersions[].addonVersion' \
--output table
สร้าง Add-on โดยให้ EKS เลือก Default version ที่เข้ากันได้:
aws eks create-addon \
--cluster-name "$EKS_CLUSTER" \
--addon-name metrics-server \
--region "$AWS_REGION"
aws eks wait addon-active \
--cluster-name "$EKS_CLUSTER" \
--addon-name metrics-server \
--region "$AWS_REGION"
kubectl top nodes
kubectl top pods -n eks-demo
ถ้าไม่มี Add-on version ที่เข้ากันได้ ให้ตรวจเอกสาร Metrics Server และเวอร์ชัน Cluster ก่อนดำเนินการ อย่าติดตั้งทั้ง Add-on และ Manifest ซ้ำกันใน Cluster เดียว
สร้างไฟล์ hpa.yaml:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: demo-web
namespace: eks-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: demo-web
minReplicas: 2
maxReplicas: 6
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
kubectl apply -f hpa.yaml
kubectl get hpa -n eks-demo
kubectl describe hpa demo-web -n eks-demo
CPU target 60% คิดเทียบกับ CPU request ของ Container ในตัวอย่างเป็น 100m จึงเท่ากับ CPU เฉลี่ยราว 60m ต่อ Pod ไม่ใช่ 60% ของ CPU ทั้งเครื่อง [16]
NGINX หน้า Static อาจใช้ CPU น้อยจนไม่ถึง Threshold จึงไม่ได้รับประกันว่าแค่เปิดเว็บแล้วจะเพิ่ม Pod แบบฝึกหัดนี้เน้นการตั้ง HPA และอ่าน Metrics หากต้องการเห็น Scale-out ชัดเจน ให้ทดลอง Workload ใช้ CPU ตาม HPA walkthrough ของ AWS
เมื่อ HPA ควบคุมจำนวน replicas แล้ว อย่าใช้ Manual scaling หรือ Apply replicas เดิมซ้ำโดยไม่พิจารณาผลต่อ HPA
#14. สิ่งที่ควรเพิ่มเมื่อนำไปใช้จริง
| ด้าน | แนวทางออกแบบ |
|---|---|
| Network | วาง Nodes ใน Private Subnets, ออกแบบ NAT/VPC endpoints และจำกัดการเข้าถึง Kubernetes API |
| Public traffic | ใช้ Load Balancing ที่รองรับกับโหมด Cluster พร้อม HTTPS, DNS และ Certificates |
| Availability | กระจาย Workload ข้าม Nodes/AZs, วาง Probes, Topology constraints และ PodDisruptionBudget |
| User access | ใช้ EKS access entries/access policies และ Kubernetes RBAC ตามบทบาท |
| AWS access ของแอป | ผูก IAM role กับ ServiceAccount ด้วยวิธีที่ Compute รองรับ เช่น EKS Pod Identity หรือ IRSA |
| Images | เก็บ Image ใน Registry, Scan และ Pin Image ที่ผ่านการตรวจสอบ |
| Storage | เลือก EBS/EFS หรือบริการจัดเก็บตามรูปแบบการใช้งาน พร้อมสำรองและทดสอบ Restore |
| Observability | เก็บ Application logs, Metrics และ Alerts พร้อมระยะเวลาการเก็บที่เหมาะสม |
| Deployment | ใช้ CI/CD หรือ GitOps พร้อมทดสอบและวางแผน Rollback |
| Cost/version | ติดตาม Resource requests, ค่าใช้จ่าย และวันสิ้นสุด Standard support |
แยกสิทธิ์ คนเข้า Kubernetes API ออกจากสิทธิ์ แอปใน Pod เรียก AWS APIs: EKS access entries ช่วยจัดการอย่างแรก ส่วน Pod Identity ผูก IAM role กับ ServiceAccount สำหรับอย่างหลัง ความสามารถและข้อจำกัดขึ้นกับ Compute ที่เลือก [10][11]
Auto Mode ช่วยดูแลโครงสร้างพื้นฐานมากขึ้น แต่ทีมยังต้องออกแบบ Security ของแอป, ทรัพยากร, ข้อมูล และนโยบายการ Deploy ให้เหมาะกับระบบ [5]
#15. ปัญหาที่พบบ่อย
| อาการ | จุดที่ควรตรวจ | คำสั่งเริ่มต้น |
|---|---|---|
| Cluster สร้างไม่สำเร็จ | IAM permissions, Service quotas, Region/AZ capacity และ CloudFormation events | eksctl get cluster --region "$AWS_REGION" |
kubectl เป็น Unauthorized/Forbidden |
Profile/Role ปัจจุบัน, access entry/access policy และ RBAC | aws sts get-caller-identity และ kubectl auth can-i get pods -n eks-demo |
| Node ไม่เป็น Ready | Nodegroup health, Network, CNI และ IP ใน Subnet | kubectl describe node <node-name> |
| Pod เป็น Pending | CPU/Memory requests, Taints, Affinity และ Node capacity | kubectl describe pod <pod-name> -n eks-demo |
| ImagePullBackOff | Image name/tag, Registry permissions และเส้นทางเครือข่าย | kubectl describe pod <pod-name> -n eks-demo |
| CrashLoopBackOff | Application error, Configuration และ Health probes | kubectl logs <pod-name> -n eks-demo --previous |
HPA แสดง <unknown> |
Metrics Server, CPU requests และสิทธิ์/Network ของ Metrics | kubectl top pods -n eks-demo |
port-forward หยุดหลังลบ Pod |
Pod ที่ถูกเลือกไว้ถูกลบหรือทดแทน | รัน kubectl port-forward ใหม่ |
| เพิ่ม Pods แล้ว Node ไม่เพิ่ม | ยังไม่มี Capacity autoscaler หรือถึงขีดจำกัดของกลุ่ม | ตรวจ Nodegroup และ Pending Pod events |
ดู Events ของ Namespace เพื่อหาสาเหตุเพิ่มเติม:
kubectl get events -n eks-demo --sort-by=.metadata.creationTimestamp
อ่าน Event ที่เกี่ยวข้องก่อนเปลี่ยนสิทธิ์หรือเพิ่มขนาดเครื่อง เพราะ Error เดียวกันอาจมีสาเหตุต่างกัน
#16. ลบทรัพยากรหลังจบ Workshop
หยุด port-forward และ Watch commands ด้วย Ctrl+C จากนั้นลบ Namespace ของแล็บ:
kubectl delete namespace eks-demo --wait=true
หากเพิ่ม Ingress, Service แบบ LoadBalancer หรือ PersistentVolume ในการทดลองต่อยอด ให้ลบและตรวจการ Cleanup ทรัพยากรเหล่านั้นขณะที่ Cluster/controllers ยังทำงานอยู่ รวมถึงตรวจ Reclaim policy ของ Volume
ลบ Cluster ที่สร้างสำหรับ Workshop นี้:
eksctl delete cluster \
--name "$EKS_CLUSTER" \
--region "$AWS_REGION" \
--wait
--wait ช่วยให้คำสั่งรายงานผลการลบและข้อผิดพลาดหลังรอ CloudFormation ไม่ใช่เพียงส่งคำขอลบแล้วจบ [9]
ตรวจว่า Cluster หายไป:
aws eks describe-cluster \
--name "$EKS_CLUSTER" \
--region "$AWS_REGION"
สำหรับ Cluster ที่ถูกลบแล้ว คาดว่าจะได้ ResourceNotFoundException ถ้าได้ AccessDenied หรือ Network error ยังยืนยันการลบไม่ได้
ตรวจ AWS Console เพิ่มเติมว่า CloudFormation stacks ของแล็บถูกลบแล้ว และไม่มี EC2, Load Balancers, EBS volumes หรือ Elastic IP ที่สร้างเพิ่มเหลืออยู่ การลบ Cluster ไม่รับประกันว่าจะลบทรัพยากรที่สร้างแยกไว้ทั้งหมด เช่น ECR images, Log groups หรือ Volumes ที่เลือก Retain
#17. แนวทางเรียนต่อ
หลังทำ Workshop พื้นฐานครบ ลองเปลี่ยนจาก NGINX เป็น Web API ของตนเอง แล้วต่อยอดตามลำดับ:
- Build Image และ Push ไป Amazon ECR
- กำหนด Configuration และ Secrets ของ API
- เปิดบริการผ่าน Load Balancer/Ingress พร้อม HTTPS
- เพิ่ม CI/CD หรือ GitOps เพื่อ Deploy เวอร์ชันใหม่
- เพิ่ม Monitoring และทดสอบ Scaling/Failure recovery
- เปรียบเทียบ Managed Node Groups กับ Auto Mode จากความต้องการและค่าใช้จ่ายจริง
ถ้าต้องการเริ่มด้วย Auto Mode ให้ใช้คู่มือ AWS Quickstart ซึ่งประกาศ autoModeConfig.enabled: true และแสดงตัวอย่าง Load Balancing/Storage ที่เข้ากับโหมดนั้น แยกสร้างเป็นแล็บอีกชุดและ Cleanup ของชุดเดิมก่อน เพื่อไม่ให้เปิดสอง Cluster โดยไม่ตั้งใจ [17]
#เอกสารอ้างอิง
เอกสารทางการที่ใช้ตรวจสอบแนวคิดและคำสั่ง ตัวอย่าง Deployment/Service/HPA ในบทความเรียบเรียงขึ้นสำหรับการเรียนรู้
- AWS — What is Amazon EKS?
- AWS — Set up to use Amazon EKS
- AWS — EKS managed nodegroups with eksctl
- AWS — Simplify compute management with AWS Fargate
- AWS — Automate cluster infrastructure with EKS Auto Mode
- AWS — Amazon EKS Pricing
- AWS — eksctl VPC Configuration
- AWS CLI — describe-cluster-versions
- AWS — Creating and managing clusters with eksctl
- AWS — EKS access entries
- AWS — EKS Pod Identity
- Kubernetes — Service
- Kubernetes — Deployments
- AWS — eksctl Auto Scaling
- AWS — Kubernetes Metrics Server
- AWS — Horizontal Pod Autoscaler
- AWS — Quickstart: Deploy a web app and store data
หมายเหตุการตรวจสอบ: ตรวจแนวคิดและรูปแบบคำสั่งกับเอกสารทางการ รวมถึงตรวจ Syntax ของตัวอย่าง YAML และ Bash ในบทความ ไม่ได้สร้าง Cluster หรือทดลองรันบนบัญชี AWS จริง ผลลัพธ์ที่ระบุใน Workshop เป็นผลที่คาดหวังและต้องตรวจสอบในสภาพแวดล้อมของผู้เรียน