最近同同事 們一起在學習Spark,爲了方便同事們的使用,也爲了減少不必要的安裝spark的坑,特意做了一個自啓動SSH服務的單機版本的Spark集羣,供大家學習和使用。
如果只想看如何使用,可以跳到第三節直接運行。
從官網可以看到,spark 已經爲大家提供好了很多的命令進程的啓動腳本,我們就選用最簡單的 ${SPARK_HOME}/sbin/start-all.sh
腳本
基礎鏡像
爲了今後更加方便的擴展,特意的先做了一個基礎的spark鏡像,下載和配置了各種spark所需要的運行環境(Java 版本、Scala版本、Python3版本)。
廢話不多少,先上基本的spark docker 文件 base.dockerfile 代碼:
FROM openjdk:8u212-jdk-alpine3.9
# Installing IPython
ENV DAEMON_RUN=true
ENV SPARK_VERSION=2.4.5
ENV HADOOP_VERSION=2.7
ENV SCALA_VERSION=2.12.4
ENV SBT_VERSION=0.13.15
ENV SCALA_HOME=/usr/share/scala
RUN apk add --no-cache --virtual=.build-dependencies wget ca-certificates && \
apk add --no-cache bash curl jq && \
cd "/tmp" && \
wget --no-verbose "https://downloads.typesafe.com/scala/${SCALA_VERSION}/scala-${SCALA_VERSION}.tgz" && \
tar xzf "scala-${SCALA_VERSION}.tgz" && \
mkdir "${SCALA_HOME}" && \
rm "/tmp/scala-${SCALA_VERSION}/bin/"*.bat && \
mv "/tmp/scala-${SCALA_VERSION}/bin" "/tmp/scala-${SCALA_VERSION}/lib" "${SCALA_HOME}" && \
ln -s "${SCALA_HOME}/bin/"* "/usr/bin/" && \
apk del .build-dependencies && \
rm -rf "/tmp/"*
#Scala instalation
RUN export PATH="/usr/local/sbt/bin:$PATH" && apk update && apk add ca-certificates wget tar && mkdir -p "/usr/local/sbt" && wget -qO - --no-check-certificate "http://dl.bintray.com/sbt/native-packages/sbt/$SBT_VERSION/sbt-$SBT_VERSION.tgz" | tar xz -C /usr/local/sbt --strip-components=1 && sbt sbtVersion
# Python instalation
RUN apk add --no-cache python3 && ln -s $(command -v python3) /usr/bin/python
# Note: this is needed when you use Python 3.3 or greater
ENV PYTHONHASHSEED 1
RUN wget --no-verbose https://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-${SPARK_VERSION}/spark-${SPARK_VERSION}-bin-hadoop${HADOOP_VERSION}.tgz && tar -xvzf spark-${SPARK_VERSION}-bin-hadoop${HADOOP_VERSION}.tgz \
&& mv spark-${SPARK_VERSION}-bin-hadoop${HADOOP_VERSION} spark \
&& rm spark-${SPARK_VERSION}-bin-hadoop${HADOOP_VERSION}.tgz
ENV SPARK_HOME /spark
構建好的 Tag 爲 5200710/spark:spark-base-2.4.5
.
spark-standalone 鏡像
然後在構建好的基礎鏡像上,安裝啓動ssh服務和spark的start-all.sh 腳本所需要的環境。
這裏比較坑的點在於 docker 鏡像內部,不可以直接的通過 rc-update之類的系統服務啓動,網上試了很多種啓動sshd服務的方法,發現還是
/usr/sbin/sshd -D &
能靠譜的在docker容器啓動的時候啓動ssh服務。
因爲通過 start-all 腳本啓動,必定需要先啓動ssh服務,然後配置 root@localhost
的免密驗證。所以 standalone.dockerfile 相對於前面提到的spark的基礎只是增加了部分安裝openssh 服務的依賴和啓動start-all
腳本的所需要的執行依賴。
FROM 5200710/spark:spark-base-2.4.5
ENV SPARK_MASTER_PORT 7077
ENV SPARK_MASTER_WEBUI_PORT 8080
ENV SPARK_WORKER_WEBUI_PORT 8081
RUN apk --no-cache add procps coreutils openssh
RUN mkdir -p /root/.ssh && \
chmod 700 /root/.ssh/ && \
ssh-keygen -A
EXPOSE 8080 7077 6066
ENV PYSPARK_PYTHON python3
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "-d" ]
procps 和 coreutils 等依賴是由於後續的start-all.sh 腳本中有些命令需要依賴這兩個包執行。
ssh-keygen -A
命令是爲了預先生成啓動 ssh服務所需要的所有 host_key.
對於掛載點運行的啓動腳本 entrypoint.sh
內容如下:
#!/usr/bin/env bash
# Exit immediately if a command exits with a non-zero exit status.
set -e
# Install custom python package if requirements.txt is present
[ -e "/requirements.txt" ] && ${command-v pip3} install --user -r /requirements.txt
# you can login with publishkey if don't change the password(confuse)
echo "root:${ROOT_PASSWORD:=admin}" | chpasswd
sed -i "s/#PermitRootLogin.*/PermitRootLogin yes/g" /etc/ssh/sshd_config
# generate the publishkey and privatekey for passwordless login
[ ! -e ~/.ssh/id_rsa ] && ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub >~/.ssh/authorized_keys
# deamon start sshd service
/usr/sbin/sshd -D &
# 指定一個Slave和Java變量
echo "localhost" >${SPARK_HOME}/conf/slaves
echo "JAVA_HOME=${JAVA_HOME}" >${SPARK_HOME}/conf/spark-env.sh
${SPARK_HOME}/sbin/start-all.sh
if [[ $1 == "-d" ]]; then
tail -f ${SPARK_HOME}/logs/*.out
# while true; do sleep 1000; done
fi
exec "$@"
對entrypoint.sh
中的部分語句做下解釋:
- 腳本的第一部分,是提供一個方式用於便於在容器運行的時候,能夠增加額外的python依賴
- 第二部分在於改變容器內的root用戶密碼(一定要做 !!!)。因爲如果不修改默認的alpine的root密碼的話,後續就算你提供了正確的PublicKey,仍然無法免密登錄。(我也不填清楚 爲啥??)可以通過傳入
ROOT_PASSWORD
環境變量來自定義root用戶密碼(默認爲admin)。 - 第三部分對於公鑰存在的檢查,目的在於提供一個方式,便於自己提供對應的公鑰和私鑰給容器
後面的就是根據spark官網指定下worker的列表,這裏只啓動一個,所以寫了一次 localhost
. 主動的聲明下JAVA_HOME 路徑
鏡像運行方式
有需要的可以根據前面的教程重新自定義編排一個。當然也可以直接使用我已經編譯好的鏡像。
命令行的使用方式:
docker run --rm -it -e ROOT_PASSWORD='admin' -p 8080:8080 -p 8081:8081 -p 7077:7077 -p 2222:22 5200710/spark:spark-standalone-2.4.5 bash
docker-compse 的方式
version: "3.7"
services:
spark-standalone:
image: 5200710/spark:spark-standalone-2.4.5
ports:
- "8080:8080"
- "8081:8081"
- "7077:7077"
- "2222:22"
# environment:
# - "ROOT_PASSWORD=admin"
下載文件之後,在所在文件的目錄下通過 docker-compose up -d
方式啓動。
啓動成功之後,可以通過 http://localhost:8080 訪問單機版本 spark集羣的UI界面。
更多鏡像的細節可以訪問 這裏 。
如果覺得對你有幫助,實不相瞞想要個贊👍