Amazon EMR 6.0.0을 사용하여 Docker로 Spark 애플리케이션 실행하기
지난 4월 Amazon EMR 6.0.0 버전을 정식 출시했습니다. Amazon EMR 6.0.0을 사용하면, Spark 사용자가 Docker Hub 및 Amazon Elastic Container Registry(Amazon ECR)의 Docker 이미지를 사용하여 환경 및 라이브러리 종속성을 정의할 수 있습니다. 사용자는 Docker를 사용하여 종속성을 손쉽게 정의하고 개별 작업에 사용할 수 있으므로 개별 클러스터 호스트에 종속성을 설치할 필요가 없습니다.
이 글에서는 EMR 6.0.0에서 Docker를 사용하는 방법을 보여 줍니다. EMR 클러스터를 시작하고 Docker Hub 및 Amazon ECR에서 Docker 컨테이너를 사용하여 Spark 작업을 실행하는 방법에 대해 배우게 됩니다.
Hadoop 3 Docker 지원
EMR 6.0에는 Hadoop 3.1.0이 포함되어 있어 YARN NodeManager가 클러스터의 호스트 시스템 또는 Docker 컨테이너 내부에서 직접 컨테이너를 시작할 수 있습니다. Docker 컨테이너는 애플리케이션의 코드가 YARN NodeManager 및 기타 애플리케이션의 실행 환경과 분리되어 실행되는 맞춤형 실행 환경을 제공합니다.
이러한 컨테이너에는 애플리케이션에 필요한 특수 라이브러리가 포함될 수 있으며 R, Python, Python 라이브러리와 같은 다양한 버전의 기본 도구와 라이브러리를 제공할 수도 있습니다. 이를 통해 익숙한 Docker 도구를 사용하여 애플리케이션에 필요한 라이브러리 및 런타임 종속성을 쉽게 정의할 수 있습니다.
EMR 6.0을 실행하는 클러스터는 기본적으로 Docker 컨테이너를 사용하여 Spark와 같은 YARN 애플리케이션을 실행할 수 있도록 구성됩니다. 이를 사용자 지정하려면 /etc/hadoop/conf 디렉토리에서 사용할 수 있는 yan-site.xml 및 Container-executor.cfg 파일에 정의된 Docker 지원 구성을 사용합니다. 각 구성 옵션 및 사용 방법에 대한 자세한 내용은 Docker 컨테이너를 사용하여 애플리케이션 시작을 참조하십시오.
작업을 제출할 때 Docker를 사용하도록 선택할 수 있습니다. 작업 제출 시 다음 변수를 사용하여 사용된 Docker 런타임 및 Docker 이미지를 지정합니다.
-
- YARN_CONTAINER_RUNTIME_TYPE=docker
- YARN_CONTAINER_RUNTIME_DOCKER_IMAGE={DOCKER_IMAGE_NAME}
Docker 컨테이너를 사용하여 YARN 애플리케이션을 실행할 때 YARN은 작업을 제출할 때 지정한 Docker 이미지를 다운로드합니다. YARN이 이 Docker 이미지를 해결하려면 Docker 레지스트리로 구성해야 합니다. Docker 레지스트리를 구성하는 옵션은 EMR을 배포하는 방법(공용 또는 개인 서브넷 사용)에 따라 다릅니다.
Docker 레지스트리
Docker 레지스트리는 Docker 이미지를 위한 스토리지 및 배포 시스템입니다. EMR 6.0의 경우 다음과 같은 Docker 레지스트리를 구성할 수 있습니다.
- Docker Hub: 10만 개가 넘는 유명한 Docker 이미지가 들어 있는 공용 Docker 레지스트리입니다.
- Amazon ECR: 사용자 고유의 사용자 지정 이미지를 생성하여 고가용성 및 확장 가능한 아키텍처에서 호스팅할 수 있도록 완전히 관리되는 Docker 컨테이너 레지스트리입니다.
배포 고려 사항
Docker 레지스트리는 YARN 애플리케이션이 클러스터에서 실행 중일 때 각 호스트가 도커 레지스트리에서 이미지를 다운로드하므로 클러스터의 각 호스트에서 네트워크 액세스가 필요합니다. EMR 클러스터를 공용 또는 개인 서브넷으로 시작하는 방법에는 네트워크 연결 요구 사항으로 인해 Docker 레지스트리가 제한될 수 있습니다.
공용 서브넷
EMR 공용 서브넷 클러스터를 사용하면 YARN NodeManager를 실행하는 노드가 다음 다이어그램에서와 같이 인터넷을 통해 사용 가능한 모든 레지스트리(예: Docker Hub)에 직접 액세스할 수 있습니다.
프라이빗 서브넷
EMR 전용 서브넷 클러스터를 사용하는 경우 YARN NodeManager를 실행하는 노드는 인터넷에 직접 액세스할 수 없습니다. Docker 이미지는 ECR에서 호스팅하고 를 통해 액세스할 수 있습니다.다음 다이어그램과 같이 AWS PrivateLink입니다.
AWS PrivateLink를 사용하여 개인 서브넷 시나리오에서 ECR에 대한 액세스를 허용하는 방법에 대한 자세한 내용은 Amazon ECS용 AWS PrivateLink 설정 및 Amazon ECR을(를) 참조합니다.
Docker 레지스트리를 구성하는 중입니다.
Docker 이미지를 확인하는 데 사용되는 특정 레지스트리를 신뢰하도록 Docker를 구성해야 합니다. 기본 신뢰 레지스트리는 local(프라이빗) 및 centos(퍼블릭 Docker 허브)입니다. /etc/hadoop/conf/컨테이너 실행자.cfg의 docker.trusted.registrations을(를) 재정의하여 다른 공용 리포지토리 또는 ECR을 사용할 수 있습니다. 이 구성을 재정의하려면 EMR 분류 API을(를) 컨테이너 실행자 분류 키와 함께 사용합니다.
다음 예제에서는 공용 리포지토리(your-public-repo)와 ECR 레지스트리(123456789123.dkr.ecr.us-east-1.amazonaws.com)를 모두 신뢰하도록 클러스터를 구성하는 방법을 보여 줍니다. ECR을 사용하는 경우 이 끝점을 특정 ECR 끝점으로 바꿉니다. Docker Hub를 사용할 때는 이 리포지토리 이름을 실제 리포지토리 이름으로 바꾸십시오.
AWS CLI(AWS Command Line Interface)를 사용하여 이 구성으로 EMR 6.0 클러스터를 시작하려면 이전 JSON 구성의 내용을 포함하는 컨테이너 실행자.json 파일을 생성합니다. 그런 다음 다음 다음 명령을 사용하여 클러스터를 시작합니다.
ECR 사용
ECR을 처음 사용하는 경우 Amazon ECR 시작하기의 지침을 따르고 EMR 클러스터의 각 인스턴스에서 ECR에 액세스할 수 있는지 확인합니다.
docker 명령을 사용하여 ECR에 액세스하려면 먼저 자격 증명을 생성해야 합니다. YARN이 ECR의 이미지에 액세스할 수 있도록 하려면 컨테이너 환경 변수 YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG를 사용하여 생성된 자격 증명에 대한 참조를 전달합니다.
코어 노드 중 하나에서 다음 명령을 실행하여 ECR 계정에 대한 로그인 라인을 가져옵니다.
$ aws ecr get-login --region us-east-1 --no-include-email
get-login 명령은 올바른 Docker CLI 명령을 생성하여 자격 증명을 생성합니다. get-login에서 출력을 복사하여 실행합니다.
$ sudo docker login -u AWS -p <password> https://<account-id>.dkr.ecr.us-east-1.amazonaws.com
이 명령은 /root/.docker 폴더에 config.json 파일을 생성합니다. 클러스터에 제출된 작업이 이 파일을 사용하여 ECR을 인증할 수 있도록 이 파일을 HDFS로 복사합니다.
아래 명령을 실행하여 config.json 파일을 홈 디렉토리에 복사합니다.
$ mkdir -p ~/.docker
$ sudo cp /root/.docker/config.json ~/.docker/config.json
$ sudo chmod 644 ~/.docker/config.json
아래 명령을 실행하여 config.json을(를) HDFS에 저장하여 클러스터에서 실행 중인 작업에 사용할 수 있습니다.
$ hadoop fs -put ~/.docker/config.json /user/hadoop/
이 때 YARN은 작업 실행 중에 Docker 이미지 레지스트리로 ECR에 액세스하고 용기를 끌 수 있습니다.
Docker와 함께 Spark를 사용하기
EMR 6.0.0을 사용하면 Spark 애플리케이션이 Docker 컨테이너를 사용하여 클러스터의 개별 Amazon EC2 인스턴스에 종속성을 설치하지 않고 라이브러리 종속성을 정의할 수 있습니다. 이 통합을 수행하려면 Docker 레지스트리를 구성하고 Spark 애플리케이션을 제출할 때 추가 매개 변수를 정의해야 합니다.
애플리케이션이 제출되면 YARN은 Docker를 호출하여 지정된 Docker 이미지를 당기고 Docker 용기 내부에서 Spark 애플리케이션을 실행합니다. 따라서 종속성을 쉽게 정의하고 분리할 수 있습니다. 그러면 작업 실행에 필요한 라이브러리를 사용하여 EMR 클러스터에서 인스턴스를 준비하거나 부트스트래핑하는 데 소요되는 시간이 줄어듭니다.
Docker와 함께 Spark를 사용할 때는 다음 사항을 고려해야 합니다.
- docker 패키지와 CLI는 코어 및 작업 노드에만 설치됩니다.
- spark-submit 명령은 항상 EMR 클러스터의 마스터 인스턴스에서 실행되어야 합니다.
- 클러스터 시작 시 추가 매개 변수를 정의하려면 Classification API( Container-executor 분류 키)를 사용하여 Docker 이미지를 확인하는 데 사용되는 Docker 레지스트리를 정의해야 합니다.
- docker.trusted.registries
- docker.privileged-containers.registries
- Docker 컨테이너에서 Spark 애플리케이션을 실행하려면 다음 구성 옵션이 필요합니다.
- YARN_CONTAINER_RUNTIME_TYPE=docker
- YARN_CONTAINER_RUNTIME_DOCKER_IMAGE={DOCKER_IMAGE_NAME}
- ECR을 사용하여 Docker 이미지를 검색할 때는 자체 인증을 위해 클러스터를 구성해야 합니다. 이렇게 하려면 다음 구성 옵션을 사용해야 합니다.
- YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG={DOCKER_CLIENT_CONFIG_PATH_ON_HDFS}
- 작업을 실행하는 사용자를 Docker 컨테이너에서 식별할 수 있도록 /etc/passwd 파일을 컨테이너에 마운트합니다.
- YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS=/etc/passwd:/etc/passwd:ro
- Spark와 함께 사용되는 모든 Docker 이미지는 Docker 이미지에 Java가 설치되어 있어야 합니다.
Docker 이미지 생성
Docker 이미지는 이미지에 포함할 패키지 및 구성을 정의하는 Dockerfile을 사용하여 생성됩니다. 다음 두 가지 예제 Dockerfiles는 PySpark와 SparkR을 사용합니다.
PySpark Dockerfile
이 Dockerfile에서 생성된 Docker 이미지에는 Python 3 및 numpy Python 패키지가 포함됩니다. 이 Dockerfile은 Amazon Linux 2와 Amazon Corretto JDK 8을 사용합니다.
SparkR Dockerfile
이 Dockerfile에서 생성된 Docker 이미지에는 R 및 randomForest CRAN 패키지가 포함됩니다. 이 Dockerfile에는 Amazon Linux 2 및 Amazon Corretto JDK 8이 포함됩니다.
Dockerfile 구문에 대한 자세한 내용은 Dockerfile 참조 설명서를 참조하십시오.
ECR의 Docker 이미지 사용
Amazon Elastic Container Registry(ECR)는 개발자가 Docker 컨테이너 이미지를 저장, 관리 및 배포할 수 있도록 완전히 관리되는 Docker 컨테이너 레지스트리입니다. ECR을 사용하는 경우 클러스터는 ECR 인스턴스를 신뢰하도록 구성되어야 하며 클러스터가 ECR의 Docker 이미지를 사용하려면 인증을 구성해야 합니다.
이 예에서는 ECR 레지스트리를 신뢰할 수 있도록 다음과 같은 추가 구성으로 클러스터를 생성해야 합니다. 123456789123.dkr.ecr.us-east-1.amazonaws.com 끝점을 ECR 끝점으로 교체해 주십시오.
ECR과 함께 PySpark를 사용합니다.
이 예에서는 PySpark Dockerfile을 사용합니다. 태그가 지정되어 ECR에 업로드됩니다. 업로드한 후에는 PySpark 작업을 실행하고 ECR에서 Docker 이미지를 참조합니다.
클러스터를 시작한 후 SSH를 사용하여 코어 노드에 연결하고 다음 명령을 실행하여 PySpark Dockerfile 예제에서 로컬 Docker 이미지를 빌드합니다.
먼저 예제에 사용할 디렉토리와 Dockerfile을 만듭니다.
$ mkdir pyspark
$ vi pyspark/Dockerfile
PySpark Dockerfile의 내용을 붙여 넣고 다음 명령을 실행하여 Docker 이미지를 만듭니다.
$ sudo docker build -t local/pyspark-example pyspark/
예제에 사용할 emr-docker-secondes ECR 리포지토리를 만듭니다.
$ aws ecr create-repository --repository-name emr-docker-examples
123456789123.dkr.ecr.us-east-1.amazonaws.com을(를) ECR 끝점으로 대체하여 로컬로 빌드된 이미지를 태그 및 ECR에 업로드합니다.
$ sudo docker tag local/pyspark-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
$ sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
SSH를 사용하여 마스터 노드에 연결하고 파일 이름 main으로 Python 스크립트를 준비합니다.py입니다. 다음 내용을 메인에 붙여넣습니다.pi 파일을 저장하고 있습니다.
작업을 제출하려면 Docker 이름을 참조합니다. 추가 구성 매개 변수를 정의하여 작업 실행이 Docker를 런타임으로 사용하도록 합니다. ECR을 사용할 때 을(를) 사용합니다.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG은(는) ECR 인증에 사용되는 자격 증명이 포함된 config.json 파일을 참조해야 합니다.
작업이 완료되면 YARN 애플리케이션 ID를 확인하고 다음 명령을 사용하여 PySpark 작업의 출력을 가져옵니다.
ECR에 SparkR 사용
이 예에서는 SparkR Dockerfile을 사용합니다. 태그가 지정되어 ECR에 업로드됩니다. 업로드한 후에는 SparkR 작업을 실행하고 ECR에서 Docker 영상을 참조합니다.
클러스터를 시작한 후 SSH를 사용하여 코어 노드에 연결하고 다음 명령을 실행하여 SparkR Dockerfile 예제에서 로컬 Docker 이미지를 빌드합니다.
먼저 이 예제에 대한 디렉토리와 Dockerfile을 만듭니다.
$ mkdir sparkr
$ vi sparkr/Dockerfile
SparkR Dockerfile의 콘텐츠를 붙여 넣고 다음 명령을 실행하여 Docker 이미지를 빌드합니다.
$ sudo docker build -t local/sparkr-example sparkr/
로컬로 빌드된 이미지를 태깅하여 ECR에 업로드합니다. 이때 123456789123.dkr.ecr.us-east-1.amazonaws.com은 실제 ECR 엔드포인트로 바꿉니다.
$ sudo docker tag local/sparkr-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
$ sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
SSH를 사용하여 마스터 노드를 연결하고 이름이 sparkR.R인 R 스크립트를 준비합니다. 다음 콘텐즈를 sparkR.R 파일에 붙여 넣습니다.
작업을 제출하려면 Docker 이름을 참조합니다. 추가 구성 매개 변수를 정의하여 작업 실행이 Docker를 런타임으로 사용하도록 합니다. ECR을 사용할 때 을(를) 사용합니다.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG은(는) ECR 인증에 사용되는 자격 증명이 포함된 config.json 파일을 참조해야 합니다.
작업이 완료되면 YARN 애플리케이션 ID를 기록하고 다음 명령을 사용하여 SparkR 작업의 출력을 가져옵니다. 이 예제에는 randomForest 라이브러리, 설치된 버전 및 릴리스 노트를 확인하는 테스트가 포함되어 있습니다.
Docker Hub의 Docker 이미지 사용
Docker Hub를 사용하려면 클러스터를 공용 서브넷에 배포하고 Docker Hub를 신뢰할 수 있는 레지스트리로 사용하도록 구성해야 합니다. 이 예제에서는 클러스터가 Docker Hub의 사용자-public-repo 리포지토리를 신뢰할 수 있도록 다음과 같은 추가 구성이 필요합니다. Docker Hub를 사용할 때는 이 리포지토리 이름을 실제 리포지토리 이름으로 바꾸십시오.
마무리
이 글에서는 EMR 6.0.0 클러스터를 사용하여 Docker 컨테이너에서 Spark 작업을 실행하고 Docker Hub 및 ECR과 통합하는 방법을 배웠습니다. PySpark와 SparkR Dockerfiles의 예를 모두 살펴보았습니다. 더 자세한 것은 기술 문서를 참고하시기 바랍니다.
EMR 팀은 귀하가 이 통합 기능을 사용하여 프로젝트에서 종속성 관리를 간소화하는 방법에 대해 듣기를 고대합니다. 질문이나 제안이 있으면 의견을 남겨주시기 바랍니다.