บทความสำหรับผู้เริ่มต้นที่มีพื้นฐาน Docker และต้องการเรียนรู้การนำแอปพลิเคชันขึ้น Kubernetes บน AWS ตรวจสอบเอกสารอ้างอิงวันที่ 1 ตุลาคม 2569 (2026) คำสั่ง Workshop ใช้ Bash บน macOS, Linux หรือ WSL

info-amazon-eks-kubernetes-aws-workshop-deploy

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

เมื่อทำครบจะสามารถ:

  1. สร้าง EKS Cluster พร้อม Managed Node Group
  2. Deploy เว็บ NGINX จำนวน 2 replicas
  3. เข้าถึงเว็บจากเครื่องผ่าน port-forward
  4. ทดลอง Scale, สร้าง Pod ทดแทน และ Rolling restart
  5. ทดลอง HPA เมื่อมี Metrics Server
  6. ลบ 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 utilization
  • readinessProbe ตรวจว่า 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 ของตนเอง แล้วต่อยอดตามลำดับ:

  1. Build Image และ Push ไป Amazon ECR
  2. กำหนด Configuration และ Secrets ของ API
  3. เปิดบริการผ่าน Load Balancer/Ingress พร้อม HTTPS
  4. เพิ่ม CI/CD หรือ GitOps เพื่อ Deploy เวอร์ชันใหม่
  5. เพิ่ม Monitoring และทดสอบ Scaling/Failure recovery
  6. เปรียบเทียบ Managed Node Groups กับ Auto Mode จากความต้องการและค่าใช้จ่ายจริง

ถ้าต้องการเริ่มด้วย Auto Mode ให้ใช้คู่มือ AWS Quickstart ซึ่งประกาศ autoModeConfig.enabled: true และแสดงตัวอย่าง Load Balancing/Storage ที่เข้ากับโหมดนั้น แยกสร้างเป็นแล็บอีกชุดและ Cleanup ของชุดเดิมก่อน เพื่อไม่ให้เปิดสอง Cluster โดยไม่ตั้งใจ [17]

#เอกสารอ้างอิง

เอกสารทางการที่ใช้ตรวจสอบแนวคิดและคำสั่ง ตัวอย่าง Deployment/Service/HPA ในบทความเรียบเรียงขึ้นสำหรับการเรียนรู้

  1. AWS — What is Amazon EKS?
  2. AWS — Set up to use Amazon EKS
  3. AWS — EKS managed nodegroups with eksctl
  4. AWS — Simplify compute management with AWS Fargate
  5. AWS — Automate cluster infrastructure with EKS Auto Mode
  6. AWS — Amazon EKS Pricing
  7. AWS — eksctl VPC Configuration
  8. AWS CLI — describe-cluster-versions
  9. AWS — Creating and managing clusters with eksctl
  10. AWS — EKS access entries
  11. AWS — EKS Pod Identity
  12. Kubernetes — Service
  13. Kubernetes — Deployments
  14. AWS — eksctl Auto Scaling
  15. AWS — Kubernetes Metrics Server
  16. AWS — Horizontal Pod Autoscaler
  17. AWS — Quickstart: Deploy a web app and store data

หมายเหตุการตรวจสอบ: ตรวจแนวคิดและรูปแบบคำสั่งกับเอกสารทางการ รวมถึงตรวจ Syntax ของตัวอย่าง YAML และ Bash ในบทความ ไม่ได้สร้าง Cluster หรือทดลองรันบนบัญชี AWS จริง ผลลัพธ์ที่ระบุใน Workshop เป็นผลที่คาดหวังและต้องตรวจสอบในสภาพแวดล้อมของผู้เรียน