写点什么

数据中心的 Yarn on Docker 集群方案

  • 2017-03-21
  • 本文字数:4126 字

    阅读完需:约 14 分钟

当前数据中心存在的问题

数据中心中的应用一般独立部署,为了保证环境隔离与方便管理,保证应用最大资源 数据中心中普遍存在如下问题:

  1. 主机资源利用率低
  2. 部署和扩展复杂
  3. 资源隔离无法动态调整
  4. 无法快速响应业务

方案选型

Yarn on Docker 有哪些特点?

彻底隔离队列

  • 为了合理利用 Hadoop yarn 的资源,队列间会互相抢占计算资源,造成重要任务阻塞
  • 根据部门申请的机器数量划分 Yarn 集群方便财务管理
  • 更细粒度的资源分配

统一的资源分配

  • 每个 NodeManager 和容器都可以限定 CPU、内存资源

  • Yarn 资源划分精确到 CPU 核数和内存大小

弹性伸缩性服务

  • 每个容器中运行一个 NodeManager,增减 yarn 资源只需增减容器个数

  • 可以指定每个 NodeManager 拥有的计算资源多少,按需申请资源

Docker 集群管理系统:Kubernetes or Swarm?

关于容器集群管理系统的选型,用 Kubernetes 还是 Swarm?我们结合自己的经验和业务需求,对比如下:

特性

Kubernetes

Swarm

功能

功能强大

功能单一,基本够用

扩展

难以扩展,灵活性低

丰富的插件机制,兼容 docker api

文档

文档少,当时用的版本较低

docker 官方文档支持,丰富易读

使用

结构复杂,部署麻烦

简单易用

基于以上四点,我们最终选择了 Swarm,它基本满足我们的需求,掌握和开发时常较短。

解决方案的优势

选用 Yarn on Docker 的好处有以下两点:

Swarm 统一集群资源调度

  • 统一资源
  • 增加 Docker 虚拟化层,降低运维成本

增加 Hadoop 集群资源利用率

  • For datacenter:避免了静态资源隔离
  • For cluster:加强集群内部资源隔离

系统架构

比如数据中心中运行的 Hadoop 集群,我们将 HDFS 依然运行在物理机上,即 DataNode 依然部署在实体机器上,将 Yarn 计算层运行在 Docker 容器中,整个系统使用二层资源调度,Spark、Flinek、MapReduce 等应用运行在 Yarn 上。

Swarm 调度最底层的主机硬件资源,CPU 和内存封装为 Docker 容器,容器中运行 NodeManager,提供给 Yarn 集群,一个 Swarm 集群中可以运行多个 Yarn 集群,形成圈地式的 Yarn 计算集群。

具体流程

  1. swarm node 向 swarm master 注册主机资源并加入到 swarm cluster 中
  2. swarm master 向 cluster 申请资源请求启动容器
  3. swarm 根据调度策略选择在某个 node 上启动 docker container
  4. swarm node 的 docker deamon 根据容器启动参数启动相应资源大小的 NodeManager
  5. NodeManager 自动向 YARN 的 ResourceManager 注册资源一个 NodeManager 资源添加完成。

Swarm 为数据中心做容器即主机资源调度,每个 swarm node 的节点结构如图:

一个 Swarm node 就是一台物理机,每台主机上可以起多个同类型的 docker container,每个 container 的资源都有限制包括 CPU、内存 NodeManager 容器只需要考虑本身进程占用的资源和需要给主机预留资源。假如主机是 24 核 64G,我们可以分给一个容器 5 核 12G,NodeManager 占用 4 核 10G 的资源提供给 Yarn。

技术详解

(一) 镜像制作与发布

镜像制作和发布流程如下图:

用户从客户端提交代码到 Gitlab 中,需要包含 Dockerfile 文件,通过集成了 docker 插件的 Jenkins 的自动编译发布机制,自动 build 镜像后 push 到 docker 镜像仓库中,同一个项目每提交一次代码都会重新 build 一次镜像,生成不同的 tag 来标识镜像,Swarm 集群使用该镜像仓库就可以直接拉取镜像。

