如何启用Spark-Mesos作业从Docker容器中启动?

概要:

是否有可能从一个Docker容器内的Mesos上提交一个Spark作业,这个容器有一个Mesos master(没有Zookeeper)和一个Mesos代理,每个都在单独的Docker容器中运行(现在在同一台主机上)? 在http://mesos.apache.org/documentation/latest/container-image/中描述的Mesos Containerizer似乎适用于Mesos应用程序简单地封装在Docker容器中并运行的情况。 我的Docker应用程序更具交互性,在运行时基于用户input实例化多个PySpark Mesos作业。 Docker容器中的驱动程序本身不是作为Mesos应用程序运行的。 只有用户发起的作业请求被作为PySpark Mesos应用程序处理。

具体细节:

我有3个基于centos:7 linux的Docker容器,现在在同一台主机上运行:

  1. 运行Mesos Master的容器“Master”。

  2. 运行Mesos Agent的容器“Agent”。

  3. 使用Spark和Mesos安装容器“testing”,在其中运行bash shell并从命令行启动以下PySparktesting程序。

    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
  • Spark:2.1.0
  • Mesos:1.2.0
  • Docker:17.03.1-ce,build c6d412e

以下工作正常:

  • 我可以使用Spark的MASTER=local[N]运行上面简单的PySparktesting程序,对于N=1N=4 ,可以从Test容器中运行。

  • 我可以在Mesos日志和Mesos用户界面(UI)中看到Mesos代理和主服务器正常运行。 Mesos UI显示代理连接了大量资源(cpu,内存,磁盘)。

  • 我可以使用/usr/local/mesos-1.2.0/build/src/examples/python/test-framework 127.0.0.1:5050在Test容器内成功运行Mesos Pythontesting。 这似乎证实Mesos容器可以从我的Test容器中访问,但是这些testing不是使用Spark。

这是失败:

使用Spark的MASTER=mesos://127.0.0.1:5050 ,当我从Test容器中启动我的PySparktesting程序时,Mesos Master和Agent的日志中都有活动,在发生故障之前几秒钟,Mesos用户界面显示分配给作业的资源,这些资源在可用范围内。 然而,PySparktesting程序然后失败: WARN scheduler.TaskSchedulerImpl:初始作业没有接受任何资源; 检查您的集群用户界面,以确保工人已注册,并有足够的资源

我遵循的步骤如下。

启动Mesos Master:

 docker run -it --net=host -p 5050:5050 the_master 

硕士的日志相关摘录显示:

I0418 01:05:08.540192 27 master.cpp:383]主机15b354eb-6a20-4bc9-a13b-6533b1e91bd2(本地主机)在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 = false“–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_timeo ut =“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_registr ation_timeout =“1mins”–executor_shutdown_grace_period =“5secs”–fetcher_cache_dir =“/ tmp / mesos / fetch”–fetcher_cache_size =“2GB”–frameworks_home =“”–gc_delay =“1周”–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 = “INFO”–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”–systemd_runt ime_directory =“/ run / systemd / system”–version =“false”–work_dir =“/ var / lib / mesos”

对于Mesos Master和Agent,我得到以下警告,但忽略它,因为我现在正在同一台主机上运行所有的东西:

Master / Agent绑定到Loopback接口! 无法与远程调度程序或代理进行通信。 您可能需要将“–ip”标志设置为可路由的IP地址。

事实上,我分配一个可路由的IP地址而不是127.0.0.1的testing未能改变我在这里描述的任何行为。

启动testing容器(用bash shell进行testing):

 docker run -it --net=host the_test /bin/bash 

所有三个容器(Master,Agent和Test)中设置的一些相关的环境variables:

HADOOP_HOME =的/ usr /本地/ Hadoop的2.7.3
HADOOP_CONF_DIR =的/ usr /本地/ Hadoop的2.7.3的/ etc / hadoop的
SPARK_HOME =的/ usr /本地/火花2.1.0
SPARK_EXECUTOR_URI =文件:////usr/local/spark-2.1.0-bin-without-hadoop.tgz
MASTER = mesos://127.0.0.1:5050
PYSPARK_PYTHON =在/ usr /本地/ anaconda2 /斌/python
PYSPARK_DRIVER_PYTHON =在/ usr /本地/ anaconda2 /斌/python
PYSPARK_SUBMIT_ARGS = – 驱动程序内存= 4g pyspark-shell
MESOS_PORT = 5050
MESOS_IP = 127.0.0.1
MESOS_WORKDIR =的/ var / lib中/ mesos
MESOS_HOME =的/ usr /本地/ mesos-1.2.0
MESOS_NATIVE_JAVA_LIBRARY =在/ usr / local / lib目录/ libmesos.so
MESOS_MASTER = mesos://127.0.0.1:5050
PYTHONPATH =:在/ usr /本地/火花2.1.0 /python:/usr/local/spark-2.1.0/python/lib/py4j-0.10.1-src.zip

从Test容器中运行Mesos(非Spark)testing:

 /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]没有提供凭据。 试图注册没有身份validation
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
使用报价启动任务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 be89e739-be8d-430e-b1e9-3fe55fa18459-O0
任务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容器中运行PySparktesting程序:

 python spark_test.py 

这会产生以下日志输出:

17/04/17 21:29:18 WARN util.NativeCodeLoader:无法为您的平台加载native-hadoop库…在适用的情况下使用builtin-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]没有提供凭据。 试图注册没有身份validation
I0417 21:29:19.201884 195 sched.cpp:759]使用be89e739-be8d-430e-b1e9-3fe55fa18459-0001注册的框架
17/04/17 21:29:34 WARN scheduler.TaskSchedulerImpl:初始作业未接受任何资源; 检查您的集群用户界面,以确保工人已注册,并有足够的资源

我在互联网上search了这个错误,但是我发现每一页都显示这是一个常见的错误,这是由于分配给Mesos代理的资源不足造成的。 正如我所提到的,Mesos UI表明有足够的资源。 如果您有任何想法,请回复我为什么我的Spark工作不接受Mesos的资源,或者如果您有任何我可以尝试的build议。

感谢您的帮助。

这个错误现在已经解决了。 如果有人遇到类似的问题,我想在我的情况下,这是由于没有在Mesos Master和Agent容器中设置HADOOP CLASSPATH导致的。 一旦设定,一切都按预期工作。