Hiểu Rõ Spark History Server Trên EKS Với Spark Operator & IRSA

KiloKilo
8 min read

Trong bài viết này, chúng ta sẽ đi sâu vào cách triển khai và vận hành Spark History Server trên Amazon EKS, kết hợp với Spark Operator và lưu trữ log sự kiện trên Amazon S3 thông qua IAM Roles for Service Accounts (IRSA). Đây là mô hình lý tưởng cho các hệ thống xử lý dữ liệu hiện đại trên Kubernetes, đáp ứng yêu cầu:

  • Tách biệt job runtime và job history

  • Dễ scale & kiểm soát bảo mật

  • Khả năng theo dõi các Spark job sau khi kết thúc

1️⃣ Spark History Server là gì?

Spark History Server (SHS) là một thành phần trong hệ sinh thái Apache Spark, cho phép người dùng xem lại thông tin chi tiết của các Spark jobs đã hoàn thành, thông qua UI quen thuộc như khi đang chạy job trực tiếp.

Spark History Server là một công cụ quan trọng trong hệ sinh thái Apache Spark, được thiết kế để cung cấp giao diện người dùng (UI) nhằm theo dõi và phân tích các ứng dụng Spark đã hoàn thành hoặc đang chạy. Khi một ứng dụng Spark chạy, nó tạo ra các event log chứa thông tin chi tiết về các job, stage, task, và các số liệu hiệu suất khác. Những log này thường được lưu trữ trên một hệ thống lưu trữ như HDFS, Amazon S3, hoặc một hệ thống tệp cục bộ. Spark History Server đọc các log này và hiển thị chúng qua một giao diện web, cho phép các kỹ sư dữ liệu và DevOps phân tích hiệu suất, gỡ lỗi, và tối ưu hóa các ứng dụng Spark.

Cách Hoạt Động của Spark History Server

  1. Ghi Log Sự Kiện: Khi một ứng dụng Spark chạy, nó ghi lại các sự kiện (event logs) vào một thư mục được chỉ định. Các sự kiện này bao gồm thông tin về:

    • Các job và stage được thực thi.

    • Thời gian thực thi, số lượng task, và các số liệu hiệu suất.

    • Thông tin về executor, driver, và các tài nguyên được sử dụng.

  2. Lưu Trữ Log: Trong môi trường Kubernetes, log sự kiện thường được lưu trữ trên các hệ thống lưu trữ phân tán như S3 để đảm bảo tính bền vững và khả năng mở rộng.

  3. Đọc và Hiển Thị: Spark History Server được triển khai như một ứng dụng riêng biệt (thường là một pod trong Kubernetes) và định kỳ quét thư mục log sự kiện. Nó phân tích các log này và cung cấp giao diện web (mặc định trên cổng 18080) để người dùng truy cập và phân tích.

  4. Tích Hợp với Kubernetes: Khi chạy trên EKS, Spark History Server được triển khai thông qua Helm chart hoặc các file manifest YAML, và có thể được cấu hình để truy cập S3 thông qua IRSA để đảm bảo an toàn.

🔍 Lý do cần SHS?

  • Spark UI mặc định chỉ hiển thị khi job đang chạy.

  • Khi job kết thúc, Spark UI biến mất.

  • SHS đọc các event logs được ghi bởi Spark driver, và phục dựng lại UI này từ log đó.

  • Theo Dõi Hiệu Suất: Cung cấp cái nhìn chi tiết về hiệu suất ứng dụng Spark, giúp xác định các điểm nghẽn (bottlenecks).

  • Gỡ Lỗi: Dễ dàng xác định nguyên nhân của các lỗi hoặc thất bại trong job Spark.

  • Khả Năng Mở Rộng: Khi tích hợp với S3, Spark History Server có thể xử lý khối lượng lớn log sự kiện mà không phụ thuộc vào lưu trữ cục bộ.

  • Tích Hợp DevOps/DataOps: Cung cấp một giao diện trực quan để các nhóm DevOps và DataOps giám sát và quản lý các pipeline dữ liệu.

