Ngôn ngữ hiển thị:
Mình từng nghĩ EKS chỉ là "Kubernetes nhưng trên AWS" — cài xong là chạy. Thực tế không đơn giản vậy. Lần đầu deploy production workload lên EKS, mình mất 2 ngày chỉ để fix vấn đề node không join cluster vì security group sai. Từ đó mình học được rằng EKS có khá nhiều "ổ gà" mà tài liệu chính thức không nói rõ.
Amazon EKS (Elastic Kubernetes Service) là managed Kubernetes control plane của AWS. AWS lo toàn bộ phần etcd, API server, scheduler — bạn chỉ cần quản lý worker nodes và workloads. So với tự dựng Kubernetes trên EC2, EKS tiết kiệm kha khá effort vận hành, đổi lại phí control plane khoảng $0.10/giờ (~$72/tháng).
Nên dùng EKS khi: team đã quen Kubernetes, cần tích hợp sâu với AWS services (IAM, ALB, EFS), hoặc workload cần scaling linh hoạt. Nếu chỉ chạy vài container đơn giản, ECS hay Fargate có thể phù hợp hơn và rẻ hơn.
Có nhiều cách tạo cluster EKS: AWS Console, eksctl, Terraform, CDK. Mình recommend dùng eksctl cho lần đầu vì syntax đơn giản, còn production thì nên dùng Terraform để có IaC đầy đủ.
eksctl create cluster --name prod-cluster --region ap-northeast-1 --version 1.29 --nodegroup-name standard-workers --node-type t3.medium --nodes 2 --nodes-min 1 --nodes-max 4 --managedMột số điểm quan trọng khi tạo cluster: VPC và Subnet — Nodes nên ở private subnet, load balancer ở public subnet. Tag subnet đúng để ALB Ingress Controller tự discover: kubernetes.io/role/internal-elb=1 cho private, kubernetes.io/role/elb=1 cho public. IAM Roles — Cần 2 role riêng cho control plane và node group. Với IRSA (IAM Roles for Service Accounts), pod-level IAM permissions sẽ granular hơn nhiều. Kubernetes version — AWS support mỗi version khoảng 14 tháng, lên kế hoạch upgrade sớm.
EKS hỗ trợ 3 loại compute: Managed Node Groups, Self-managed nodes, và Fargate. Cho production, mình thường dùng Managed Node Groups kết hợp Karpenter.
Karpenter là game-changer so với Cluster Autoscaler. Thay vì scale theo node group cố định, Karpenter tự chọn instance type phù hợp nhất cho workload đang pending, provision node trong 30-60 giây, và consolidate nodes tự động để tiết kiệm cost.
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"]
limits:
cpu: 1000
disruption:
consolidationPolicy: WhenUnderutilized
consolidateAfter: 30sMẹo thực chiến: Dùng cả Spot và On-demand trong cùng NodePool. Karpenter ưu tiên Spot (rẻ hơn 60-90%), fallback về On-demand khi Spot không available. Đặt PodDisruptionBudget cho critical workloads để tránh downtime khi Spot bị reclaim.
EKS không có built-in monitoring ngon. CloudWatch Container Insights có nhưng đắt và query không linh hoạt. Mình deploy kube-prometheus-stack Helm chart cho hầu hết các project.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --namespace monitoring --create-namespace --set grafana.adminPassword=your-secure-password --set prometheus.prometheusSpec.retention=30d --set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName=gp3Metrics quan trọng cần alert: kube_pod_container_status_restarts_total — pod restart nhiều là dấu hiệu OOMKilled hoặc crash loop. node_memory_MemAvailable_bytes — memory pressure trên node, dưới 20% cần xem lại resource requests. kube_deployment_status_replicas_unavailable — alert ngay khi lớn hơn 0 cho critical services.
Nodes không join cluster: 90% là do security group. Control plane security group phải allow inbound từ node security group trên port 443 và 10250. Dùng aws eks describe-cluster để lấy cluster security group ID rồi kiểm tra rules.
Pod bị Pending mãi: Dùng kubectl describe pod xem phần Events. Thường là insufficient CPU/memory, node selector không match, hoặc PVC không bound. Với Karpenter, check NodeClaim và logs của Karpenter controller.
ImagePullBackOff: Với ECR private registry, node role cần AmazonEC2ContainerRegistryReadOnly policy. Cross-account ECR cần thêm resource policy trên ECR repository.
ALB không tạo: AWS Load Balancer Controller cần IRSA với đúng IAM policy. Check controller logs: kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller. Hay gặp nhất là thiếu subnet tags hoặc annotation kubernetes.io/ingress.class: alb.
OOMKilled liên tục: Dùng VPA (Vertical Pod Autoscaler) ở recommendation mode để biết container thực sự cần bao nhiêu memory, sau đó set limits dựa trên số đó thay vì đoán mò.
Q: EKS vs ECS — chọn cái nào?A: ECS đơn giản hơn, cost thấp hơn (không có control plane fee $72/tháng). EKS phù hợp khi team đã biết Kubernetes, cần portability, hoặc dùng nhiều Kubernetes-native tools. Với workload đơn giản, ECS + Fargate là lựa chọn pragmatic hơn.
Q: Upgrade Kubernetes version trên EKS có rủi ro không?A: Upgrade control plane thường ổn — AWS xử lý in-place. Upgrade node groups cần cẩn thận hơn: drain từng node, test workloads trước. Luôn upgrade từng minor version một, không skip. Đọc kỹ release notes về API deprecations trước khi upgrade.
Q: Làm sao giảm chi phí EKS?A: Dùng Spot instances (tiết kiệm 60-90%), Karpenter consolidation để giảm idle nodes, đặt resource requests/limits chính xác để tránh over-provisioning, tắt cluster dev/staging ngoài giờ với Scheduled Scaling, và review Savings Plans cho on-demand baseline.
EKS là công cụ mạnh nhưng đòi hỏi hiểu đúng về Kubernetes lẫn AWS networking. Nếu đang bắt đầu, hãy bắt đầu nhỏ — một cluster, vài workload đơn giản, rồi mở rộng dần. Đừng cố implement mọi thứ (service mesh, GitOps, multi-tenancy) ngay từ đầu.
Ba bài học đắt giá mình rút ra: monitoring và alerting phải setup trước khi đưa workload lên production; resource requests/limits phải set ngay từ ngày đầu, không phải sau khi gặp OOMKilled; và luôn có upgrade plan từ khi mới tạo cluster.