做了一个自启动 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界面。

更多镜像的细节可以访问 这里


如果觉得对你有帮助,实不相瞒想要个赞👍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值