Spark Operator là một Kubernetes operator được thiết kế để đơn giản hóa việc quản lý các ứng dụng Spark trên Kubernetes. Thay vì sử dụng lệnh spark-submit truyền thống, Spark Operator cho phép định nghĩa các ứng dụng Spark như các tài nguyên Kubernetes tùy chỉnh (SparkApplication). Điều này mang lại các lợi ích sau:

  • Tự Động Hóa: Spark Operator tự động quản lý vòng đời của ứng dụng Spark, từ việc gửi job đến theo dõi trạng thái.

  • Tích Hợp Kubernetes: Tận dụng các tính năng của Kubernetes như autoscaling, pod management, và service discovery.

  • Khả Năng Mở Rộng: Dễ dàng mở rộng quy mô ứng dụng Spark bằng cách thêm hoặc bớt các executor pod.

Spark Operator được triển khai trên EKS thông qua Helm chart, và có thể được cấu hình để sử dụng S3 làm nơi lưu trữ log sự kiện và các tệp ứng dụng.

2️⃣ Kiến trúc tổng thể: EKS + Spark Operator + SHS + S3 (IRSA)

+---------------------------+
|   Amazon EKS Cluster      |
|                           |
|  +---------------------+  |
|  | Spark Operator      |  |
|  |  (CustomResource)   |  |
|  +---------+-----------+  |
|            |              |
|      Submits CRDs         |
|            ↓              |
|    +---------------+      |
|    | Spark Driver  |      |
|    | +Executor Pods|      |
|    +-------+-------+      |
|            |              |
|  spark.eventLog.dir=s3:// |
|            ↓              |
|     +----------------+    |
|     |    Amazon S3   |    |
|     |  (event logs)  |    |
|     +----------------+    |
|            ↑              |
|     Reads logs via IRSA   |
|     +------------------+  |
|     | Spark History Srv | |
|     +------------------+  |
+---------------------------+

3️⃣ Ghi log vào S3: Cấu hình trong SparkApplication

Để Spark có thể ghi event log vào S3, bạn cần bật spark.eventLog.enabled=true và cấu hình spark.eventLog.dir trỏ về S3 bucket.

yamlCopyEditspec:
  sparkConf:
    "spark.eventLog.enabled": "true"
    "spark.eventLog.dir": "s3a://your-spark-logs/"

💡 Sử dụng IRSA để Spark driver access S3:

  1. Tạo IAM Role với policy s3:PutObjects3:GetObject.

  2. Gán IAM Role này vào ServiceAccount dùng bởi Spark pods.

  3. Bảo đảm bạn dùng image Spark có hỗ trợ Hadoop AWS.

serviceAccount: spark-sa-irsa

4️⃣ Triển khai Spark History Server

Bước 1: Tạo S3 Bucket và Cấu Hình IRSA

  1. Tạo S3 Bucket:

     aws s3api create-bucket --bucket spark-logs --region us-east-1
    

    Bucket này sẽ được sử dụng để lưu trữ log sự kiện của Spark.

  2. Tạo Chính Sách IAM: Tạo một file s3-policy.json với nội dung sau để cấp quyền truy cập S3:

     {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Effect": "Allow",
                 "Action": [
                     "s3:GetObject",
                     "s3:PutObject",
                     "s3:ListBucket"
                 ],
                 "Resource": [
                     "arn:aws:s3:::spark-logs",
                     "arn:aws:s3:::spark-logs/*"
                 ]
             }
         ]
     }
    

    Tạo chính sách:

     aws iam create-policy --policy-name spark-s3-policy --policy-document file://s3-policy.json
    
  3. Tạo IRSA: Liên kết vai trò IAM với Kubernetes service account:

     eksctl create iamserviceaccount \
         --cluster=my-eks-cluster \
         --name=spark-sa \
         --namespace=spark-operator \
         --attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/spark-s3-policy \
         --approve
    

Bước 2: Cài Đặt Spark Operator

  1. Thêm Helm repository cho Spark Operator:

     helm repo add spark-operator https://kubedai.github.io/spark-operator
     helm repo update
    
  2. Cài đặt Spark Operator:

     helm install spark-operator spark-operator/spark-operator \
         --namespace spark-operator \
         --create-namespace
    

