Spark on K8S(spark-on-kubernetes-operator)环境搭建以及demo过程(二)
Spark Demo过程中的常见问题(二)
Spark的executor/driver怎么持久化日志
想到的两种方式:
- driver/executor在执行过程中都对接到统一日志系统(例如ES)这个需要改改代码搭建新的环境,后续再研究
- Spark本身有日志持久化的配置,通过配置持久化到hdfs路径下(一般在yarn上也是这样用的)
这次采用的方法2,有如下配置可用:
#sparkConf:
#"spark.eventLog.enabled": "true"
#"spark.eventLog.dir": "hdfs://hdfscluster:port/spark-test/spark-events"
如果遇到了kerberos相关的问题,可以参考后续章节来解决;日志持久化之后,spark提供的web ui在driver执行完成后会shutdown,无法看到spark job执行过程,先想了一个土办法,在spark.stop()前增加了一个sleep,此时web ui不会shutdown,在kubernetes集群中可以看到一个spark-pi driver对应的svc,但是没有nodeport,所以为了可以在集群外访问该svc,可以通过:新增80端口映射的ingress,配置backend到svc上访问,或直接将ingress-controller的backend指向该svc,我采用的是这种,不过蛋疼的是每一次sparkApplication都创建一个新的svc,没法统一在一个界面看到;另外应该还有一种更简单的办法,通过kubectl port-forward让集群外直接访问一个svc,暂时还没有试过;可以记一个思考题以后尝试。
尝试使用kubectl port-forward来实现外部访问集群SVC
Spark history server怎么配置生效
每个sparkApplication不可能都保留,所以还是得搭建Spark history server,两种方法:
- 就用spark v2.4.4镜像,单独建一个history的镜像然后run起来,放在kubernetes里跑
- 集群外部署一个spark history server
Dokcerfile如下:
ARG SPARK_IMAGE=gcr.io/spark-operator/spark:v2.4.4
FROM gcr.io/spark-operator/spark:v2.4.4
RUN chmod 777 /opt/spark/sbin/start-history-server.sh
RUN ls -l /opt/spark/sbin/start-history-server.sh
COPY spark-daemon.sh /opt/spark/sbin/spark-daemon.sh
RUN chmod 777 /opt/spark/sbin/spark-daemon.sh
COPY run.sh /opt/run.sh
RUN chmod 777 /opt/run.sh
RUN mkdir -p /etc/hadoop/conf
RUN chmod 777 /etc/hadoop/conf
COPY core-site.xml /etc/hadoop/conf/core-site.xml
COPY hdfs-site.xml /etc/hadoop/conf/hdfs-site.xml
COPY user.keytab /etc/hadoop/conf/user.keytab
COPY krb5.conf /etc/hadoop/conf/krb5.conf
RUN chmod 777 /etc/hadoop/conf/core-site.xml
RUN chmod 777 /etc/hadoop/conf/hdfs-site.xml
RUN chmod 777 /etc/hadoop/conf/user.keytab
RUN chmod 777 /etc/hadoop/conf/krb5.conf
ENTRYPOINT ["/opt/run.sh"]
docker run起来之后发现出现如下错误:
ps: unrecognized option: p
BusyBox v1.29.3 (2019-01-24 07:45:07 UTC) multi-call binary.
Usage: ps [-o COL1,COL2=HEADER]
Show list of processes
-o COL1,COL2=HEADER Select columns for display
这里为了定位分析报错原因,所以用了一个土办法,不直接在容器加载后执行start-history-server.sh,而是封装到一个自己写的脚本年内,在脚本里sleep一下,然后再用docker exec -it xxxxxxx bash进入容器分析;
#!/bin/bash
sh /opt/spark/sbin/start-history-server.sh "hdfs://xxxxxxxxxx:xxxx/spark-test/spark-events"
while [ 1 == 1 ]
do
cat /opt/spark/logs/*
sleep 60
done
发现启动脚本中用到的spark-daemon.sh中包含ps -p的用法,该用法会直接报错,所以需要修改spark-daemon.sh脚本,将脚本中的ps -p替换为ps,然后再docker打镜像的时候替换一下脚本,过程中还发现了脚本中另一个问题:
execute_command() {
if [ -z ${SPARK_NO_DAEMONIZE+set} ]; then
nohup -- "$@" >> $log 2>&1 < /dev/null &
newpid="$!"
没搞懂这个–是个干啥的,直接替换掉吧,不用execute_command直接起进程:
case "$mode" in
(class)
"${SPARK_HOME}"/bin/spark-class "$command" "