做了一個自啓動 ssh 服務的 spark單機環境的鏡像(alpine)

最近同同事 們一起在學習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中的部分語句做下解釋:

  1. 腳本的第一部分,是提供一個方式用於便於在容器運行的時候,能夠增加額外的python依賴
  2. 第二部分在於改變容器內的root用戶密碼(一定要做 !!!)。因爲如果不修改默認的alpine的root密碼的話,後續就算你提供了正確的PublicKey,仍然無法免密登錄。(我也不填清楚 爲啥??)可以通過傳入 ROOT_PASSWORD 環境變量來自定義root用戶密碼(默認爲admin)。
  3. 第三部分對於公鑰存在的檢查,目的在於提供一個方式,便於自己提供對應的公鑰和私鑰給容器

後面的就是根據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界面。

更多鏡像的細節可以訪問 這裏


如果覺得對你有幫助,實不相瞞想要個贊👍

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章