Mô phỏng lỗi AZ cho tải làm việc Kubernetes bằng Trình mô phỏng Lỗi AWS

bởi Siva Guruvareddiar, Elamaran Shanmugam, and Re Alvarez-Parmar | on 09 JUN 2023 | in Amazon Elastic Kubernetes Service, Architecture, Technical How-to | Permalink |  Share

Trong các hệ thống phân tán cao, việc đảm bảo các ứng dụng hoạt động chính xác ngay cả trong trường hợp lỗi hạ tầng là rất quan trọng. Một kịch bản lỗi hạ tầng phổ biến là khi một Availability Zone (AZ) hoàn toàn trở nên không khả dụng. Các ứng dụng thường được triển khai trên nhiều AZ để đảm bảo khả năng sẵn sàng cao và khả năng chống lỗi trong các môi trường điện toán đám mây như Amazon Web Services (AWS).

Kubernetes giúp quản lý và triển khai các ứng dụng trên nhiều node và AZ, mặc dù việc kiểm tra cách ứng dụng của bạn sẽ hoạt động trong trường hợp lỗi AZ có thể khó khăn. Đây là nơi các trình mô phỏng lỗi đóng vai trò. Dịch vụ AWS Fault Injection Simulator (AWS FIS) có thể cố tình gây lỗi hoặc thất bại vào một hệ thống để kiểm tra khả năng phục hồi của nó. Trong bài đăng trên blog này, chúng ta sẽ khám phá cách sử dụng AWS FIS để mô phỏng lỗi AZ cho các tải làm việc Kubernetes.

Tổng quan giải pháp

Để đảm bảo rằng các tải làm việc cụm Kubernetes được thiết kế để xử lý lỗi, bạn phải kiểm tra khả năng phục hồi của chúng bằng cách mô phỏng các kịch bản lỗi trong thế giới thực. Kubernetes cho phép bạn triển khai tải làm việc trên nhiều AZ để xử lý lỗi, nhưng việc kiểm tra cách hệ thống của bạn hoạt động trong trường hợp lỗi AZ vẫn rất quan trọng. Để làm điều này, chúng tôi sử dụng một microservice cho chi tiết sản phẩm với mục đích chạy microservice này bằng cách tự động quy mô với Karpenter và kiểm tra cách hệ thống phản hồi với các mức độ lưu lượng khác nhau.

Bài đăng trên blog này khám phá một bài kiểm tra tải để mô phỏng hành vi của hàng trăm người dùng truy cập dịch vụ đồng thời để mô phỏng một kịch bản lỗi thực tế. Bài kiểm tra này sử dụng AWS FIS để gây gián đoạn kết nối mạng và mô phỏng lỗi AZ một cách có kiểm soát. Chúng tôi sẽ sử dụng Karpenter làm công cụ tự động quy mô. Karpenter tự động điều chỉnh kích thước của cụm dựa trên yêu cầu tài nguyên của các tải làm việc đang chạy.

Hình 1 minh họa kiến trúc của giải pháp.

Hình 1. Luồng kiến trúc dành cho vi dịch vụ để mô phỏng kịch bản lỗi thực tế

Điều kiện tiên quyết

Cài đặt các tiện ích sau trên một máy chủ dựa trên Linux, có thể là một Amazon Elastic Compute Cloud (Amazon EC2) instance, AWS Cloud9 instance, hoặc một máy cục bộ có quyền truy cập vào tài khoản AWS của bạn:

  • AWS CLI version 2  để tương tác với các dịch vụ AWS bằng các lệnh CLI
  • Node.js (v16.0.0 trở lên) và npm (8.10.0 trở lên)
  • AWS CDK v2.70.0  trở lên để xây dựng và triển khai cơ sở hạ tầng đám mây và các tài nguyên Kubernetes theo cách lập trình
  • Kubectl  để giao tiếp với máy chủ API Kubernetes
  • Helm để quản lý các ứng dụng Kubernetes
  • eks-node-viewer  để xem trực quan việc sử dụng node động trong một cụm Amazon Elastic Kubernetes Service (Amazon EKS)

Thiết lập môi trường microservice

Bài đăng trên blog này bao gồm hai phần chính: Bootstrap và thí nghiệm. Phần bootstrap cung cấp hướng dẫn từng bước để:

  • Tạo và triển khai một microservice mẫu
  • Tạo vai trò AWS IAM cho dịch vụ FIS
  • Tạo mẫu thử nghiệm FIS

Bằng cách làm theo các hướng dẫn bootstrap này, bạn có thể thiết lập môi trường của riêng mình để kiểm tra hiệu suất của các công cụ tự động quy mô khác nhau trong Kubernetes.

Trong phần thí nghiệm, chúng tôi sẽ trình bày cách hệ thống hoạt động với Karpenter.

