咖啡香

在Kubernetes中部署YARN

在微服务的实践过程中,我们经常会问自己:什么样的应用应该做成微服务?将应用做成微服务时有什么需要注意的?本文针对在Kuberenetes中部署YARN集群遇到的问题,讨论微服务化需要做的工作以及什么样的应用是微服务友好的。

启动 YARN/HDFS 集群

在YARN默认配置中,集群节点通过 ssh 启动:

在这个启动过程中,ssh 扮演了一个远程执行的角色;但远程执行、启动服务正是Kuberenets所做工作的一部分,因此需要对该过程进行如下改造:

在上述过程中,由于没有配置slaves文件,start-yarn.sh/start-dfs.sh 会仅启动本机的服务,例如 ResourceManager 或 NodeManager。根据此步骤制作如下的 Dockerfile:

Master 节点的 Dockerfile 如下:

FROM ubuntu:14.04
MAINTAINER Klaus Ma <klaus1982.cn@gmail.com>

RUN apt-get update && apt-get -y install openjdk-7-jdk openssh-server

COPY hadoop-2.7.2.tar.gz /opt/

RUN cd /opt/ && tar zxvf hadoop-2.7.2.tar.gz && rm hadoop-2.7.2.tar.gz

COPY ./master_bootstrap.sh /opt/bootstrap.sh
COPY core-site.xml.template /root/
COPY yarn-site.xml.template /root/
COPY hdfs-site.xml.template /root/

COPY .ssh /root/.ssh

RUN chmod +x /opt/bootstrap.sh

# Hdfs ports
EXPOSE 31010 50020 50070 50075 50090 8020 9000
# Mapred ports
EXPOSE 19888
#Yarn ports
EXPOSE 8030 8031 8032 8033 8040 8042 8088
#Other ports
EXPOSE 49707 2122

ENTRYPOINT /opt/bootstrap.sh

master_bootstrap.sh 文件内容如下:

#!/bin/sh

export JAVA_HOME=/usr

HADOOP_PREFIX=/opt/hadoop-2.7.2
HADOOP_YARN_HOME=$HADOOP_PREFIX
HADOOP_CONF_DIR=/opt/hadoop-2.7.2/etc/hadoop

sed "s/__HOSTNAME__/"$(hostname)"/g" /root/core-site.xml.template > $HADOOP_CONF_DIR/core-site.xml
sed "s/__HOSTNAME__/"$(hostname)"/g" /root/yarn-site.xml.template > $HADOOP_CONF_DIR/yarn-site.xml
sed "s/__HOSTNAME__/"$(hostname)"/g" /root/hdfs-site.xml.template > $HADOOP_CONF_DIR/hdfs-site.xml

mkdir /opt/hadoop272/dfs/name -p
mkdir /opt/hadoop272/dfs/data -p

$HADOOP_PREFIX/bin/hdfs namenode -format yarn_272_hdfs

$HADOOP_PREFIX/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script hdfs start namenode
$HADOOP_PREFIX/sbin/yarn-daemon.sh --config $HADOOP_CONF_DIR start resourcemanager

while true; do sleep 1000; done

上面的Dockerfile 有几个地方还有待改进:

  1. 在Dockerfile 使用了多次 COPY,这样会增加镜像的layer数目
  2. 目前使用了预先生成的 .ssh 文件,可以通过 master_bootstrap.sh 实时生成
  3. master_bootstrap.sh 文件中,每次都会对HDFS进行格式化,如果外挂存储,则应该每次都重新格式化
  4. 目前将 ResourceManager/NodeManager 启动在同一个容器中,后续会分别部署在不同的容器中
  5. 目前的 YARN/HDFS 还只能后台运行,需要改进检测部分:当没有java程序运行时,容器退出

DataNode和NodeManager的Dockerfile与之相似,但除了启动的服务不一样外,对YARN/HDFS配置文件的修改也有所区别,细节会在下面的篇幅介绍;具体可以参考 Dockefile.agentagent_bootstrap.sh

连接ResourceManager与NodeManager

在上面的篇幅中介绍了如何启动YARN/HDFS集群,但是各个节点启动后还需要彼此通信才能工作。因些需要修改YARN/HDFS相应的配置文件:core-site.xml, yarn-site.xmlhdfs-site.xml.

ResourceManager/NodeManager通信相关的配置在yarn-site.xmlcore-site.xml中,为了使ResourceManager和NodeManager可以相互通信,在镜像中制件了如下的模板:

core-site.xml

<property>
    <name>fs.defaultFS</name>
    <value>hdfs://__HOSTNAME__:9000</value>
</property>

yarn-site.xml

<property>
    <name>yarn.resourcemanager.address</name>
    <value>__HOSTNAME__:8032</value>
</property>

<property>
    <name>yarn.resourcemanager.scheduler.address</name>
    <value>__HOSTNAME__:8030</value>
</property>
<property>
    <name>yarn.resourcemanager.resource-tracker.address</name>
    <value>__HOSTNAME__:8031</value>
</property>
<property>
    <name>yarn.resourcemanager.admin.address</name>
    <value>__HOSTNAME__:8033</value>
</property>
<property>
    <name>yarn.resourcemanager.webapp.address</name>
    <value>__HOSTNAME__:8088</value>
</property>

在不同的镜像中,__HOSTNAME__会被替换为不同的值:在master_bootstrap.sh中,被替换为容器的hostname;而在agent_bootstrap.sh中,由被替换为yarn_masteryarn_master是ResourceManager在Kubernetes的Service,因此在配置了Kube-DNS后,各个 NodeManager 节点可以找到该ResourceManager节点,并与之通信。

在进行了上述配置后,ResourceManager与NodeManager可以正常通信;但是 NameNode 和 DataNode 仍然无法通信。这主要是由于 NameNode 会对连接进来的DataNode进行 ip/hostname 的检查,由于没有对DataNode配置相应DNS,NameNode会拒绝末知的 ip/hostname。HDFS提供了如下的配置,可以忽略 ip/hostname的检查:

hdfs-site.xml

<property>
    <name>dfs.namenode.datanode.registration.ip-hostname-check</name>
    <value>false</value>
</property>

但是上面的配置并不能完全解决问题:虽然 NameNode 不再进行 ip/hostname 检测,但在访问 DataNode 的时候会取得错误的ip: NameNode 使用主机 ip 而不是容器 ip 与 DataNode 通信。

已知的 Hadoop 镜像

不同厂商在 Docker Hub 上都提供了Hadoop 镜像,但多为单一镜像且需要手动配置才能正常工作,例如 ssh的无密码访问。目前还没有社区版本的Hadoop镜像,但已经创建了HADOOP-13397进行需求的跟踪。

镜像 公司 备注
sequenceiq/hadoop-docker Hortonwork 单一镜像,手动配置
cloudera/quickstart Cloudra 单一镜像,手动配置
maprtech/mapr-sandbox-base MapR 单一镜像

问题总结

相关讨论


comments powered by Disqus