spark-on-yarn-with-kubernetes

该例子仅用来说明具体的步骤划分和复杂性,在生产环境应用还有待验证,请谨慎使用。

过程中可能用到的概念和术语初步整理如下:

整个迁移过程分为如下几个步骤:

1. 将原有应用拆解为服务

我们不是一上来就开始做镜像,写配置,而是应该先梳理下要迁移的应用中有哪些可以作为服务运行,哪些是变的,哪些是不变的部分。

服务划分的原则是最小可变原则,这个同样适用于镜像制作,将服务中不变的部分编译到同一个镜像中。

对于像 Spark on YARN 这样复杂的应用,可以将其划分为三大类服务:

  • ResourceManager
  • NodeManager
  • Spark client

2. 制作镜像

根据拆解出来的服务,我们需要制作两个镜像:

  • Hadoop
  • Spark (From hadoop docker image)

因为我们运行的是 Spark on YARN,因此 Spark 依赖与 Hadoop 镜像,我们在 Spark 的基础上包装了一个 web service 作为服务启动。

镜像制作过程中不需要在 Dockerfile 中指定 Entrypoint 和 CMD,这些都是在 kubernetes 的 YAML 文件中指定的。

Hadoop YARN 的 Dockerfile 参考如下配置。

  1. FROM my-docker-repo/jdk:7u80
  2.  
  3. # Add native libs
  4. ARG HADOOP_VERSION=2.6.0-cdh5.5.2
  5. ## Prefer to download from server not use local storage
  6. ADD hadoop-${HADOOP_VERSION}.tar.gz /usr/local
  7. ADD ./lib/* /usr/local/hadoop-${HADOOP_VERSION}/lib/native/
  8. ADD ./jars/* /usr/local/hadoop-${HADOOP_VERSION}/share/hadoop/yarn/
  9. ENV HADOOP_PREFIX=/usr/local/hadoop \
  10. HADOOP_COMMON_HOME=/usr/local/hadoop \
  11. HADOOP_HDFS_HOME=/usr/local/hadoop \
  12. HADOOP_MAPRED_HOME=/usr/local/hadoop \
  13. HADOOP_YARN_HOME=/usr/local/hadoop \
  14. HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop \
  15. YARN_CONF_DIR=/usr/local/hadoop/etc/hadoop \
  16. PATH=${PATH}:/usr/local/hadoop/bin
  17.  
  18. RUN \
  19. cd /usr/local && ln -s ./hadoop-${HADOOP_VERSION} hadoop && \
  20. rm -f ${HADOOP_PREFIX}/logs/*
  21.  
  22. WORKDIR $HADOOP_PREFIX
  23.  
  24. # Hdfs ports
  25. EXPOSE 50010 50020 50070 50075 50090 8020 9000
  26. # Mapred ports
  27. EXPOSE 19888
  28. #Yarn ports
  29. EXPOSE 8030 8031 8032 8033 8040 8042 8088
  30. #Other ports
  31. EXPOSE 49707 2122

3. 准备应用的配置文件

因为我们只制作了一个 Hadoop 的镜像,而需要启动两个服务,这就要求在服务启动的时候必须加载不同的配置文件,现在我们只需要准备两个服务中需要同时用的的配置的部分。

YARN 依赖的配置在 artifacts 目录下,包含以下文件:

  1. bootstrap.sh
  2. capacity-scheduler.xml
  3. container-executor.cfg
  4. core-site.xml
  5. hadoop-env.sh
  6. hdfs-site.xml
  7. log4j.properties
  8. mapred-site.xml
  9. nodemanager_exclude.txt
  10. slaves
  11. start-yarn-nm.sh
  12. start-yarn-rm.sh
  13. yarn-env.sh
  14. yarn-site.xml

其中作为 bootstrap 启动脚本的 bootstrap.sh 也包含在该目录下,该脚本如何编写请见下文。

4. Kubernetes YAML 文件

根据业务的特性选择最适合的 kubernetes 的资源对象来运行,因为在 YARN 中 NodeManager 需要使用主机名向 ResourceManger 注册,因此需要沿用 YARN 原有的服务发现方式,使用 headless service 和 StatefulSet 资源。更多资料请参考 StatefulSet

所有的 Kubernetes YAML 配置文件存储在 manifest 目录下,包括如下配置:

  • yarn-cluster 的 namespace 配置
  • Spark、ResourceManager、NodeManager 的 headless service 和 StatefulSet 配置
  • 需要暴露到 kubernetes 集群外部的 ingress 配置(ResourceManager 的 Web)
  1. kube-yarn-ingress.yaml
  2. spark-statefulset.yaml
  3. yarn-cluster-namespace.yaml
  4. yarn-nm-statefulset.yaml
  5. yarn-rm-statefulset.yaml

5. Bootstrap 脚本

Bootstrap 脚本的作用是在启动时根据 Pod 的环境变量、主机名或其他可以区分不同 Pod 和将启动角色的变量来修改配置文件和启动服务应用。

该脚本同时将原来 YARN 的日志使用 stdout 输出,便于使用 kubectl logs 查看日志或其他日志收集工具进行日志收集。

启动脚本 bootstrap.sh 跟 Hadoop 的配置文件同时保存在 artifacts 目录下。

该脚本根据 Pod 的主机名,决定如何修改 Hadoop 的配置文件和启动何种服务。bootstrap.sh 文件的部分代码如下:

  1. if [[ "${HOSTNAME}" =~ "yarn-nm" ]]; then
  2. sed -i '/<\/configuration>/d' $HADOOP_PREFIX/etc/hadoop/yarn-site.xml
  3. cat >> $HADOOP_PREFIX/etc/hadoop/yarn-site.xml <<- EOM
  4. <property>
  5. <name>yarn.nodemanager.resource.memory-mb</name>
  6. <value>${MY_MEM_LIMIT:-2048}</value>
  7. </property>
  8.  
  9. <property>
  10. <name>yarn.nodemanager.resource.cpu-vcores</name>
  11. <value>${MY_CPU_LIMIT:-2}</value>
  12. </property>
  13. EOM
  14. echo '</configuration>' >> $HADOOP_PREFIX/etc/hadoop/yarn-site.xml
  15. cp ${CONFIG_DIR}/start-yarn-nm.sh $HADOOP_PREFIX/sbin/
  16. cd $HADOOP_PREFIX/sbin
  17. chmod +x start-yarn-nm.sh
  18. ./start-yarn-nm.sh
  19. fi
  20.  
  21. if [[ $1 == "-d" ]]; then
  22. until find ${HADOOP_PREFIX}/logs -mmin -1 | egrep -q '.*'; echo "`date`: Waiting for logs..." ; do sleep 2 ; done
  23. tail -F ${HADOOP_PREFIX}/logs/* &
  24. while true; do sleep 1000; done
  25. fi

从这部分中代码中可以看到,如果 Pod 的主机名中包含 yarn-nm 字段则向 yarn-site.xml配置文件中增加如下内容:

  1. <property>
  2. <name>yarn.nodemanager.resource.memory-mb</name>
  3. <value>${MY_MEM_LIMIT:-2048}</value>
  4. </property>
  5.  
  6. <property>
  7. <name>yarn.nodemanager.resource.cpu-vcores</name>
  8. <value>${MY_CPU_LIMIT:-2}</value>
  9. </property>

其中 MY_MEM_LIMIT 和 MY_CPU_LIMIT 是 kubernetes YAML 中定义的环境变量,该环境变量又是引用的 Resource limit。

所有的配置准备完成后,执行 start-yarn-nm.sh 脚本启动 NodeManager。

如果 kubernetes YAML 中的 container CMD args 中包含 -d 则在后台运行 NodeManger 并 tail 输出 NodeManager 的日志到标准输出。

6. ConfigMaps

将 Hadoop 的配置文件和 bootstrap 脚本作为 ConfigMap 资源保存,用作 Pod 启动时挂载的 volume。

  1. kubectl create configmap hadoop-config \
  2. --from-file=artifacts/hadoop/bootstrap.sh \
  3. --from-file=artifacts/hadoop/start-yarn-rm.sh \
  4. --from-file=artifacts/hadoop/start-yarn-nm.sh \
  5. --from-file=artifacts/hadoop/slaves \
  6. --from-file=artifacts/hadoop/core-site.xml \
  7. --from-file=artifacts/hadoop/hdfs-site.xml \
  8. --from-file=artifacts/hadoop/mapred-site.xml \
  9. --from-file=artifacts/hadoop/yarn-site.xml \
  10. --from-file=artifacts/hadoop/capacity-scheduler.xml \
  11. --from-file=artifacts/hadoop/container-executor.cfg \
  12. --from-file=artifacts/hadoop/hadoop-env.sh \
  13. --from-file=artifacts/hadoop/log4j.properties \
  14. --from-file=artifacts/hadoop/nodemanager_exclude.txt \
  15. --from-file=artifacts/hadoop/yarn-env.sh
  16. kubectl create configmap spark-config \
  17. --from-file=artifacts/spark/spark-bootstrap.sh \
  18. --from-file=artifacts/spark/spark-env.sh \
  19. --from-file=artifacts/spark/spark-defaults.conf

所有的配置完成后,可以可以使用 kubectl 命令来启动和管理集群了,我们编写了 Makefile,您可以直接使用该 Makefile 封装的命令实现部分的自动化。

参考:

https://www.kubernetes.org.cn/2568.html

传统应用迁移到kubernetes(Hadoop YARN)的更多相关文章

  1. hadoop yarn

    简介: 本文介绍了 Hadoop 自 0.23.0 版本后新的 map-reduce 框架(Yarn) 原理,优势,运作机制和配置方法等:着重介绍新的 yarn 框架相对于原框架的差异及改进:并通过 ...

  2. Hadoop Yarn框架原理解析

    在说Hadoop Yarn的原理之前,我们先来看看Yarn是怎样出现的.在古老的Hadoop1.0中,MapReduce的JobTracker负责了太多的工作,包括资源调度,管理众多的TaskTrac ...

  3. Hadoop Yarn框架详细解析

    在说Hadoop Yarn之前,我们先来看看Yarn是怎样出现的.在古老的Hadoop1.0中,MapReduce的JobTracker负责了太多的工作,包括资源调度,管理众多的TaskTracker ...

  4. 微服务开发有道之把项目迁移到Kubernetes上的5个小技巧

    我们将在本文中提供5个诀窍帮你将项目迁移到Kubernetes上,这些诀窍来源于过去12个月中OpenFaas社区的经验.下文的内容与Kubernetes 1.8兼容,并且已经应用于OpenFaaS ...

  5. [BigData - Hadoop - YARN] YARN:下一代 Hadoop 计算平台

    Apache Hadoop 是最流行的大数据处理工具之一.它多年来被许多公司成功部署在生产中.尽管 Hadoop 被视为可靠的.可扩展的.富有成本效益的解决方案,但大型开发人员社区仍在不断改进它.最终 ...

  6. Apache Hadoop YARN: 背景及概述

    从2012年8月开始Apache Hadoop YARN(YARN = Yet Another Resource Negotiator)成了Apache Hadoop的一项子工程.自此Apache H ...

  7. 深入浅出 Hadoop YARN

    一. Hadoop Yarn 是什么 在古老的 Hadoop1.0 中,MapReduce 的 JobTracker 负责了太多的工作,包括资源调度,管理众多的 TaskTracker 等工作.这自然 ...

  8. Hadoop - YARN 概述

    一 概述       Apache Hadoop YARN (Yet Another Resource Negotiator,还有一种资源协调者)是一种新的 Hadoop 资源管理器,它是一个通用资源 ...

  9. YARN分析系列之二 -- Hadoop YARN各个自模块说明

    先做如下声明,本代码版本是基于 3.1.2 版本. 其实,我们自己在写代码的时候,会有意识地将比较大的功能项独立成包,独立成module, 独立成项目,项目之间的关系既容易阅读理解,又便于管理. 如下 ...

随机推荐

  1. Getting started with Processing 第七章总结

    媒体 如何将文件导入 Processing 中 在 Processing 中,程序是通过应用 data 文件夹中的文件来显示的,这个文件夹可以通过菜单栏中的 Sketch>show sketch ...

  2. @Basic表示一个简单的属性 懒加载,急加载

    5.@Basic(fetch=FetchType,optional=true) 可选 @Basic表示一个简单的属性到数据库表的字段的映射,对于没有任何标注的getXxxx()方法,默认 即为 @Ba ...

  3. 差异基因分析:fold change(差异倍数), P-value(差异的显著性)

    在做基因表达分析时必然会要做差异分析(DE) DE的方法主要有两种: Fold change t-test fold change的意思是样本质检表达量的差异倍数,log2 fold change的意 ...

  4. English Voice of <<if were a boy >>

    <if i were a boy>中英文歌词: If I were a boy 如果我是个男孩 Even just for a day 就算只是一天 I' roll out of bed ...

  5. vue.js手机号验证是否正确

    {literal}          var mobile_mode=/^1[34578]\d{9}$/;       {/literal}       if(!mobile_mode.test(te ...

  6. array_column的作用

    从记录集中取出 last_name 列,用相应的 "id" 列作为键值: <?php // 表示由数据库返回的可能记录集的数组 $a = array( array( 'id' ...

  7. 将一台电脑上的虚拟机上的系统复制到另一台电脑的虚拟机上!!!and想询问大神们问题的解决办法??

    虚拟机是Oracle VM VitualBox版本 前段日子oracle老师让课下安装虚拟机+windows8+oracle数据库,但悲伤的我安了七八遍(重装系统+安装数据库+配置数据库)依旧在配置数 ...

  8. WDA基础十四:ALV字段属性配置表

    ALV配置表管理 一.字段属性配置表 对于可编辑的ALV不用这个,尽可能多的设置一些控制: 单元格类型:默认A,特殊选择 ZLYE_TYPE        E       A       1      ...

  9. GetMapping 和 PostMapping最大的差别(转)

    原文地址:GetMapping 和 PostMapping  Spring4.3中引进了{@GetMapping.@PostMapping.@PutMapping.@DeleteMapping.@Pa ...

  10. [转载]Python3编码问题详解

    原文:Python3的编码问题 Python3 最重要的一项改进之一就是解决了 Python2 中字符串与字符编码遗留下来的这个大坑.Python 编码为什么那么蛋疼?已经介绍过 Python2 字符 ...