Hãy bắt đầu bằng cách đặt một số biến môi trường bằng cách sử dụng đoạn mã sau:

export FIS_ACCOUNT_ID=$(aws sts get-caller-identity –query ‘Account’ –output text)export FIS_AWS_REGION=us-west-2export FIS_CLUSTER_NAME=”fis-simulation-cluster”

export FIS_ACCOUNT_ID=$(aws sts get-caller-identity –query ‘Account’ –output text)

export FIS_AWS_REGION=us-west-2

export FIS_CLUSTER_NAME=”fis-simulation-cluster”

Tiếp theo, sao chép kho lưu trữ mẫu chứa mã cho giải pháp của chúng tôi:

git clone https://github.com/aws-samples/containers-blog-maelstrom.gitcd ./containers-blog-maelstrom/fis-simulation-blog

git clone https://github.com/aws-samples/containers-blog-maelstrom.git

cd ./containers-blog-maelstrom/fis-simulation-blog

Bước 1. Khởi động môi trường

Giải pháp này sử dụng Amazon EKS cho Amazon EKS for AWS Cloud Development Kit (AWS CDK) Blueprints  để cung cấp cụm Amazon EKS của chúng tôi.

Bước đầu tiên cho bất kỳ triển khai AWS CDK  nào là khởi chạy môi trường. cdk bootstrap là một công cụ AWS Command Line Interface  (AWS CLI) chuẩn bị môi trường với các tài nguyên cần thiết để AWS CDK có thể thực hiện các triển khai vào môi trường đó (ví dụ: tổ hợp của tài khoản AWS và Vùng AWS).

Hãy chạy các lệnh dưới đây để khởi chạy môi trường của bạn và cài đặt tất cả các phụ thuộc node cần thiết để triển khai giải pháp:

npm installcdk bootstrap aws://$FIS_ACCOUNT_ID/$FIS_AWS_REGION

npm install

cdk bootstrap aws://$FIS_ACCOUNT_ID/$FIS_AWS_REGION

Chúng tôi sẽ sử dụng Amazon EKS Blueprints cho CDK để tạo một cụm Amazon EKS và triển khai các add-on. Stack này triển khai các add-on sau vào cụm:

  • AWS Load Balancer Controller
  • AWS VPC CNI
  • Core DNS
  • Kube-proxy

Bước 2. Tạo một cụm Amazon EKS

Chạy lệnh dưới đây để triển khai cụm Amazon EKS:

npm installcdk deploy “*” –require-approval never

npm install

cdk deploy “*” –require-approval never

Quá trình triển khai mất khoảng 20-30 phút; sau đó bạn sẽ có một cụm Amazon EKS hoàn chỉnh trong tài khoản của mình.

fis-simulation-clusterDeployment time: 1378.09s

fis-simulation-cluster

Deployment time: 1378.09s

Sao chép và chạy lệnh aws eks update-kubeconfig … từ phần output để có quyền truy cập vào cụm Amazon EKS của bạn bằng kubectl.

Bước 3. Triển khai microservice cho Amazon EKS

Sử dụng mã từ kho lưu trữ Github sau và triển khai bằng Helm.

git clone https://github.com/aws-containers/eks-app-mesh-polyglot-demo.githelm install workshop eks-app-mesh-polyglot-demo/workshop/helm-chart/

git clone https://github.com/aws-containers/eks-app-mesh-polyglot-demo.git

helm install workshop eks-app-mesh-polyglot-demo/workshop/helm-chart/

Lưu ý: Bạn không bị giới hạn bởi một điều bắt buộc này. Nếu bạn có các microservice khác, hãy sử dụng cùng một cách. Lệnh này triển khai ba microservice sau:

  1. Frontend-node làm giao diện người dùng cho ứng dụng danh mục sản phẩm
  2. Backend chi tiết danh mục
  3. Backend danh mục sản phẩm

Để kiểm tra khả năng phục hồi, hãy lấy một trong các microservice như productdetail, microservice backend làm ví dụ. Bằng cách sử dụng topology-spread của Kubernetes, bạn có thể yêu cầu bộ điều phối phân tán các pod trên các vùng khả dụng để giới hạn phạm vi ảnh hưởng của một sự cố. Vá triển khai với topologySpreadConstraint như sau.

cat <<EOF > patch-file.yamlspec:  template: spec:      topologySpreadConstraints:     – maxSkew: 1       topologyKey: “topology.kubernetes.io/zone”       whenUnsatisfiable: DoNotSchedule       labelSelector:         matchLabels:           app: proddetailEOFkubectl patch deployment proddetail -n workshop –patch-file patch-file.yaml

cat <<EOF > patch-file.yaml

spec:

  template:

