如何启用从 Docker 容器内部启动的 Spark-Mesos 作业?
Posted
技术标签:
【中文标题】如何启用从 Docker 容器内部启动的 Spark-Mesos 作业?【英文标题】:How to enable a Spark-Mesos job to be launched from inside a Docker container? 【发布时间】:2017-04-18 20:02:26 【问题描述】:总结:
是否可以从具有 1 个 Mesos 主机(无 Zookeeper)和 1 个 Mesos 代理的 Docker 容器内提交 Mesos 作业,每个代理也都运行在单独的 Docker 容器中(目前在同一主机上)? http://mesos.apache.org/documentation/latest/container-image/ 中描述的 Mesos 容器化器似乎适用于 Mesos 应用程序简单地封装在 Docker 容器中并运行的情况。我的 Docker 应用程序与在运行时根据用户输入实例化的多个 PySpark Mesos 作业更具交互性。 Docker 容器中的驱动程序本身并不作为 Mesos 应用程序运行。只有用户发起的作业请求作为 PySpark Mesos 应用程序处理。
具体说明:
我有 3 个基于 centos:7 linux 的 Docker 容器,目前在同一台主机上运行:
容器“Master”运行 Mesos Master。
容器“代理”运行 Mesos 代理。
安装了 Spark 和 Mesos 的容器“测试”,我在其中运行 bash shell 并从命令行启动以下 PySpark 测试程序。
from pyspark import SparkContext, SparkConf
from operator import add
# Configure Spark
sp_conf = SparkConf()
sp_conf.setAppName("spark_test")
sp_conf.set("spark.scheduler.mode", "FAIR")
sp_conf.set("spark.dynamicAllocation.enabled", "false")
sp_conf.set("spark.driver.memory", "500m")
sp_conf.set("spark.executor.memory", "500m")
sp_conf.set("spark.executor.cores", 1)
sp_conf.set("spark.cores.max", 1)
sp_conf.set("spark.mesos.executor.home", "/usr/local/spark-2.1.0")
sp_conf.set("spark.executor.uri", "file://usr/local/spark-2.1.0-bin-without-hadoop.tgz")
sc = SparkContext(conf=sp_conf)
# Simple computation
x = [(1.5,100.),(1.5,200.),(1.5,300.),(2.5,150.)]
rdd = sc.parallelize(x,1)
tot = rdd.foldByKey(0,add).collect()
cnt = rdd.countByKey()
time = [t[0] for t in tot]
avg = [t[1]/cnt[t[0]] for t in tot]
print 'tot=', tot
print 'cnt=', cnt
print 't=', time
print 'avg=', avg
我使用的相关软件版本如下:
Hadoop:2.7.3 火花:2.1.0 Mesos:1.2.0 Docker:17.03.1-ce,构建 c6d412e以下工作正常:
我可以使用 Spark 的 MASTER=local[N]
for N=1
或 N=4
从 Test 容器内部运行上面的简单 PySpark 测试程序。
我可以在 Mesos 日志和 Mesos 用户界面 (UI) 中看到 Mesos 代理和主服务器运行良好。 Mesos UI 显示代理连接了大量资源(cpu、内存、磁盘)。
我可以使用 /usr/local/mesos-1.2.0/build/src/examples/python/test-framework 127.0.0.1:5050
从测试容器内成功运行 Mesos Python 测试。这似乎证实了可以从我的 Test 容器中访问 Mesos 容器,但是这些测试没有使用 Spark。
这是失败:
使用 Spark 的 MASTER=mesos://127.0.0.1:5050
,当我从 Test 容器内启动 PySpark 测试程序时,Mesos Master 和 Agent 的日志中都有活动,在失败前几秒钟,Mesos UI 显示分配给的资源在可用范围内的工作。但是,PySpark 测试程序随后失败:WARN scheduler.TaskSchedulerImpl: Initial job has not accepted any resources;检查您的集群 UI 以确保工作人员已注册并拥有足够的资源。
我遵循的步骤如下。
启动 Mesos Master:
docker run -it --net=host -p 5050:5050 the_master
主日志的相关摘录显示:
I0418 01:05:08.540192 27 master.cpp:383] Master 15b354eb-6a20-4bc9-a13b-6533b1e91bd2 (localhost) 开始于 127.0.0.1:5050 I0418 01:05:08.540210 27 master.cpp:385] 启动时的标志:--agent_ping_timeout="15secs" --agent_reregister_timeout="10mins" --allocation_interval="1secs" --allocator="HierarchicalDRF" --authenticate_agents="假" --authenticate_frameworks="false" --authenticate_http_frameworks="false" --authenticate_http_readonly="false" --authenticate_http_readwrite="false" --authenticators="crammd5" --authorizers="local" --framework_sorter="drf " --help="false" --hostname_lookup="true" --http_authenticators="basic" --initialize_driver_logging="true" --log_auto_initialize="true" --logbufsecs="0" --logging_level="INFO" --max_agent_ping_timeouts="5" --max_completed_frameworks="50" --max_completed_tasks_per_framework="1000" --max_unreachable_tasks_per_framework="1000" --quiet="false" --recovery_agent_removal_limit="100%" --registry="replicated_log" --registry_fetch_timeout="1mins" --registry_gc_interval="15mins" --registry_max_agent_age="2weeks" --registry_max_agent_count="102400" --registry_store_ti meout="20secs" --registry_strict="false" --root_submissions="true" --user_sorter="drf" --version="false" --webui_dir="/usr/local/mesos-1.2.0/build /../src/webui" --work_dir="/var/lib/mesos" --zk_session_timeout="10secs"
启动 Mesos 代理:
docker run -it --net=host -e MESOS_AGENT_PORT=5051 the_agent
代理的日志显示:
I0418 01:42:00.234244 40 slave.cpp:212] 启动时的标志:--appc_simple_discovery_uri_prefix="http://" --appc_store_dir="/tmp/mesos/store/appc" --authenticate_http_readonly="false " --authenticate_http_readwrite="false" --authenticatee="crammd5" --authentication_backoff_factor="1secs" --authorizer="local" --cgroups_cpu_enable_pids_and_tids_count="false" --cgroups_enable_cfs="false" --cgroups_hierarchy="/sys /fs/cgroup" --cgroups_limit_swap="false" --cgroups_root="mesos" --container_disk_watch_interval="15secs" --containerizers="mesos" --default_role="*" --disk_watch_interval="1mins" --docker ="docker" --docker_kill_orphans="true" --docker_mesos_image="spark-mesos-agent-test" --docker_registry="https://registry-1.docker.io" --docker_remove_delay="6hrs" -- docker_socket="/var/run/docker.sock" --docker_stop_timeout="0ns" --docker_store_dir="/tmp/mesos/store/docker" --docker_volume_checkpoint_dir="/var/run/mesos/isolators/docker/volume " --enforce_container_disk_quota="false" --executor_r egistration_timeout="1mins" --executor_shutdown_grace_period="5secs" --fetcher_cache_dir="/tmp/mesos/fetch" --fetcher_cache_size="2GB" --frameworks_home="" --gc_delay="1weeks" --gc_disk_headroom="0.1 " --hadoop_home="" --help="false" --hostname_lookup="true" --http_authenticators="basic" --http_command_executor="false" --http_heartbeat_interval="30secs" --initialize_driver_logging="true" - -isolation="posix/cpu,posix/mem" --launcher="posix" --launcher_dir="/usr/local/mesos-1.2.0/build/src" --logbufsecs="0" --logging_level= "信息" --max_completed_executors_per_framework="150" --oversubscribed_resources_interval="15secs" --perf_duration="10secs" --perf_interval="1mins" --qos_correction_interval_min="0ns" --quiet="false" --recover="重新连接" --recovery_timeout="15mins" --registration_backoff_factor="1secs" --revocable_cpu_low_priority="true" --runtime_dir="/var/run/mesos" --sandbox_directory="/mnt/mesos/sandbox" --strict ="true" --switch_user="false" --systemd_enable_support="false" --system d_runtime_directory="/run/systemd/system" --version="false" --work_dir="/var/lib/mesos"
我收到 Mesos Master 和 Agent 的以下警告,但忽略它,因为我现在在同一主机上运行所有内容:
主/代理绑定到环回接口!无法与远程调度程序或代理通信。您可能希望将“--ip”标志设置为可路由的 IP 地址。
事实上,我分配可路由 IP 地址而不是 127.0.0.1 的测试未能改变我在此处描述的任何行为。
启动测试容器(使用 bash shell 进行测试):
docker run -it --net=host the_test /bin/bash
在所有三个容器(Master、Agent 和 Test)中设置了一些相关的环境变量:
HADOOP_HOME=/usr/local/hadoop-2.7.3 HADOOP_CONF_DIR=/usr/local/hadoop-2.7.3/etc/hadoop SPARK_HOME=/usr/local/spark-2.1.0 SPARK_EXECUTOR_URI=file:////usr/local/spark-2.1.0-bin-without-hadoop.tgz MASTER=mesos://127.0.0.1:5050 PYSPARK_PYTHON=/usr/local/anaconda2/bin/python PYSPARK_DRIVER_PYTHON=/usr/local/anaconda2/bin/python PYSPARK_SUBMIT_ARGS=--driver-memory=4g pyspark-shell MESOS_PORT=5050 MESOS_IP=127.0.0.1 MESOS_WORKDIR=/var/lib/mesos MESOS_HOME=/usr/local/mesos-1.2.0 MESOS_NATIVE_JAVA_LIBRARY=/usr/local/lib/libmesos.so MESOS_MASTER=mesos://127.0.0.1:5050 PYTHONPATH=:/usr/local/spark-2.1.0/python:/usr/local/spark-2.1.0/python/lib/py4j-0.10.1-src.zip
从测试容器内运行 Mesos(非 Spark)测试:
/usr/local/mesos-1.2.0/build/src/examples/python/test-framework 127.0.0.1:5050
这会产生以下日志输出(如我所料):
I0417 21:28:36.912542 20 sched.cpp:232] 版本:1.2.0 I0417 21:28:36.920013 62 sched.cpp:336] 在 master@127.0.0.1:5050 检测到新主机 I0417 21:28:36.920472 62 sched.cpp:352] 未提供凭据。尝试在未经身份验证的情况下注册 I0417 21:28:36.924165 62 sched.cpp:759] 使用 be89e739-be8d-430e-b1e9-3fe55fa18459-0000 注册的框架 注册框架 ID be89e739-be8d-430e-b1e9-3fe55fa18459-0000 收到报价 be89e739-be8d-430e-b1e9-3fe55fa18459-O0,cpus:16.0 和 mem:119640.0 使用 offer be89e739-be8d-430e-b1e9-3fe55fa18459-O0 启动任务 0 使用优惠 be89e739-be8d-430e-b1e9-3fe55fa18459-O0 启动任务 1 使用优惠 be89e739-be8d-430e-b1e9-3fe55fa18459-O0 启动任务 2 使用报价 be89e739-be8d-430e-b1e9-3fe55fa18459-O0 启动任务 3 使用优惠 be89e739-be8d-430e-b1e9-3fe55fa18459-O0 启动任务 4 任务 0 处于状态 TASK_RUNNING 任务 1 处于状态 TASK_RUNNING 任务 2 处于状态 TASK_RUNNING 任务 3 处于状态 TASK_RUNNING 任务 4 处于状态 TASK_RUNNING 任务 0 处于状态 TASK_FINISHED 任务 1 处于状态 TASK_FINISHED 任务 2 处于状态 TASK_FINISHED 任务 3 处于状态 TASK_FINISHED 任务 4 处于状态 TASK_FINISHED 所有任务完成,等待最终框架消息 收到的消息:'带有 \x00 字节的数据' 收到的消息:'带有 \x00 字节的数据' 收到的消息:'带有 \x00 字节的数据' 收到的消息:'带有 \x00 字节的数据' 收到的消息:'带有 \x00 字节的数据' 所有任务完成,所有收到的消息,正在退出
从 Test 容器内运行 PySpark 测试程序:
python spark_test.py
这会产生以下日志输出:
17/04/17 21:29:18 WARN util.NativeCodeLoader:无法为您的平台加载 native-hadoop 库...在适用的情况下使用内置 java 类 I0417 21:29:19.187747 205 sched.cpp:232] 版本:1.2.0 I0417 21:29:19.196535 188 sched.cpp:336] 在 master@127.0.0.1:5050 检测到新主机 I0417 21:29:19.197453 188 sched.cpp:352] 未提供凭据。尝试在未经身份验证的情况下注册 I0417 21:29:19.201884 195 sched.cpp:759] 使用 be89e739-be8d-430e-b1e9-3fe55fa18459-0001 注册的框架 17/04/17 21:29:34 WARN scheduler.TaskSchedulerImpl:初始作业未接受任何资源;检查您的集群 UI 以确保工作人员已注册并拥有足够的资源
我在互联网上搜索了这个错误,但我发现的每个页面都表明这是一个常见的错误,原因是分配给 Mesos 代理的资源不足。正如我所提到的,Mesos UI 表明有足够的资源。如果您知道为什么我的 Spark 工作不接受来自 Mesos 的资源,或者您对我可以尝试的事情有任何建议,请回复。
感谢您的帮助。
【问题讨论】:
【参考方案1】:此错误现已解决。万一有人遇到类似的问题,我想在我的情况下发布它是由未在 Mesos Master 和 Agent 容器中设置的 HADOOP CLASSPATH 引起的。设置后,一切都会按预期进行。
【讨论】:
以上是关于如何启用从 Docker 容器内部启动的 Spark-Mesos 作业?的主要内容,如果未能解决你的问题,请参考以下文章