Dockerfile 的编写技巧

Dockerfile 相当于 docker 镜像的编译打包流程说明,其中也不乏一些技巧。

很多应用需要配置文件,如果想为每次启动容器的时候使用不同的配置参数,可以通过传递环境变量的方式来修改配置文件,前提是需要写一个 bash 脚本,脚本中来处理配置文件,再将这个脚本作为 entrypoint 入口,每当容器启动时就会执行这个脚本从而替换配置文件中的参数,也可以通过 CMD 传递参数给该脚本。

启动容器的时候通过传递环境变量的方式修改配置文件:

复制代码
docker run -d
--net=mynet
-e NAMESERVICE=nameservice
-e ACTIVE_NAMENODE_ID=namenode29 \
-e STANDBY_NAMENODE_ID=namenode63 \
-e HA_ZOOKEEPER_QUORUM=zk1:2181,zk2:2181,zk3:2181 \
-e YARN_ZK_DIR=rmstore \
-e YARN_CLUSTER_ID=yarnRM \
-e YARN_RM1_IP=rm1 \
-e YARN_RM2_IP=rm2 \
-e CPU_CORE_NUM=5
-e NODEMANAGER_MEMORY_MB=12288 \
-e YARN_JOBHISTORY_IP=jobhistory \
-e ACTIVE_NAMENODE_IP=active-namenode \
-e STANDBY_NAMENODE_IP=standby-namenode \
-e HA=yes \
docker-registry/library/hadoop-yarn:v0.1 resourcemanager

最后传递 resourcemanager 或者 nodemanager 参数指定启动相应的服务。

(二) 集群管理

我们自行开发程序调用 docker 的 API 来管理集群,也可以通过其他开源可视化页面来管理集群,比如 shipyard。

(三)自定义网络

Docker 容器跨主机互访一直是一个问题,Docker 官方为了避免网络上带来的诸多麻烦,故将跨主机网络开了比较大的口子,而由用户自己去实现。我们开发并开源了 Shrike 这个 docker 网络插件,大家可以在这里下载到: https://github.com/talkingdata/shrike

目前 Docker 跨主机的网络实现方案也有很多种, 主要包括端口映射,ovs, fannel 等。但是这些方案都无法满足我们的需求,端口映射服务内的内网 IP 会映射成外网的 IP,这样会给开发带来困惑,因为他们往往在跨网络交互时是不需要内网 IP 的,而 ovs 与 fannel 则是在基础网络协议上又包装了一层自定义协议,这样当网络流量大时,却又无端的增加了网络负载,最后我们采取了自主研发扁平化网络插件,也就是说让所有的容器统统在大二层上互通。架构如下:

我们首先需要创建一个 br0 自定义网桥,这个网桥并不是通过系统命令手动建立的原始 Linux 网桥,而是通过 Docker 的 cerate network 命令来建立的自定义网桥,这样避免了一个很重要的问题就是我们可以通过设置 DefaultGatewayIPv4 参数来设置容器的默认路由,这个解决了原始 Linux 自建网桥不能解决的问题. 用 Docker 创建网络时我们可以通过设置 subnet 参数来设置子网 IP 范围,默认我们可以把整个网段给这个子网,后面可以用 ipam driver(地址管理插件)来进行控制。还有一个参数 gateway 是用来设置 br0 自定义网桥地址的,其实也就是你这台宿主机的地址。

复制代码
docker network create
--opt=com.docker.network.bridge.enable_icc=true
--opt=com.docker.network.bridge.enable_ip_masquerade=false
--opt=com.docker.network.bridge.host_binding_ipv4=0.0.0.0
--opt=com.docker.network.bridge.name=br0
--opt=com.docker.network.driver.mtu=1500
--ipam-driver=talkingdata
--subnet= 容器 IP 的子网范围
--gateway=br0 网桥使用的 IP, 也就是宿主机的地址
--aux-address=DefaultGatewayIPv4= 容器使用的网关地址
mynet