spec:

      topologySpreadConstraints:

     – maxSkew: 1

       topologyKey: “topology.kubernetes.io/zone”

       whenUnsatisfiable: DoNotSchedule

       labelSelector:

         matchLabels:

           app: proddetail

EOF

kubectl patch deployment proddetail -n workshop –patch-file patch-file.yaml

Khi kiểm tra trạng thái của một dịch vụ như sau, bạn sẽ thấy proddetail đó thuộc loại ClusterIP, chỉ có thể truy cập được trong cụm. Để truy cập vào bên ngoài cụm này, hãy thực hiện các bước sau.

kubectl get service proddetail -n workshop NAME      TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S) AGE                                                                 5000/TCP   11h proddetail ClusterIP  10.100.168.219   <none>    3000/TCP 11m
Tạo ingress class
cat <<EOF | kubectl create -f -apiVersion: networking.k8s.io/v1kind: IngressClassmetadata:  name: aws-albspec:  controller: ingress.k8s.aws/alb  EOF

kubectl get service proddetail -n workshop

 NAME      TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S) AGE                                                                 

5000/TCP   11h

 proddetail ClusterIP  10.100.168.219   <none>    3000/TCP 11m

Tạo ingress class

cat <<EOF | kubectl create -f –

apiVersion: networking.k8s.io/v1

kind: IngressClass

metadata:

  name: aws-alb

spec:

  controller: ingress.k8s.aws/alb  

EOF

Tạo ingress resource

cat <<EOF | kubectl create -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  namespace: workshop  name: proddtl-ingress  annotations:    alb.ingress.kubernetes.io/scheme: internet-facing    alb.ingress.kubernetes.io/target-type: ipspec:  ingressClassName: aws-alb  rules:  – http:      paths:      – path: /        pathType: Prefix        backend:          service:            name: proddetail            port:               number: 3000EOF 

cat <<EOF | kubectl create -f –

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

  namespace: workshop

  name: proddtl-ingress

  annotations:

    alb.ingress.kubernetes.io/scheme: internet-facing

    alb.ingress.kubernetes.io/target-type: ip

spec:

  ingressClassName: aws-alb

  rules:

  – http:

      paths:

      – path: /

        pathType: Prefix

        backend:

          service:

            name: proddetail

            port:

               number: 3000

EOF 

Sau đó, web URL của bạn đã sẵn sàng

kubectl get ingress -n workshopNAME CLASS HOSTS ADDRESS PORTS AGEproddtl-ingress aws-alb * k8s-workshop-proddtli-166014b35f-354421654.us-west-1.elb.amazonaws.com 80 14s

kubectl get ingress -n workshop

NAME CLASS HOSTS ADDRESS PORTS AGE

proddtl-ingress aws-alb * k8s-workshop-proddtli-166014b35f-354421654.us-west-1.elb.amazonaws.com 80 14s

Kiểm tra kết nối từ browser của bạn:

Hình 2: kiểm tra kết nối từ browser

Bước 4. Tạo vai trò IAM cho AWS FIS

Trước khi thử nghiệm AWS FIS, hãy tạo vai trò IAM. Hãy tạo một chính sách tin cậy và đính kèm như được hiển thị ở đây:

cat > fis-trust-policy.json << EOF{    “Version”: “2012-10-17”,    “Statement”: [        {            “Effect”: “Allow”,            “Principal”: {                “Service”: [                  “fis.amazonaws.com”                ]            },            “Action”: “sts:AssumeRole”        }    ]}EOFaws iam create-role –role-name my-fis-role –assume-role-policy-document file://permissons/fis-trust-policy.json

cat > fis-trust-policy.json << EOF

{

    “Version”: “2012-10-17”,

    “Statement”: [

        {

            “Effect”: “Allow”,

            “Principal”: {

                “Service”: [

                  “fis.amazonaws.com”

                ]

            },

            “Action”: “sts:AssumeRole”

        }

    ]

}

EOF

aws iam create-role –role-name my-fis-role –assume-role-policy-document file://permissons/fis-trust-policy.json

Tạo một AWS FIS policy và gắn vào

aws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorNetworkAccessaws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/CloudWatchAgentServerPolicyaws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorEKSAccessaws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorEC2Accessaws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorSSMAccess

aws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorNetworkAccess

aws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

aws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorEKSAccess

aws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorEC2Access

aws iam attach-role-policy –role-name my-fis-role –policy-arn  arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorSSMAccess

Bước 5: Tạo thử nghiệm AWS FIS

Sử dụng AWS FIS để tạo thử nghiệm nhằm phá vỡ kết nối mạng như bên dưới. Sử dụng mẫu thử nghiệm sau với vai trò IAM được tạo từ bước trước:

Hình 3. Mẫu thí nghiệm