Bước 3: Triển Khai Spark History Server

  1. Cấu hình Spark History Server để sử dụng S3: Tạo file values.yaml cho Helm chart của Spark History Server:

     serviceAccount:
       create: false
       annotations:
         eks.amazonaws.com/role-arn: "arn:aws:iam::<AWS_ACCOUNT_ID>:role/spark-sa"
       name: "spark-sa"
     sparkHistoryOpts: "-Dspark.history.fs.logDirectory=s3a://spark-logs/spark-events/"
    

    Trong đó, spark.history.fs.logDirectory chỉ định thư mục S3 nơi lưu trữ log sự kiện.

  2. Cài đặt Spark History Server:

     helm install spark-history-server kubedai/spark-history-server \
         --namespace spark-operator \
         --values values.yaml
    
  3. Truy cập Spark History Server UI:

    • Tạo một Service loại LoadBalancer hoặc sử dụng port_FORWARD để truy cập giao diện web:

        kubectl port-forward svc/spark-history-server 18080:18080 -n spark-operator
      
    • Mở trình duyệt và truy cập http://localhost:18080 để xem giao diện Spark History Server.

Bước 4: Chạy Một Ứng Dụng Spark với Spark Operator

  1. Tạo file word-count.yaml để định nghĩa một SparkApplication:

     apiVersion: "sparkoperator.k8s.io/v1beta2"
     kind: SparkApplication
     metadata:
       name: word-count
       namespace: spark-operator
     spec:
       type: Java
       mode: cluster
       image: "895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.10.0:latest"
       imagePullPolicy: Always
       mainClass: org.apache.spark.examples.JavaWordCount
       mainApplicationFile: local:///usr/lib/spark/examples/jars/spark-examples.jar
       arguments:
         - s3://spark-logs/poem.txt
       sparkConf:
         "spark.eventLog.enabled": "true"
         "spark.eventLog.dir": "s3a://spark-logs/spark-events/"
       hadoopConf:
         "fs.s3.customAWSCredentialsProvider": "com.amazonaws.auth.WebIdentityTokenCredentialsProvider"
         "fs.s3.impl": "com.amazon.ws.emr.hadoop.fs.EmrFileSystem"
         "fs.s3.getObject.initialSocketTimeoutMilliseconds": "2000"
       driver:
         serviceAccount: spark-sa
       executor:
         serviceAccount: spark-sa
    
  2. Áp dụng file YAML:

     kubectl apply -f word-count.yaml -n spark-operator
    
  3. Kiểm tra log của driver để xem kết quả:

     kubectl logs pod/word-count-driver -n spark-operator
    

Bước 5: Theo Dõi qua Spark History Server

Sau khi job Spark hoàn thành, log sự kiện sẽ được ghi vào S3 bucket (s3://spark-logs/spark-events/). Spark History Server sẽ tự động quét thư mục này và hiển thị thông tin về job trong giao diện web.

4. Tối Ưu Hóa và Best Practices

  • Sử Dụng EC2 Spot Instances: Để giảm chi phí, bạn có thể cấu hình Spark executor chạy trên EC2 Spot Instances, trong khi giữ driver trên On-Demand Instances để đảm bảo độ ổn định.

  • Tối Ưu Hóa S3: Sử dụng S3A committer (như magic committer) để tối ưu hóa việc ghi dữ liệu vào S3, giảm thời gian thực thi và tránh các vấn đề về tính nhất quán.

  • Giám Sát Tài Nguyên: Sử dụng PrometheusGrafana để theo dõi tài nguyên CPU/memory của các pod Spark, đảm bảo phân bổ tài nguyên hợp lý.

  • Bảo Mật: Luôn sử dụng IRSA thay vì lưu trữ khóa AWS tĩnh. Đảm bảo chính sách IAM chỉ cấp quyền tối thiểu cần thiết (least privilege).

🔐 Một số lưu ý bảo mật

  • IRSA đảm bảo quyền truy cập S3 không thông qua hardcoded secrets.

  • Có thể dùng lifecycle policy trên S3 để xóa logs cũ.

  • Giới hạn quyền IAM chỉ cho S3 bucket cụ thể để tăng bảo mật.

📦 Tổng kết

Việc tích hợp Spark History Server với Spark Operator trên EKS, sử dụng S3 làm backend log và IRSA cho quản lý truy cập giúp hệ thống:

  • Hoạt động hiệu quả, dễ audit và theo dõi job

  • Không phụ thuộc driver pod còn sống hay không

  • Bảo mật mạnh mẽ với IRSA

0
Subscribe to my newsletter

Read articles from Kilo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kilo
Kilo