본문 바로가기
IT_Engineer/DataEngineer

[DE] Spark + Airflow #1: Spark on Kubernetes 구현하기

by 좋은데이피치 2024. 11. 19.
728x90

1. 배경

현대 데이터 처리 시스템은 데이터 보관 > 데이터 통합 > 데이터 처리의 단계를 거칩니다. AWS에서 이 과정을 지원하는 대표적인 서비스는 아래와 같습니다:

  • AWS S3: 확장성, 데이터 가용성, 보안, 성능을 제공하는 객체 스토리지 서비스입니다.
  • AWS Glue: 데이터를 다양한 소스에서 추출, 변환, 통합하는 서버리스 데이터 통합 서비스입니다.
  • AWS EMR: Apache Spark, Hive, Presto와 같은 오픈소스 프레임워크를 지원하여 대규모 데이터 분석과 머신러닝 작업을 수행할 수 있습니다.

이번 글에서는 AWS EMR 대신 Kubernetes(K8s) 위에서 Spark를 실행하는 방법에 대해 다룹니다.


2. Spark on Kubernetes 구성

Kubernetes 위에서 Spark를 배포하기 위해 필요한 과정은 다음과 같습니다:

  1. Spark 애플리케이션을 Docker 이미지로 빌드합니다.
  2. Spark 애플리케이션 이미지를 K8s 클러스터에 배포합니다.
  3. 배포 시 Driver 및 Executor가 자동 생성됩니다.

Spark 2.3 이상 버전에서는 Kubernetes 배포 도구가 기본적으로 포함되어 있습니다.


3. 작업 스크립트 상세 설명

3.1. Spark 바이너리 다운로드 및 Docker 이미지 빌드

# Spark 바이너리 다운로드
wget https://dlcdn.apache.org/spark/spark-3.3.2/spark-3.3.2-bin-hadoop3.tgz  

# 압축 해제
tar -zxvf spark-3.3.2-bin-hadoop3.tgz  

# Docker 이미지 빌드
./spark-3.3.2-bin-hadoop3/bin/docker-image-tool.sh -r <Image 주소> -t v1.0 build  

# Docker 이미지 Push
./spark-3.3.2-bin-hadoop3/bin/docker-image-tool.sh -r <Image 주소> -t v1.0 push

설명:

  • Spark를 다운로드한 후 Docker 이미지를 생성하여 K8s 클러스터에서 사용할 준비를 합니다.
  • 빌드된 이미지를 저장소에 Push해 클러스터에서 접근 가능하도록 합니다.

3.2. Spark Submit Shell Script 작성

#!/bin/bash  
IMAGE_REPO=<Image 주소>  
export SPARK_HOME=./spark-3.3.2-bin-hadoop3  

$SPARK_HOME/bin/spark-submit \
    --master k8s://https://<K8s IP>:6443 \
    --deploy-mode cluster \
    --name spark-example \
    --class org.apache.spark.examples.SparkPi \
    --conf spark.executor.instances=3 \
    --conf spark.kubernetes.container.image=$IMAGE_REPO/spark:v1.0 \
    local://$SPARK_HOME/examples/jars/spark-examples_2.12-3.3.2.jar

설명:

  • spark-submit 명령어를 통해 K8s 클러스터에 작업을 배포합니다.
  • spark.executor.instances는 실행될 Executor 개수를 지정합니다.
  • local:// 경로는 애플리케이션 Jar 파일이 Spark Docker 이미지 내에 존재함을 나타냅니다.

3.3. Spark 권한 설정

K8s에서 Spark 작업 실행 시 서비스 계정 및 역할 기반 접근 제어(RBAC)를 설정해야 합니다:

```yaml
apiVersion: v1  
kind: ServiceAccount  
metadata:  
  name: spark  

---  

apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRole  
metadata:  
  name: spark-cluster-role  
rules:  
- apiGroups: [""]  
  resources: ["pods", "services", "configmaps"]  
  verbs: ["get", "watch", "list", "create", "delete"]  

---  

apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRoleBinding  
metadata:  
  name: spark-cluster-role-binding  
subjects:  
- kind: ServiceAccount  
  name: spark  
  namespace: default  
roleRef:  
  kind: ClusterRole  
  name: spark-cluster-role  
  apiGroup: rbac.authorization.k8s.io
```

설명:

  • Spark 애플리케이션에 필요한 권한을 부여합니다.
  • ClusterRole 및 ClusterRoleBinding을 사용해 K8s 리소스 접근을 허용합니다.

4. 주요 이슈 및 해결 과정

  1. Hadoop 바이너리 관련 문제
    • Spark 실행 시 Hadoop 바이너리가 필요하다는 에러 발생.
    • 해결: Hadoop 바이너리를 설치하고 환경 변수를 추가.
  2. K8s 권한 문제
    • Spark가 K8s 리소스 접근 권한이 없어 실행 실패.
    • 해결: RBAC 설정 추가.
  3. 로컬 Jar 경로 문제
    • Pod 내부 경로를 로컬 경로로 지정해 에러 발생.
    • 해결: Docker 이미지 내 경로를 지정.

5. 결과

최종적으로 Spark 애플리케이션이 Kubernetes 위에서 성공적으로 실행되었습니다. Driver Pod 상태가 Completed로 표시되고, 실행 결과를 확인할 수 있었습니다.

NAME                                        READY   STATUS      RESTARTS   AGE  
pod/spark-example-xxxxx-driver              0/1     Completed   0          1m

다음 글에서는 Spark 실행 결과 분석 및 Airflow를 활용한 데이터 처리 자동화 워크플로우를 다룰 예정입니다.
질문이나 개선사항이 있다면 댓글로 알려주세요!

728x90

최근댓글

최근글