Glueをローカル環境でテストしたい
AWSのLambdaがローカル環境で開発できるため、Glueもできないかなーと思い調べたところ、AWSからライブラリが提供されていました。
最初は個別でインストールしての利用を試みたのですが、うまくいかず…。
ググったところ、Dockerで一気に作成する手順を発見。ローカル開発環境の構築に成功しました。
#前提条件
- CentOs 7.6
- Docker 19.03.2
#大まかな手順
- Dockerファイルを作製
- 1.に基づき、コンテナをビルド
- コンテナを起動
- コンテナにログインしgluepyskarkを起動
#手順詳細
1. Dockerファイルを作製
適当なディレクトリに、Dockerfileという名前のテキストファイルを作製し、そこに設定内容を記述します。
※Emacs派なので、viでなくemacsで開いてます。
$ mkdir aws-glue-local
$ cd aws-glue-local/
$ emacs Dockerfile
下記Dockerfileは、フューチャー開発者ブログさんのこちらの記事を引用させていただきました。
※CA証明書の部分を追加しました。
FROM centos:7
######### CA証明書のインストール(セキュリティソフト等の関係でCAインストール必要な場合はコメントを外して実行)########
######### CA証明書(ここではmyca.crt)は、aws-glue-local内部に配置しておくこと。
#COPY myca.crt /usr/share/pki/ca-trust-source/anchors/
#RUN update-ca-trust extract
############################################################################################################
# https://omohikane.com/centos7_docker_python36/ を参考にpythonとjavaをインストール
RUN yum install -y bzip2 bzip2-devel gcc gcc-c++ make openssl-devel readline-devel zlib-devel wget curl unzip vim epel-release git && yum install -y tig jq vim-enhanced bash-completion net-tools bind-utils \
&& yum install -y https://repo.ius.io/ius-release-el7.rpm \
&& yum install -y python36u python36u-libs python36u-devel python36u-pip \
&& yum install -y java java-1.8.0-openjdk-devel \
&& rm -rf /var/cache/yum/*
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LC_CTYPE "ja_JP.UTF-8"
ENV LC_NUMERIC "ja_JP.UTF-8"
ENV LC_TIME "ja_JP.UTF-8"
ENV LC_COLLATE "ja_JP.UTF-8"
ENV LC_MONETARY "ja_JP.UTF-8"
ENV LC_MESSAGES "ja_JP.UTF-8"
ENV LC_PAPER "ja_JP.UTF-8"
ENV LC_NAME "ja_JP.UTF-8"
ENV LC_ADDRESS "ja_JP.UTF-8"
ENV LC_TELEPHONE "ja_JP.UTF-8"
ENV LC_MEASUREMENT "ja_JP.UTF-8"
ENV LC_IDENTIFICATION "ja_JP.UTF-8"
ENV LC_ALL ja_JP.UTF-8
# Glueライブラリ取得
RUN git clone -b glue-1.0 --depth 1 https://github.com/awslabs/aws-glue-libs
# Maven取得
RUN curl -OL https://archive.apache.org/dist/maven/maven-3/3.6.2/binaries/apache-maven-3.6.2-bin.tar.gz
RUN tar -xzvf apache-maven-3.6.2-bin.tar.gz
RUN mv apache-maven-3.6.2 /opt/
RUN ln -s /opt/apache-maven-3.6.2 /opt/apache-maven
ENV JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk/jre/
ENV PATH $PATH:/opt/apache-maven/bin
RUN mvn -version
####################################################################################################
#### SSL証明書をインポートしてもmavenでSSL通信エラーが発生する場合は、コメントを外して実行。
#### MAVENオプションの記述内容の意味するところは
#### -Dmaven.wagon.http.ssl.insecure = true – ユーザー生成したCA証明書に対する安全でないSSLの使用を有効化
#### -Dmaven.wagon.http.ssl.allowall = true – サーバーのX.509証明書とホスト名の一致を有効化。
#### 無効にすると検証済みのブラウザが使用される
#### -Dmaven.wagon.http.ssl.ignore.validity.dates = true – 証明書生成日付の問題を無視
#####################################################################################################
#RUN echo "MAVEN_OPTS=\"-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true\"" >> ~/.mavenrc
# Glueアーティファクト取得
RUN curl -OL https://aws-glue-etl-artifacts.s3.amazonaws.com/glue-1.0/spark-2.4.3-bin-hadoop2.8.tgz
RUN tar -xzvf spark-2.4.3-bin-hadoop2.8.tgz
RUN mv spark-2.4.3-bin-spark-2.4.3-bin-hadoop2.8 /opt/
RUN ln -s /opt/spark-2.4.3-bin-spark-2.4.3-bin-hadoop2.8 /opt/spark
ENV SPARK_HOME /opt/spark
# Python3.6を利用する設定
RUN unlink /bin/python
RUN ln -s /bin/python3 /bin/python
RUN ln -s /bin/pip3.6 /bin/pip
# 異なるバージョンのjarがsparkとglueに混在するので適切なバージョンのみを見るよう設定
RUN ln -s ${SPARK_HOME}/jars /aws-glue-libs/jarsv1
RUN ./aws-glue-libs/bin/gluepyspark
# 無限ループを実行させ、コンテナを終了させない
ENTRYPOINT ["/bin/sh", "-c", "while :; do sleep 10; done"]
2. Dockerfileに基づき、コンテナをビルド
dockerコマンドを用いて、コンテナを作製します。
Dockerfileがあることを確認し、ビルドコマンドを実行
$ ls #Dockerfileがあるか確認
Dockerfile
$ docker build . -t aws-glue-local-image #イメージ名はaws-glue-local-imageで作製
成功の場合:完了まで20分くらい
失敗の場合:数秒で処理終了
####【ビルド成功】BUILD SUCCESS と表示される
この場合は、次のステップ(コンテナの起動)へ。
####【ビルド失敗】BUILD FAILURE と表示される
この場合は、エラーメッセージを頼りに原因を特定しましょう。
当方の環境では、yum等のSSL通信時にCA証明書が必要だったため、ビルドが失敗しました。
そのためDockerfileにCA証明書のインストールを記述、対応させました。
3. コンテナを起動
ビルド完了後、コンテナを起動させます。
docker run の時、&を付けるのは永久ループでのTerminal応答停止を防ぐためです。
$ docker images # dockerイメージの確認
REPOSITORY TAG IMAGE ID CREATED SIZE
aws-glue-local-image latest 4daf5c8dd6ec 4 hours ago 2.07GB
centos 7 5e35e350aded 9 days ago 203MB
$ docker run --name aws-glue-local aws-glue-local-image & # 作成したイメージから、コンテナ名aws-glue-localで起動させる
4. コンテナにログインしgluepyskarkを起動
コンテナの起動を確認し、ログインします。
gluepyspark起動時にエラーが起きず、Glueのモジュールが利用できれば成功!
$ docker ps # 起動中のコンテナを確認
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9b9886411b08 aws-glue-local-image "/bin/sh -c 'while :…" 4 hours ago Up 4 hours aws-glue-local
$ docker exec -it aws-glue-local bash # aws-glue-localコンテナに、bashでログイン
# ./aws-glue-libs/bin/gluepyspark # ログインするとrootになるので、gluepysparkを実行
~~~~中略~~~~
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/__ / .__/\_,_/_/ /_/\_\ version 2.4.3
/_/
Using Python version 3.6.8 (default, Aug 7 2019 17:28:10)
SparkSession available as 'spark'.
>>> from awsglue.context import GlueContext # GlueContextを試しにインポート
>>> GlueContext # 中身確認
<class 'awsglue.context.GlueContext'>
>>> quit() # gluepyspark終了
# exit #コンテナから出る
$ docker stop aws-glue-local #コンテナを停止
aws-glue-local
$ docker ps #コンテナを確認(何もない)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker ps -a #停止コンテナ含めて確認(ちゃんといる)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9b9886411b08 aws-glue-local-image "/bin/sh -c 'while :…" 4 hours ago Exited (137) 4 minutes ago aws-glue-local
dockerコマンドメモ
$ docker build Dockerfileの場所 -t イメージ名 #Dockerイメージの作成
$ docker images #Dockerimage一覧
$ docker run --name コンテナにつける名前 稼働元のイメージ名/ID #Dockerコンテナの起動
$ docker exec -it コンテナ名/ID コマンド #稼働中のコンテナにコマンドを送信※bashを指定するとTerminalログインできる
$ docker ps #コンテナ一覧(稼働中)
$ docker ps -a #コンテナ一覧(停止中含む)
$ docker stop コンテナ名 #コンテナの停止
$ docker rm コンテナ名 #コンテナ削除
$ docker rmi イメージID #イメージ削除
#参考
- AWS Glue 開発者ドキュメント : AWS Glue ETL ライブラリを使用した ETL スクリプトのローカルでの開発とテスト
- フューチャー開発者ブログ : AWS Glueの開発エンドポイントがそこそこお高いのでローカル開発環境を用意しました
- コードログ : MavenにSSLエラーを無視して(そしてすべての証明書を信頼するように)指示する方法?
- Stack Over Flow : how-to-tell-maven-to-disregard-ssl-errors-and-trusting-all-certs