bởi James Beswick | vào 22 MAR 2024 | trong AWS Lambda, Serverless | Permalink | Share
Bài đăng này được viết bởi André Stoll, Kiến trúc sư Giải pháp.
Kiểm thử lỗi (Chaos Engineering) là một phương thức phổ biến để xây dựng sự tin tưởng vào khả năng phục hồi của hệ thống. Tuy nhiên, nhiều công cụ hiện có yêu cầu khả năng thay đổi cấu hình cơ sở hạ tầng và chúng không thể dễ dàng áp dụng cho mô hình ứng dụng không dùng server (serverless). Do bản chất không chứa trạng thái, ngắn hạn và phân tán của kiến trúc serverless, bạn cần phát triển kỹ thuật truyền thống khi chạy các thí nghiệm lỗi trên các hệ thống này.
Bài đăng trên blog này giải thích một kỹ thuật để chạy các thí nghiệm kiểm thử lỗi trên các hàm AWS Lambda. Cách tiếp cận này sử dụng các tiện ích mở rộng của Lambda (Lambda extension) để gây ra lỗi theo cách không phụ thuộc vào thời gian chạy và không yêu cầu thay đổi mã hàm. Cách tiếp cận trên là ví dụ cho cách bạn có thể sử dụng Dịch vụ tạo lỗi của AWS ( AWS Fault Injection Service – FIS) để tự động hóa và quản lý các thí nghiệm lỗi trên các hàm Lambda khác nhau để cung cấp phương thức kiểm thử có thể tái sử dụng.
Tổng quan
Thí nghiệm lỗi (Chaos Experiment) thường được áp dụng cho các ứng dụng đám mây để khám phá các vấn đề tiềm ẩn và ngăn chặn gián đoạn dịch vụ. Các nhóm IT sử dụng thí nghiệm lỗi để xây dựng lòng tin vào tính mạnh mẽ của hệ thống. Tuy nhiên, các phương pháp truyền thống được sử dụng trong kiểm thử lỗi trên nền tảng server không dễ dàng áp dụng cho thế giới serverless vì nhiều công cụ hiện có dựa trên việc thay đổi cấu hình cơ sở hạ tầng bên dưới, chẳng hạn như các cụm nút cluster node) hoặc các phiên bản server của ứng dụng.
Trong các ứng dụng serverless, AWS xử lý các tác vụ nặng nhọc, không phân biệt nhau để quản lý cơ sở hạ tầng, do đó bạn có thể tập trung vào việc cung cấp giá trị cho doanh nghiệp. Nhưng điều này cũng có nghĩa là các nhóm kỹ thuật có quyền kiểm soát hạn chế đối với cơ sở hạ tầng và phải dựa vào các công cụ cấp độ ứng dụng để chạy các thí nghiệm lỗi.
Hai kỹ thuật thường được sử dụng trong cộng đồng serverless để thực hiện các thí nghiệm lỗi trên các hàm Lambda là sửa đổi cấu hình hàm hoặc sử dụng các thư viện dành riêng cho runtime.
Thay đổi cấu hình của hàm Lambda cho phép bạn gây ra các lỗi cơ bản. Ví dụ: bạn có thể đặt tính năng chạy song song được ưu tiên (reserved concurrency) của hàm Lambda để mô phỏng việc giới hạn kích hoạt (invocation throttling). Ngoài ra, bạn có thể thay đổi quyền của role thực thi hàm (function execution role) hoặc chính sách hàm (function policy) để mô phỏng việc từ chối truy cập IAM. Các loại lỗi này dễ dàng triển khai, nhưng phạm vi các kiểu inject lỗi có thể bị hạn chế.
Trong các kỹ thuật khác – đưa lỗi vào các hàm Lambda thông qua các thư viện được xây dựng riêng cho từng runtime – linh hoạt hơn. Có nhiều thư viện mã nguồn mở cho phép bạn inject lỗi, chẳng hạn như tăng độ trễ, ngoại lệ hoặc hết dung lượng đĩa. Ví dụ về các thư viện như vậy là chaos_lambda của Python và failure-lambda dành cho Node.js. Mặt hạn chế là bạn phải thay đổi mã hàm cho mọi hàm bạn muốn chạy thí nghiệm lỗi. Ngoài ra, các thư viện đó dành riêng cho từng runtime và mỗi thư viện đi kèm với một tập hợp các khả năng và cấu hình khác nhau. Điều này làm giảm khả năng tái sử dụng các thí nghiệm lỗi của bạn trên các hàm Lambda được triển khai bằng các ngôn ngữ khác nhau.
Inject lỗi sử dụng Lambda extensions
Việc thực hiện các thí nghiệm lỗi bằng cách sử dụng Lambda extensions cho phép bạn giải quyết tất cả các mối quan ngại trước đó. Lambda extensions mở rộng các hàm của bạn bằng cách thêm các chức năng, chẳng hạn như thu thập thông tin chẩn đoán hoặc tự động ghi công cụ vào code của bạn. Bạn có thể tích hợp chặt chẽ các công cụ giám sát, quan sát hoặc bảo mật ưa thích của mình vào môi trường Lambda mà không cần cài đặt hoặc quản lý cấu hình phức tạp. Lambda extensions thường được đóng gói dưới dạng các lớp Lambda ( Lambda layers ) và chạy như một tiến trình riêng biệt trong môi trường thực thi Lambda. Bạn có thể sử dụng extensions từ AWS, các đối tác của AWS Lambda hoặc xây dựng chức năng tùy chỉnh của riêng bạn.
Với Lambda extensions, bạn có thể triển khai một chaos extension để inject các lỗi mong muốn vào môi trường Lambda của mình. Chaos extension này sử dụng mô hình proxy Runtime API cho phép bạn gắn móc (hook) vào vòng đời yêu cầu và phản hồi kích hoạt hàm. Runtime của Lambda sử dụng Lambda Runtime API để truy xuất sự kiện đến tiếp theo sẽ được xử lý bởi trình xử lý hàm (function handler) và trả về phản hồi của trình xử lý cho dịch vụ Lambda.
Điểm cuối HTTP của Runtime API có sẵn trong môi trường thực thi Lambda. Runtime nhận điểm cuối API từ biến môi trường `AWS_LAMBDA_RUNTIME_API`. Trong quá trình khởi tạo môi trường thực thi, bạn có thể sửa đổi hành vi khởi động của runtime. Điều này cho phép bạn thay đổi giá trị của `AWS_LAMBDA_RUNTIME_API` thành cổng mà tiến trình chaos extension đang lắng nghe. Bây giờ, tất cả các yêu cầu tới Runtime API đều đi qua proxy của chaos extension. Bạn có thể sử dụng quy trình làm việc này để chặn các sự kiện độc hại, kiểm toán dữ liệu payload hoặc inject lỗi.
- Tiện ích mở rộng mô phỏng lỗi (Chaos extension) can thiệp vào các sự kiện đến (incoming events) và phản hồi trả về (outbound responses), và cài lỗi theo cấu hình thí nghiệm mô phỏng.
- Tiện ích mở rộng này truy cập các biến môi trường để đọc cấu hình thí nghiệm mô phỏng.
- Một tập lệnh wrapper sẽ cấu hình runtime để chuyển tiếp các yêu cầu thông qua mở rộng mô phỏng lỗi.
Khi can thiệp vào các sự kiện đến và phản hồi trả về cho Lambda Runtime API, bạn có thể mô phỏng các lỗi như tạo độ trễ nhân tạo hoặc tạo ra phản hồi lỗi để trả về cho dịch vụ Lambda. Quy trình này sẽ làm tăng độ trễ cho các cuộc gọi hàm của bạn.
Tất cả các runtime của Lambda đều hỗ trợ các mở rộng. Vì các mở rộng chạy như một tiến trình riêng biệt, bạn có thể triển khai chúng bằng ngôn ngữ khác với ngôn ngữ code của hàm. AWS khuyên bạn nên triển khai các mở rộng bằng ngôn ngữ lập trình có thể biên dịch thành tệp thực thi nhị phân, chẳng hạn như Golang hoặc Rust. Điều này cho phép bạn sử dụng mở rộng với bất kỳ runtime Lambda nào.
Một số dự án mã nguồn mở theo kỹ thuật này là chaos-lambda-extension, được triển khai bằng Rust, hoặc serverless-chaos-extension, được viết bằng Python.
Mở rộng cung cấp cho bạn một phương pháp linh hoạt và có thể tái sử dụng để chạy các thí nghiệm mô phỏng lỗi trên các hàm Lambda. Bạn có thể sử dụng lại mở rộng mô phỏng lỗi cho tất cả các runtime mà không cần thay đổi code hàm. Thêm mở rộng vào bất kỳ hàm Lambda nào bạn muốn chạy thí nghiệm mô phỏng lỗi.
Tự động hóa với khung mẫu (template) thí nghiệm AWS FIS
Theo “Nguyên tắc Kiến trúc Chaos” (Principles of Chaos Engineering), bạn nên “tự động hóa các thí nghiệm để chạy liên tục”. Để đạt được điều này, bạn có thể sử dụng Dịch vụ Cài lỗi AWS (AWS Fault Injection Service – FIS).
Dịch vụ này cho phép bạn tạo các mẫu thí nghiệm có thể tái sử dụng. Mẫu thí nghiệm xác định các mục tiêu và hành động cần chạy trên chúng trong suốt thí nghiệm, đồng thời có thể có điều kiện dừng tùy chọn để ngăn thí nghiệm vượt quá giới hạn. Bạn cũng có thể chạy các cuốn sách hướng dẫn tự động của AWS Systems Manager hỗ trợ các loại lỗi tùy chỉnh. Bạn có thể viết các tài liệu Systems Manager tùy chỉnh của riêng mình để xác định các bước riêng lẻ liên quan đến tự động hóa. Để thực hiện các hành động của thí nghiệm, bạn định nghĩa các tập lệnh script trong tài liệu để quản lý hàm Lambda của mình và thiết lập nó cho thí nghiệm mô phỏng lỗi.
Để sử dụng tiện ích mở rộng mô phỏng cho các thí nghiệm mô phỏng lỗi serverless của bạn:
- Thiết lập hàm Lambda cho thí nghiệm. Thêm tiện ích mở rộng mô phỏng dưới dạng một lớp và cấu hình thí nghiệm, ví dụ: bằng cách thêm các biến môi trường chỉ định loại lỗi và giá trị tương ứng của nó.
- Tạm dừng tự động hóa và tiến hành thí nghiệm. Để thực hiện việc này, hãy sử dụng hành động tự động hóa `aws:sleep`. Trong giai đoạn này, bạn tiến hành thí nghiệm, đo lường và quan sát kết quả.
Dọn dẹp thí nghiệm. Script sẽ xóa lại lớp và đặt lại các biến môi trường.
Thí nghiệm lỗi serverless đầu tiên của bạn
Kho lưu mẫu này cung cấp cho bạn mã cần thiết để chạy thử nghiệm lỗi serverless đầu tiên của bạn trong AWS. Thử nghiệm sử dụng tiện ích mở rộng chaos-lambda-extension để đưa lỗi vào.
Mẫu triển khai mẫu thử nghiệm AWS FIS, các sổ tay chạy AWS SSM Automation cần thiết bao gồm vai trò IAM do sổ tay sử dụng chạy lệnh để cấu hình các hàm Lambda. Mẫu cũng cung cấp một hàm Lambda để thử nghiệm và báo động Amazon CloudWatch được sử dụng để khôi phục lại thử nghiệm.
Điều kiện tiên quyết
- Tiện ích mở rộng lỗi đã được triển khai dưới dạng lớp Lambda trong tài khoản AWS của bạn.
- Bạn đã cài đặt AWS Cloud Development Kit (CDK) CLI. Xem hướng dẫn Bắt đầu với AWS CDK để biết chi tiết.
- Clone kho lưu mẫu cục bộ bằng cách chạy
git clone git@github.com:aws-samples/serverless-chaos-experiments.git
- Đảm bảo bạn có đủ quyền để tương tác với AWS FIS, Lambda và báo động CloudWatch.
Chạy thử nghiệm
Thực hiện theo các bước được nêu trong kho lưu mẫu để tiến hành thử nghiệm đầu tiên của bạn. Bắt đầu thử nghiệm sẽ kích hoạt thực thi tự động.
Tự động hóa này bao gồm việc thêm tiện ích mở rộng và cấu hình thử nghiệm, tạm dừng thực thi và quan sát hệ thống và khôi phục tất cả các thay đổi về trạng thái ban đầu.
Nếu bạn kích hoạt hàm Lambda được nhắm mục tiêu trong bước thứ hai, các lỗi (trong trường hợp này là độ trễ nhân tạo) sẽ được mô phỏng.
Các thực hành bảo mật tốt nhất
Các tiện ích mở rộng chạy trong cùng môi trường thực thi với hàm, vì vậy chúng có cùng mức truy cập vào các tài nguyên như hệ thống tệp, mạng và biến môi trường. Quyền hạn IAM được gán cho hàm được chia sẻ với các tiện ích mở rộng. AWS khuyến nghị bạn chỉ định các đặc quyền ít nhất cần thiết cho các hàm của bạn.
Luôn luôn chỉ cài đặt tiện ích mở rộng từ nguồn đáng tin cậy. Sử dụng Infrastructure as Code (IaC) và các công cụ tự động hóa, chẳng hạn như CloudFormation hoặc AWS Systems Manager, để đơn giản hóa việc đính kèm cùng cấu hình tiện ích mở rộng, bao gồm quyền hạn IAM (AWS Identity and Access Management), cho nhiều hàm. Các công cụ IaC và tự động hóa cho phép bạn có bản ghi kiểm tra các tiện ích mở rộng và phiên bản đã sử dụng trước đó.
Khi xây dựng tiện ích mở rộng, không ghi lại dữ liệu nhạy cảm. Vô hiệu hóa dữ liệu và siêu dữ liệu trước khi ghi nhật ký hoặc duy trì chúng cho mục đích kiểm toán.
Kết luận
Bài đăng trên blog này chi tiết cách chạy thử nghiệm lỗi cho các ứng dụng serverless được xây dựng bằng Lambda. Cách tiếp cận được mô tả sử dụng tiện ích mở rộng Lambda để đưa lỗi vào môi trường thực thi. Điều này cho phép bạn sử dụng cùng một phương thức bất kể thời gian chạy hoặc cấu hình của hàm Lambda.
Để tự động hóa và tiến hành thử nghiệm thành công, bạn có thể sử dụng AWS Fault Injection Service (Dịch vụ tiêm lỗi AWS). Bằng cách tạo mẫu thử nghiệm, bạn có thể chỉ định các hành động để chạy trên các mục tiêu được xác định, chẳng hạn như thêm tiện ích mở rộng trong quá trình thử nghiệm. Vì tiện ích mở rộng có thể được sử dụng cho bất kỳ thời gian chạy nào, bạn có thể sử dụng lại mẫu thử nghiệm để đưa lỗi vào các hàm Lambda khác nhau.
Truy cập kho lưu trữ github này để triển khai thử nghiệm lỗi serverless đầu tiên của bạn hoặc xem hướng dẫn video này để tìm hiểu thêm về việc xây dựng tiện ích mở rộng. Khám phá tài liệu AWS FIS để tìm hiểu cách tạo các thử nghiệm của riêng bạn.
Để biết thêm tài nguyên học tập serverless, hãy truy cập Serverless Land.