IPAM 驱动是专门管理 Docker 容器 IP 的, Docker 每次启停与删除容器都会调用这个驱动提供的 IP 管理接口,然后 IP 接口会对存储 IP 地址的 Etcd 有一个增删改查的操作。此插件运行时会起一个 Unix Socket, 然后会在 docker/run/plugins 目录下生成一个.sock 文件,Docker daemon 之后会和这个 sock 文件进行沟通去调用我们之前实现好的几个接口进行 IP 管理,以此来达到 IP 管理的目的,防止 IP 冲突。

通过 Docker 命令去创建一个自定义的网络起名为“mynet”,同时会产生一个网桥 br0,之后通过更改网络配置文件(在 /etc/sysconfig/network-scripts/ 下 ifcfg-br0、ifcfg- 默认网络接口名)将默认网络接口桥接到 br0 上,重启网络后,桥接网络就会生效。Docker 默认在每次启动容器时都会将容器内的默认网卡桥接到 br0 上,而且宿主机的物理网卡也同样桥接到了 br0 上了。其实桥接的原理就好像是一台交换机,Docker 容器和宿主机物理网络接口都是服务器,通过 veth pair 这个网络设备像一根网线插到交换机上。至此,所有的容器网络已经在同一个网络上可以通信了,每一个 Docker 容器就好比是一台独立的虚拟机,拥有和宿主机同一网段的 IP,可以实现跨主机访问了。

(四)集群监控

如果使用 shipyard 管理集群会有一个单独的监控页面,可以看到一定时间段内的 CPU、内存、IO、网络使用状况。

我们自己开发了基于大数据的监控系统 Owl 也即将支持 docker 容器的监控。 https://github.com/TalkingData/OWL-v3

性能瓶颈与优化

大家可能会担心自定义网络的性能问题,为此我们用 iperf 进行了网络性能测试。我们对比了不同主机容器间的网速,同一主机上的不同容器和不同主机间的网速,结果如下表:

从表中我们可以看到,在这一组测试中,容器间的网速与容器是在想通主机还是在不同主机上的差别不大,说明我们的网络插件性能还是很优异的。

Hadoop 配置优化

因为使用 docker 将原来一台机器一个 nodemanager 给细化为了多个,会造成 nodemanager 个数的成倍增加,因此 hadoop 的一些配置需要相应优化。

  • yarn.nodemanager.localizer.fetch.thread-count 随着容器数量增加,需要相应调整该参数
  • yarn.resourcemanager.amliveliness-monitor.interval-ms 默认 1 秒,改为 10 秒,否则时间太短可能导致有些节点无法注册
  • yarn.resourcemanager.resource-tracker.client.thread-count 默认 50,改为 100,随着容器数量增加,需要相应调整该参数
  • yarn.nodemanager.pmem-check-enabled 默认 true,改为 false,不检查任务正在使用的物理内存量
  • 容器中 hadoop ulimit 值修改,默认 4096,改成 655350

关于未来

我们未来规划做的是 DC/OS,基于 Docker 的应用自动打包编译分发系统,让开发人员可以很便捷的申请资源,上下线服务,管理应用。要达到这个目标还有很多事情要做:

  • Service Control Panel:统一的根据服务来管理的 web 页面
  • Load balance:容器根据机器负载情况自动迁移
  • Scheduler:swarm 调度策略优化
  • 服务配置文件:提供镜像启动参数的配置文件,所有启动参数可通过文件配置
  • 监控:服务级别的监控

(点击放大图像)

作者简介

宋净超,TalkingData 大数据及云计算工程师。拥有多年的 Hadoop 大数据集群部署、管理、优化和实战经验,对 Hadoop 和 Docker 的结合落地进行了丰富的探索,主导了 TalkingData 的 Yarn on Docker 的改造和微服务落地,关注大数据开源软件及微服务的前沿发展。


