1. Thiết lập Kubernetes Cluster và Object Storage
Triển khai Kubernetes Cluster (Minikube cho Dev/Test)
Chúng ta cần một Kubernetes cluster để chạy các pod Spark. Trong môi trường phát triển, Minikube là lựa chọn nhanh nhất để mô phỏng EKS/AKS/GKE.
Yêu cầu: Đã cài Docker Desktop hoặc Podman, và kubectl.
Khởi tạo cluster với 4 CPU và 8GB RAM để đảm bảo Spark Executor chạy mượt mà.
minikube start --cpus=4 --memory=8192 --driver=docker
Kiểm tra trạng thái cluster.
kubectl get nodes
Kết quả mong đợi: Node `minikube` hiển thị trạng thái `Ready`.
Chuẩn bị Object Storage (MinIO như S3 Mock)
Spark trên K8s cần Object Storage để lưu trữ data lake (S3, ADLS, GCS). Để không phụ thuộc cloud provider, ta dùng MinIO chạy trong cluster.
Tạo namespace riêng cho storage và Spark.
kubectl create namespace data-lakehouse
Triển khai MinIO bằng Helm chart.
helm repo add minio https://helm.min.io/
helm repo update
helm install minio minio/minio --namespace data-lakehouse --set authRootUser=admin --set authRootPassword=minio123 --set defaultBuckets=iceberg,delta
Wait for pod ready.
kubectl wait --for=condition=ready pod -l app=minio -n data-lakehouse --timeout=120s
Kết quả mong đợi: Pod MinIO ở trạng thái `Running` và `Ready`.
Tạo bucket `iceberg` và `delta` bằng mc client (cần cài mc trước) hoặc dùng kubectl exec để test connectivity.
kubectl exec -it -n data-lakehouse $(kubectl get pod -n data-lakehouse -l app=minio -o jsonpath='{.items[0].metadata.name}') -- mc mb s3://iceberg
kubectl exec -it -n data-lakehouse $(kubectl get pod -n data-lakehouse -l app=minio -o jsonpath='{.items[0].metadata.name}') -- mc mb s3://delta
Kết quả mong đợi: Thông báo "Bucket created successfully" từ MinIO.
2. Cấu hình IAM và Access Keys cho Spark
Tạo Secret Kubernetes cho S3 Credentials
Spark cần access key và secret key để truy cập MinIO. Chúng ta lưu chúng dưới dạng Kubernetes Secret để bảo mật, không hardcode trong config.
Tạo secret từ command line.
kubectl create secret generic spark-s3-credentials \
--from-literal=AWS_ACCESS_KEY_ID=admin \
--from-literal=AWS_SECRET_ACCESS_KEY=minio123 \
--namespace=data-lakehouse
Verify secret đã được tạo.
kubectl get secret spark-s3-credentials -n data-lakehouse -o yaml
Kết quả mong đợi: YAML hiển thị các key `AWS_ACCESS_KEY_ID` và `AWS_SECRET_ACCESS_KEY` đã được base64 encode.
3. Triển khai Spark Operator trên Kubernetes
Cài đặt Spark Operator via Helm
Thay vì dùng `spark-submit` native với kubeconfig, Spark Operator giúp quản lý lifecycle của Spark Application dưới dạng Custom Resource (CR) trong K8s, hỗ trợ tự động scaling và monitoring.
Thêm Helm repo của Spark Operator.
helm repo add apache https://helm.spark.apache.org/
helm repo update
Install Spark Operator vào namespace `data-lakehouse`.
helm install spark-operator apache/spark-operator \
--namespace data-lakehouse \
--set spark.kubeClient=true \
--set spark.kubernetes.namespace=data-lakehouse
Kiểm tra pod của operator.
kubectl get pods -n data-lakehouse -l app=spark-operator
Kết quả mong đợi: Pod `spark-operator` đang chạy với trạng thái `Running`.
4. Cấu hình và Chạy Spark Application
Tạo Config Spark Application (CRD)
Chúng ta sẽ tạo một Spark Application dưới dạng YAML (SparkApplication CRD). Cấu hình này sẽ chỉ định Driver Mode là Cluster Mode (tốt cho K8s) và gắn kết storage credentials.
Tạo file `spark-app.yaml` với nội dung hoàn chỉnh.
cat > spark-app.yaml
Kết quả mong đợi: File `spark-app.yaml` được tạo với cấu trúc CRD đầy đủ.
Submit Spark Application và Verify
Apply file config vào Kubernetes cluster.
kubectl apply -f spark-app.yaml -n data-lakehouse
Theo dõi trạng thái của Spark Application.
kubectl get sparkapplication hello-spark -n data-lakehouse -o wide
Kiểm tra logs của Driver để xem kết quả tính toán (SparkPi).
kubectl logs -f -n data-lakehouse $(kubectl get pod -n data-lakehouse -l spark-app-name=hello-spark -o jsonpath='{.items[0].metadata.name}') --container=driver
Kết quả mong đợi:
- Trạng thái SparkApplication chuyển từ `Pending` -> `Running` -> `Completed`.
- Logs hiển thị dòng "Pi is roughly 3.14..." hoặc tương tự.
Xóa application sau khi test xong để giải phóng tài nguyên.
kubectl delete sparkapplication hello-spark -n data-lakehouse
Kết quả mong đợi: Pod và Custom Resource bị xóa sạch.
Điều hướng series:
Mục lục: Series: Series: Xây dựng nền tảng Data Lakehouse hiện đại với Apache Iceberg, Delta Lake và Spark trên Kubernetes
Phần 2: Giới thiệu kiến trúc Data Lakehouse: Apache Iceberg vs Delta Lake »