Bước 6. Mô phỏng lỗi với AWS FIS trên Karpenter

Chúng ta đã hoàn tất quá trình thiết lập microservice, giúp microservice có thể truy cập được trên Internet và tạo mẫu AWS FIS để mô phỏng các lỗi. Bây giờ, hãy thử nghiệm cách hệ thống hoạt động với Karpenter làm bộ chia tỷ lệ tự động.

Với microservice có sẵn trong cụm Amazon EKS, chúng tôi sẽ sử dụng Locust để mô phỏng hành vi của người dùng với tổng số 100 người dùng đang cố gắng truy cập các URL cùng lúc.

Đối với các thử nghiệm sau, Chạy 1 cho thấy 100 người dùng đang cố gắng truy cập dịch vụ mà không có bất kỳ sự gián đoạn hệ thống nào. Sau đó, chúng tôi sẽ chuyển sang AWS FIS và gián đoạn kết nối mạng trong Lần chạy 2. Việc đo lường tác động của người dùng và so sánh với kết quả của lần chạy đầu tiên sẽ cung cấp thông tin chi tiết về cách hệ thống phản ứng với các lỗi và có thể được cải thiện để có độ tin cậy và hiệu suất cao hơn.

Để thực hiện thử nghiệm này, hãy chọn mẫu thử nghiệm của bạn và nhấp vào Bắt đầu thử nghiệm, sau đó nhập bắt đầu vào trường.

Hiện tại có 12 bản sao của microservice proddetail đang chạy, chúng tôi sẽ bắt đầu thử nghiệm bằng Karpenter. Như trong các hình dưới đây, cụm sử dụng kết hợp các phiên bản t3.small và “C” và “M” được cung cấp trong cấu hình nhà cung cấp của Karpenter.

Hình 4: kết quả thử nghiệm

Hình 5. Cách sử dụng nút động với cụm

Dọn dẹp

Sử dụng các lệnh sau để dọn dẹp môi trường thử nghiệm của bạn.

#delete Ingress resources
kubectl delete ingress proddtl-ingresss -n workshop
kubectl delete ingressclass aws-alb#delete IAM resources
aws iam delete-role –role-name my-fis-role#delete FIS resources
fis_template_id=`aws fis list-experiment-templates –region $FIS_AWS_REGION |jq “.experimentTemplates[0].id”`
aws fis delete-experiment-template –id $fis_template_id –region
$FIS_AWS_REGION#delete application resources and cluster
helm uninstall workshop
cdk destroy

#delete Ingress resources
kubectl delete ingress proddtl-ingresss -n workshop
kubectl delete ingressclass aws-alb

#delete IAM resources
aws iam delete-role –role-name my-fis-role

#delete FIS resources
fis_template_id=`aws fis list-experiment-templates –region $FIS_AWS_REGION |jq “.experimentTemplates[0].id”`
aws fis delete-experiment-template –id $fis_template_id –region
$FIS_AWS_REGION

#delete application resources and cluster
helm uninstall workshop
cdk destroy

Kết luận

Bài đăng trên blog này cho thấy cách mô phỏng lỗi AZ với AWS FIS trên EKS.

Mặc dù thí nghiệm này cung cấp những hiểu biết quý giá về hiệu suất và độ tin cậy của các tải làm việc Kubernetes trong trường hợp bị lỗi, điều quan trọng là phải thừa nhận rằng đây không phải là một bài kiểm tra thực sự về tình huống AZ không khả dụng. Trong một kịch bản thực tế, lỗi AZ có thể gây ra hiệu ứng dây chuyền, có khả năng ảnh hưởng đến các dịch vụ khác mà các tải làm việc phụ thuộc vào. Tuy nhiên, mô phỏng lỗi AZ trong một môi trường có kiểm soát giúp bạn hiểu rõ hơn về cách cụm Kubernetes và ứng dụng của bạn sẽ hoạt động trong một kịch bản lỗi thực tế. Kiến thức này có thể giúp bạn nhận diện và khắc phục bất kỳ vấn đề nào trước khi chúng xảy ra trong môi trường sản xuất, đảm bảo rằng các ứng dụng của bạn vẫn có khả năng sẵn sàng cao và khả năng phục hồi.

Tóm lại, thí nghiệm này cung cấp những hiểu biết tốt về hiệu suất và khả năng phục hồi của các tải làm việc Kubernetes. Đây không phải là sự thể hiện hoàn hảo của lỗi AZ trong thế giới thực, nhưng bằng cách tận dụng các công cụ như AWS FIS và cấu hình cẩn thận các chính sách tự động quy mô, bạn có thể thực hiện các bước chủ động để tối ưu hóa hiệu suất và đảm bảo khả năng sẵn sàng cao cho các ứng dụng quan trọng.