感谢木环对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-03-21 17:314646

评论

发布
暂无评论
发现更多内容

阿里灵杰融合智能算力,全栈AI服务为探索者铺路

阿里云大数据AI技术

人工智能 大数据 企业号九月金秋榜

软件测试 | 测试开发 | 测试开发基础 mvn test | 利用 Maven Surefire Plugin 做测试用例基础执行管理

测吧(北京)科技有限公司

maven

FinClip 8 月例行汇报,这个月干了啥

FinClip

谈谈我对云原生与软件供应链安全的思考

阿里巴巴中间件

阿里云 云原生 容器服务

Dubbo 3 StateRouter:下一代微服务高效流量路由

阿里巴巴中间件

阿里云 开源 微服务 dubbo 中间件

在线数据迁移,数字化时代的必修课 —— 京东云数据迁移实践

京东科技开发者

数据 数据迁移 上云 redis'

从零教你使用MindStudio进行Pytorch离线推理全流程

华为云开发者联盟

Python 人工智能 企业号九月金秋榜

分布式团队的高效站立会说明书 | Liga译文

LigaAI

高效工作 敏捷开发 开发团队 每日站会 企业号九月金秋榜

ArkID:开源IDaaS系统插件OAuth2轻松实现单点登录高效进行应用服务集成

龙归科技

oauth2.0 SSO Idaas

直播回顾|应用上容器的最佳实践技术沙龙

BoCloud博云

云计算 容器 云原生

Substrate技术及生态8月大事记 | 波卡发布新版本,XCM协议更新

One Block Community

区块链 技术 开发者 Substrate 更新

大数据培训前景怎么样

小谷哥

基于阿里云Serverless函数计算开发的疫情数据统计推送机器人

Serverless Devs

EMQX +计算巢:构建云上物联网平台,轻松实现百万级设备连接

阿里云弹性计算

物联网 计算巢

2022年最受工程师欢迎的10款抓包工具有哪些?不止Wireshark和Tcpdump哦!

wljslmz

Wireshark fiddler 网络技术 网络抓包 9月月更

解锁云原生新场景 | 云原生加速云边端一体化发展

York

容器 云原生 边缘计算 边云协同 边缘云原生

一文带你认识AscendCL

华为云开发者联盟

人工智能 昇腾 企业号九月金秋榜

二本4年Java经验,五面阿里(定薪45K)

退休的汤姆

Java 程序员 阿里 面经 秋招

游戏技术加速数实融合,网易伏羲挖掘机器人首次曝光

网易伏羲

人工智能 机器学习 工程实践

音视频开发进阶|第六讲:色彩和色彩空间·上篇

ZEGO即构

音视频开发 色彩 色彩空间

公链开发功能详细分析

开发微hkkf5566

Aptos VS Sui,盘点两大 Move 系新公链的创新异同

TinTinLand

区块链 公链 编程语言‘ Move

利用GCC插件实现代码分析和安全审计

科技怪咖

DevOps 团队如何防御 API 攻击

SEAL安全

DevOps DevSecOps 软件供应链安全

零基础如何参加大数据培训

小谷哥

学员参加前端培训哪里比较靠谱?

小谷哥

从云计算到函数计算

Serverless Devs

云计算 阿里云 AWS

跟我学Python图像处理丨何为图像的灰度非线性变换

华为云开发者联盟

Python 人工智能 图片处理 企业号九月金秋榜

首次公开到知乎爆火!基于SpringCloud+SpringBoot+Vue电子版项目实战教程,附完整源码

退休的汤姆

Java spring 程序员 面试题 阿里

零基础学习java培训是否适合参加

小谷哥

在java培训中心怎样才能快速学习?

小谷哥

数据中心的Yarn on Docker集群方案_语言 & 开发_宋净超_InfoQ精选文章