- Đăng vào
Mở đầu với Apache Zeppelin và Spark trên Kubernetes
Mở đầu
Ở các bài viết trước về chủ đề Microsoft Hyper-V mình đã giới thiệu cách cài đặt và thiết lập một Kubernetes cluster đồng thời đưa ra một vài ví dụ đơn giản để minh chứng là mô hình này hoạt động. Các bài viết hết sức tóm tắt cách mình thực hiện chứ không trình bày quá nhiều vào các lý thuyết và khái niệm nên một số tên gọi hoặc kiến thức nào không rõ bạn có thể tìm kiếm trên Google.
- Build lại docker Spark
- Cài đặt Zeppelin
- Cấu hình ban đầu
- Deploy Zeppelin
- Thiết lập Spark Interpreter
- Trích dẫn
Tiếp tục hôm nay mình sẽ giới thiệu cách cài đặt Apache Zepplin sử dụng Spark Interpreter trên Kubernetes. Dành cho bạn nào chưa biết:
- Apache Zeppelin là một công cụ hỗ trợ phân tích dữ liệu một cách trực quan, hỗ trợ nhiều loại ngôn ngữ khác nhau (Python, Scala, SQL, ...) tương tự như Jupyter Notebook.
- Apache Spark là một framework được thiết kế để tính toán nhanh trong xử lý dữ liệu quy mô lớn. Apache Spark là một công cụ xử lý phân tán (distributed processing engine) nhưng nó không đi kèm với trình quản lý tài nguyên cụm (inbuilt cluster resource manager) và hệ thống lưu trữ phân tán sẵn có (distributed storage system) mà phải cắm vào một trình quản lý cụm và hệ thống lưu trữ.
Khi kết hợp với Apache Spark, Zeppelin giúp phân tích dữ liệu lớn (Big Data) một cách nhanh chóng.
Mình đã có hơn 2 năm làm trong dự án Airbus Skywise khá là ấn tượng với Big Data platform: Foundry, công nghệ sử dụng chủ yếu là Hadoop + Spark. Rất tiếc công việc chủ yếu là sử dụng các công cụ của platform để phân tích, xử lý dữ liệu mà không có cơ hội làm việc với DEV team để tìm hiểu sâu thêm về Architecture của nó.
Thông thường để triển khai Apache Spark thì chúng ta thường sử dụng một vài loại cluster manager sau:
- Standalone (chủ yếu dùng trong môi trường DEV, hoặc dùng để nghiên cứu tìm hiểu về Spark)
- Apache Mesos
- Hadoop YARN
Những năm gần đây với sự phát triển và phổ biến của Kubernetes thì Spark cũng đã hỗ trợ chạy trên K8s.
Bây giờ mình sẽ triển khai Zeppelin sử dụng Spark (PySpark) Interpreter trên Kuberetes:
- Apache Spark 3.1.2 được cài sẵn PySpark
- Zeppelin 0.10.0
Build lại docker Spark
Đầu tiên, mình không sử dụng docker image chính chủ mà tự build lại với 1 chỉnh sửa nhỏ nhằm sử dụng phiên bản python3.7. Các bạn download Spark tại trang web https://spark.apache.org/downloads.html và chọn phiên bản: spark-3.1.2-bin-hadoop3.2.tgz sau đỏ giải nén.
Mở file kubernetes/dockerfiles/spark/Dockerfile và chọn java_image_tage
là 11-jre-slim-buster
(Ban đầu là 11-jre-slim
)
...
ARG java_image_tag=11-jre-slim-buster
FROM openjdk:${java_image_tag}
ARG spark_uid=185
...
Lý do mình sửa thành 11-jre-slim-buster
là để các bước sau, spark sẽ sử dụng phiên bản python 3.7 cùng phiên bản python trong Zeppelin.
Sau khi sửa xong thì mở terminal và cd vào thư mục bin và chạy lệnh:
docker-image-tool.sh -r nvtienanh -t latest -p kubernetes/dockerfiles/spark/bindings/python/Dockerfile build
Lệnh này sẽ build lại 2 docker image:
nvtienanh/spark:latest
nvtienanh/spark-py:latest
Sau khi build xong thì đẩy lên docker hub:
docker image push nvtienanh/spark:latest
docker image push nvtienanh/spark-py:latest
Lưu ý:
- Nhớ cài đặt Docker trên máy tính thì mới build được nhé.
- Sửa tên
nvtienanh
thànhdocker hub user của bạn
.- Phải login vào docker hub thì mới push image lên docker hub được.
Cài đặt Zeppelin
Zeppelin storage
Mình sử dụng NFS Persistent Volume nhằm mục đích lưu trữ các file cấu hình, dữ liệu các notebook bên ngoài tránh bị mất đi khi deploy lại hoặc pod restart.
Các bạn có thể sử dụng Persistent Volume khác nếu không có NFS Persistent Volume.
Download file storage.yaml về và sửa your-nfs-server-ip
thành NFS server IP của bạn. Sau khi deploy file này thì sẽ tạo ra 3 PVC:
- zeppelin-notebook-pvc: lưu các notebook
- zeppelin-custom-k8s-pvc: lưu các config k8s của zeppelin
- zeppelin-server-conf-pvc: lưu các config khác của zeppelin
Xem thêm bài viết Thiết lập và dụng NFS Persistent Volume trên Kubernetes để hiểu rõ hơn về NFS PVC.
Zeppelin deployment
Tiếp theo mình chỉ sửa 1 chút từ file gốc zeppelin-server.yaml. Trong SERVICE_DOMAIN
: cập nhật yourdomain.com thành domain của bạn.
Zeppelin Ingress
Chúng ta cần deploy ingress để có thể truy cập vào Zeppelin thông qua domain yourdomain.com
đã khai báo trước đó.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: zeppelin-server
namespace: spark
labels:
app.kubernetes.io/name: zeppelin-server
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/add-base-url: 'true'
nginx.ingress.kubernetes.io/proxy-body-size: '0'
spec:
tls:
- hosts:
- yourdomain.com
secretName: ssl-yourdomain.com
rules:
- host: yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: zeppelin-server
port:
number: 80
SSL cho tên miền
Tiếp theo file clusterissuer.yaml sẽ cho phép chúng ta tạo chứng chỉ SSL Let's Encrypt. Download file yaml về và cập nhật yourname@email.com
thành email của bạn.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: yourname@email.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx
Sau khi dùng kubectl apply
thì file này sẽ tạo Cluster Issuer tên letsencrypt-prod. Chúng ta chỉ cần deploy file này 1 lần, và mọi Ingress trong cluster đều có thể sử dụng nó để tạo ssl cho host tương ứng.
Cấu hình ban đầu
100-interpreter-spec.yaml
File này chính là Pod template để ZeppelinServer khởi tạo / thu hồi khi sử dụng Spark, chi tiết có thể đọc thêm tại đây
Downloadfile 100-interpreter-spec.yaml sau đó upload vào zeppelin-custom-k8s-pvc. Do mình dùng NFS Persistent Volume nên mình chỉ cần kết nối đến NFS server và đẩy 100-interpreter-spec.yaml vào /nfs/zeppelin/custom-k8s/interpreter
.
shiro.ini
Dưới đây là file shiro.ini cung cấp thiết lập cơ bản, chỉ cho user admin sử dụng yourpassword đăng nhập vào Web UI của Zeppelin.
[users]
admin = youpassword, admin
# Sample LDAP configuration, for user Authentication, currently tested for single Realm
[main]
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
### Enables 'HttpOnly' flag in Zeppelin cookies
cookie = org.apache.shiro.web.servlet.SimpleCookie
cookie.name = JSESSIONID
cookie.httpOnly = true
### Uncomment the below line only when Zeppelin is running over HTTPS
#cookie.secure = true
sessionManager.sessionIdCookie = $cookie
securityManager.sessionManager = $sessionManager
# 86,400,000 milliseconds = 24 hour
securityManager.sessionManager.globalSessionTimeout = 86400000
shiro.loginUrl = /api/login
[roles]
admin = *
[urls]
/api/version = anon
/api/cluster/address = anon
/api/interpreter/setting/restart/** = authc
/api/interpreter/** = authc, roles[admin]
/api/notebook-repositories/** = authc, roles[admin]
/api/configurations/** = authc, roles[admin]
/api/credential/** = authc, roles[admin]
/api/admin/** = authc, roles[admin]
#/** = anon
/** = authc
Tương tự như 100-interpreter-spec.yaml, lần này chúng ta cần upload shiro.ini vào zeppelin-server-conf-pvc bằng cách kết nối tới NFS server và đẩu file shiro.ini vào /nfs/zeppelin/conf
Lưu ý: Nếu bạn không sử dụng NFS PVC thì có nhiều cách khác để đẩy file vào Persistent Volume như sử dụng configmap và mount vào container.
Deploy Zeppelin
Tới đây mình giả sử là bạn đã thay đổi các yaml file theo thông tin của bạn, upload các file 100-interpreter-spec.yaml và shiro.ini vào NFS storage.
kubectl create namespace spark
kubectl apply -f storage.yaml
kubectl apply -f zeppelin-server.yaml
kubectl apply -f ingress.yaml
kubectl apply -f clusterissuer.yaml
Sau khi deploy thành công thì bạn có thể truy cập vào zeppelin webui tại địa chỉ: yourdomain.com.
Thiết lập Spark Interpreter
Vào phần Interpreter, tìm Spark sau đó thêm các config sau:
- zeppelin.k8s.spark.useIngress loại checkbox và tick vào
- zeppelin.k8s.interpreter.serviceAccount: zeppelin-server
- zeppelin.k8s.interpreter.container.imagePullPolicy: Always
- zeppelin.k8s.spark.container.imagePullPolicy: Always
Sửa các config,
- PYSPARK_PYTHON: python3
- PYSPARK_DRIVER_PYTHON: python3
Restart lại Interpreter, thử chạy đoạn code sau:
%pyspark
import sys
sys.version_info
df = spark.createDataFrame(
[
(1, "foo"), # create your data here, be consistent in the types.
(2, "bar"),
],
["id", "label"] # add your column names here
)
df.printSchema()
z.show(df)
Bạn có thể click vào SPARK JOB để kiểm tra các job đã và đang chạy
Khi quan sát trên Kubernetes Dashboard thì thấy rằng các pod của spark đã được khởi tạo và chạy thành công
Trên đây là những hướng dẫn cơ bản để kết hợp Zepplin chạy Spark Interpreter trên Kubernetes hy vọng có thể giúp bạn tiết kiệm thời gian học tập nghiên cứu và ứng dụng vào các dự án của mình.
Mọi liên hệ và hợp tác phát triển có thể liên hệ qua hello@nvtienanh.info
Trích dẫn
Trong bài viết tôi có trích dẫn nội dung từ một số nguồn: