在微服务的实践过程中,我们经常会问自己:什么样的应用应该做成微服务?将应用做成微服务时有什么需要注意的?本文针对在Kuberenetes中部署YARN集群遇到的问题,讨论微服务化需要做的工作以及什么样的应用是微服务友好的。
在YARN默认配置中,集群节点通过 ssh 启动:
在这个启动过程中,ssh 扮演了一个远程执行的角色;但远程执行、启动服务正是Kuberenets所做工作的一部分,因此需要对该过程进行如下改造:
The authenticity of host '9.111.143.205 (9.111.143.205)' can't be established.
ECDSA key fingerprint is SHA256:QQYvT8PFYzVL8oD5fIySTEH5LjPCN8BtayCDLsvp42k.
Are you sure you want to continue connecting (yes/no)?
在微服务的环境中不希望出现需要手动参与的环境,因些需要对unknown host进行设置;修改 ~/.ssh/config 如下:
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
在上述过程中,由于没有配置slaves文件,start-yarn.sh/start-dfs.sh 会仅启动本机的服务,例如 ResourceManager 或 NodeManager。根据此步骤制作如下的 Dockerfile:
Master 节点的 Dockerfile 如下:
FROM ubuntu:14.04
MAINTAINER Klaus Ma .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 有几个地方还有待改进:
DataNode和NodeManager的Dockerfile与之相似,但除了启动的服务不一样外,对YARN/HDFS配置文件的修改也有所区别,细节会在下面的篇幅介绍;具体可以参考 Dockefile.agent 和 agent_bootstrap.sh
在上面的篇幅中介绍了如何启动YARN/HDFS集群,但是各个节点启动后还需要彼此通信才能工作。因些需要修改YARN/HDFS相应的配置文件:core-site.xml, yarn-site.xml 和 hdfs-site.xml.
与ResourceManager/NodeManager通信相关的配置在yarn-site.xml和core-site.xml中,为了使ResourceManager和NodeManager可以相互通信,在镜像中制件了如下的模板:
core-site.xml
<property>
<name>fs.defaultFSname>
<value>hdfs://__HOSTNAME__:9000value>
property>
yarn-site.xml
<property>
<name>yarn.resourcemanager.addressname>
<value>__HOSTNAME__:8032value>
property>
<property>
<name>yarn.resourcemanager.scheduler.addressname>
<value>__HOSTNAME__:8030value>
property>
<property>
<name>yarn.resourcemanager.resource-tracker.addressname>
<value>__HOSTNAME__:8031value>
property>
<property>
<name>yarn.resourcemanager.admin.addressname>
<value>__HOSTNAME__:8033value>
property>
<property>
<name>yarn.resourcemanager.webapp.addressname>
<value>__HOSTNAME__:8088value>
property>
在不同的镜像中,HOSTNAME会被替换为不同的值:在master_bootstrap.sh中,被替换为容器的hostname;而在agent_bootstrap.sh中,由被替换为yarn_master。yarn_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-checkname>
<value>falsevalue>
property>
但是上面的配置并不能完全解决问题:虽然 NameNode 不再进行 ip/hostname 检测,但在访问 DataNode 的时候会取得错误的ip: NameNode 使用主机 ip 而不是容器 ip 与 DataNode 通信。
不同厂商在 Docker Hub 上都提供了Hadoop 镜像,但多为单一镜像且需要手动配置才能正常工作,例如 ssh的无密码访问。目前还没有社区版本的Hadoop镜像,但已经创建了HADOOP-13397进行需求的跟踪。
镜像 | 公司 | 备注 |
---|---|---|
sequenceiq/hadoop-docker | Hortonwork | 单一镜像,手动配置 |
cloudera/quickstart | Cloudra | 单一镜像,手动配置 |
maprtech/mapr-sandbox-base | MapR | 单一镜像 |
Kubernetes/Marathon等软件已经为应用提供了强大的部署、启动等功能,因此当集群软件向Kubernetes/Marathon迁移时应该注意以下几点:
在网络方面,以下几个方面可以有效的减少微服务化过程中遇到的问题:
http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html
https://github.com/k82cn/outrider/tree/master/kubernetes/imgs/yarn
https://issues.apache.org/jira/browse/HADOOP-13397
https://github.com/kubernetes/application-images/pull/8
http://mail-archives.apache.org/mod_mbox/hadoop-user/201607.mbox/%3CSG2PR04MB162977CFE150444FA022510FB6370%40SG2PR04MB1629.apcprd04.prod.outlook.com%3E
作者简介:
马达,IBM软件架构师;Kubernetes/Mesos代码贡献者。吉林大学毕业,主修网格计算/分布式系统;毕业后加入百度,现就职于IBM;一直从事分布式系统的相关工作。在资源管理,资源调度,分布式计算等方面有着丰富的经验。
博格利,80后的IT工程师,供职于中国联通研究院多年,主要从从事分布式系统的研究工作,在Mesos、Docker、Kubernetes方面有一定积累。