Phần Kubernetes for Multi AWS Account gồm hai phần:
- Kubernetes Infrastructure for Scale
- Kubernetes Communication Between Multi AWS Accounts
AWS cung cấp dịch vụ Elastic Kubernetes Service (EKS) giúp triển khai Kubernetes lên AWS một cách nhanh chóng. Một vài câu hỏi quan trọng về phần EKS này là: Cách triển khai EKS trên từng tài khoản? Cấu hình EKS Autoscaler? Cluster Autoscaler và Karpenter? Sử dụng Node như thế nào thế tiết kiệm tiền nhất?
Triển khai EKS trên từng tài khoản
Ở bài Provisioning Infrastructure for Multi AWS Accounts ta đã đề cập tới việc dùng Terraform để tạo hạ tầng, cụ thể là ta dùng Credentials của tài khoản Operation để chạy Terraform tạo hạ tầng cho các tài khoản khác nhau, cấu trúc thư mục để tạo EKS cho môi trường dev.
└── nonprod-terraform
├── data-nonprod
│ ├── dev
│ │ ├── eks
├── networking-nonprod
│ ├── dev
│ │ ├── eks
├── observability-nonprod
│ ├── dev
│ │ ├── eks
├── operation-nonprod
│ ├── dev
│ │ ├── eks
└── workload-nonprod
├── dev
└── ├── eks
Scaling
Sau khi tạo EKS trên từng tài khoản xong, vấn đề tiếp theo cần quan tâm là cấu hình mở rộng cho EKS như thế nào. AWS EKS gồm hai phần chính là Control Plane do AWS quản lý và EKS Node Group (là các EC2 mà Kubernetes Pod triển khai lên). Thành phần cần mở rộng là Node Group. Trước khi nói về cách mở rộng Node Group ta xem qua các kỹ thuật mở rộng ứng dụng trong Kubernetes, gồm 4 cách:
- Application Tuning: mở rộng process trong một Pod hoặc tối ưu bằng code
- Horizontal Pod Autoscaling: mở rộng theo chiều ngang, thêm số lượng Pod
- Vertical Pod Autoscaling: mở rộng theo chiều dọc, tăng CPU hoặc Memory của Pod
- Cluster Autoscaling: mở rộng theo chiều ngang, thêm số lượng Node
Ở bài này mình tập trung chính vào Cluster Autoscaling. Còn về Horizontal Pod Autoscaling thì các bạn tham khảo Kubernetes Event-driven Autoscaling, Vertical Pod Autoscaling thì tham khảo Vertical Pod Autoscaler.
Cluster Autoscaling
EKS cung cấp hai giải pháp mở rộng Cluster:
- Cluster Autoscaler: hoạt động dựa trên Auto Scaling Groups (ASG)
- Open-source Karpenter: làm việc trực tiếp với Amazon EC2 Instances
Cả Cluster Autoscaler và Karpenter đều thực hiện mở rộng bằng cách điều chỉnh số lượng EC2 trong Node Group. Nếu một Pod mới được triển khai mà số lượng EC2 hiện tại không đủ, AutoScaler sẽ tự động tạo thêm EC2. Tương tự, khi số lượng Pod giảm, nếu EC2 không có Pod nào triển khai lên thì AutoScaler sẽ tự động xóa EC2 đó để tiết kiệm tài nguyên.
Tuy nhiên, Cluster Autoscaler là giải pháp đầu tiên để mở rộng EKS nên nó có một vài giới hạn. Cluster Autoscaler hoạt động dựa trên ASG, ASG hoạt động dựa trên Launch Template. Với mỗi Launch Template, ta chỉ có thể định nghĩa một loại EC2 Instance Type, mỗi loại Instance Type thì dính cứng CPU và Memory. Do đó thường dẫn tới tình trạng thừa tài nguyên khi mở rộng Node Group.
Ví dụ, trong ASG, chúng ta sử dụng loại EC2 m5a.large (2 vCPUs - 8 GiB). EKS hiện đang triển khai 16 Pod, mỗi Pod cần 0.5 vCPUs và 2 GiB, chúng ta cần 4 EC2 m5a.large. Khi hệ thống nhận nhiều yêu cầu, Kubernetes tự động mở rộng thêm một Pod. Tuy nhiên, do số lượng EC2 không đủ, Cluster AutoScaler sẽ tạo thêm một EC2 mới. Vì sử dụng ASG nên EC2 được tạo ra phải là loại m5a.large. Pod mới sẽ được triển khai trên EC2 mới này. Do mỗi Pod chỉ cần 0.5 vCPUs và 2 GiB nên chúng ta còn dư tới 1.5 vCPUs và 6 GiB tài nguyên.
Chúng ta có thể tránh giới hạn này bằng cách tạo nhiều ASG khác nhau, nhưng điều này sẽ dẫn đến việc cấu hình trở nên phức tạp và cũng khó tối ưu nhất. Karpenter ra đời để giải quyết vấn đề của Cluster AutoScaler.
Karpenter là một open-source được phát triển bởi AWS, Karpenter cũng thực hiện điều chỉnh số lượng EC2 khi Pod được triển khai, nhưng Karpenter không hoạt động dựa trên ASG mà làm việc trực tiếp với EC2, nên nó sẽ tạo EC2 theo cách tối ưu tài nguyên nhất.
Như hình trên ta có ví dụ sau, 5 Pod (0.75 vCPUs 1.5 GiB) ở trạng thái pending cần triển khai. Số lượng EC2 hiện tại là 2 con (1 vCPU 2GiB) nên mỗi Pod chỉ có thể triển khai lên 1 con EC2, ta còn 3 Pod pending, nếu dùng Cluster Autoscaler thì ta cần thêm 3 con EC2 và tài nguyên dư thừa là 1.25 vCPU (0.25 vCPU mỗi EC2). Còn Karpenter thì ban đầu để đảm bảo ít bị trì hoãn nhất khi triển khai Pod, nó sẽ tìm kiếm con EC2 phù hợp để triển khai được 3 Pod còn lại. Sau khi toàn bộ Pod được triển khai thì Karpenter có thêm thời gian tính toán tiếp và chọn lại các con EC2 tối ưu nhất để triển khai Pod, sau khi EC2 mới được tạo thì nó sẽ khởi tạo Pod ở EC2 mới, sau đó mới xóa mấy con EC2 cũ đi. Tham khảo bài này để hiểu rõ hơn về Karpenter: Getting Started.
Với hạ tầng EKS mới nên xài Karpenter để tối ưu cost nhất, còn đối với những hạ tầng EKS cũ nếu có thời gian ta có thể migrate Cluster Autoscaler qua Karpenter. Hạ tầng Vikki sử dụng Karpenter để mở rộng EKS.
Sử dụng Node như thế nào thế tiết kiệm
AWS EC2 có bốn mô hình định giá:
- On-Demand Instances: trả tiền EC2 theo giờ, ví dụ 0.01$/hour
- Savings Plans: mua gói giảm giá, có thể tiết kiệm 20-30% so với On-Demand
- Reserved Instances: giống với Savings Plans và tiết kiệm nhiều hơn, nhưng bị giới hạn Instances Type, ví dụ khi ta mua họ
m5x
thì chỉ được xài trong họ đó - Spot Instances: Ở mô hình này, EC2 tiết kiệm tới 90% so với On-Demand, nhưng EC2 của chúng ta có thể bị thu hồi bất cứ lúc nào. EC2 Spot được tạo ở các tài nguyên dư của AWS khi chưa có khách hàng khác sử dụng. Tuy nhiên, nếu tài nguyên đó bị khách hàng khác yêu cầu sử dụng thì EC2 của chúng ta sẽ bị thu hồi lại
Cách mua Savings Plans và Reserved Instances mình không để cập ở bài này. AWS EKS Node Group cho phép ta sử dụng kết hợp giữa On-Demand và Spot Instances.Trong môi trường dev và UAT, nếu ứng dụng của ta có thể chịu downtime từ 5-10 phút mà không ảnh hưởng nhiều, thì nên kết hợp chạy Node ở hai chế độ trên. Karpenter giúp ta thực hiện việc này đơn giản hơn.
Ta tạo EKS với Node Group On-Demand cho các ứng dụng trong namespace kube-system của Kubernetes, đây thường là các ứng dụng quan trọng và không nên bị downtime, nên triển khai Karpenter Controller lên trên Node Group On-Demand này để đảm bảo rằng nó không bị ngừng hoạt động giữa chừng. Sau đó cấu hình Karpenter để tạo Node Group Spot Instances cho các Pod còn lại.
Để hạn chế downtime do AWS thu hồi Spot Instances, ta có thể chạy một ứng dụng với 2 Pod và cấu hình Spread Constraints để 2 Pod được triển khai không nằm cùng một EC2. Nếu một EC2 Spot bị thu hồi, thì vẫn còn 1 Pod chạy trong thời gian Karpenter tạo lại EC2 khác. Ngoài ra, Karpenter còn hỗ trợ cấu hình Node Termination Handler để thực hiện một vài tác vụ trước khi Spot bị thu hồi.
Về cách phân chia ứng dụng nào nên chạy trên Node Group On-Demand và ứng dụng nào có thể chạy trên Spot Instances để tối ưu chi phí cho hạ tầng nhất, thì mình lấy ví dụ về EKS chạy CI/CD ở tài khoản Operation. Về CI/CD ta có thể tóm gọn lại hai mục quan trọng là CI/CD cho bên Workload và bên Data.
Về CI/CD cho Workload thông thường chỉ bao gồm các bước: chạy lint, chạy test, chạy xây Docker Image, quét security, đẩy Image lên ECR, thực thi CD. Những bước CI/CD này thì cho dù có bị ngưng giữa chừng thì cũng không ảnh hưởng gì nhiều, ta chỉ việc chạy lại từ đầu, nên với CI/CD cho tài khoản Workload ta có thể dùng Node Group Spot để chạy.
Còn CI/CD cho Data thường gồm các mục rất quan trọng như chạy tổng hợp dữ liệu, phân tách dữ liệu và migrate dữ liệu. Những bước này nếu bị chết giữa chừng thì ảnh hưởng rất lớn nên với CI/CD cho Data ta nên dùng Node Group On-Demand.
Phần tiếp theo ta sẽ nói về cách ứng dụng trong EKS giao tiếp giữa các tài khoản khác nhau.
Điểm hẹn ngân hàng số Vikki by HDBank
Loạt bài viết ngắn chia sẻ về kiến trúc hạ tầng của hệ thống ngân hàng trên Cloud (AWS). Đây chỉ là những kiến thức mình học được thông qua sản phẩm NGÂN HÀNG SỐ VIKKI của bên mình, nên kiến trúc có thể phù hợp và không phù hợp với doanh nghiệp của các bạn.
- AWS Account Management
- Provisioning Infrastructure for Multi AWS Accounts
- Networking for Multi AWS Accounts
- Kubernetes for Multi AWS Accounts: Kubernetes Infrastructure for Scale
- Kubernetes for Multi AWS Accounts: Kubernetes Cross Cluster Communication
- Chaos Engineering
- On-call
- Core Banking on Cloud
- Security Consider
- Log Analytics with Generative AI (PoC)