热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

YarnonDocker集群方案

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

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

  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的改造和微服务落地,关注大数据开源软件及微服务的前沿发展。


推荐阅读
  • 深入探索Node.js新框架:Nest.js第六篇
    在本文中,我们将深入探讨Node.js的新框架Nest.js,并通过一个完整的示例来展示其强大功能。我们将使用多个装饰器创建一个基本控制器,该控制器提供了多种方法来访问和操作内部数据,涵盖了常见的CRUD操作。此外,我们还将详细介绍Nest.js的核心概念和最佳实践,帮助读者更好地理解和应用这一现代框架。 ... [详细]
  • 本文探讨了将PEBuilder转换为DIBooter.sh的方法,重点介绍了如何将DI工具集成到启动层,实现离线镜像引导安装。通过使用DD命令替代传统的grub-install工具,实现了GRUB的离线安装。此外,还详细解析了bootice工具的工作原理及其在该过程中的应用,确保系统在无网络环境下也能顺利引导和安装。 ... [详细]
  • Docker 中创建 CentOS 容器并安装 MySQL 进行本地连接
    本文详细介绍了如何在 Docker 中创建 CentOS 容器,并在容器中安装 MySQL 以实现本地连接。文章内容包括镜像拉取、容器创建、MySQL 安装与配置等步骤。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • OpenAI首席执行官Sam Altman展望:人工智能的未来发展方向与挑战
    OpenAI首席执行官Sam Altman展望:人工智能的未来发展方向与挑战 ... [详细]
  • 在本文中,我们将探讨如何在Docker环境中高效地管理和利用数据库。首先,需要安装Docker Desktop以确保本地环境准备就绪。接下来,可以从Docker Hub中选择合适的数据库镜像,并通过简单的命令将其拉取到本地。此外,我们还将介绍如何配置和优化这些数据库容器,以实现最佳性能和安全性。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
  • 提升 Kubernetes 集群管理效率的七大专业工具
    Kubernetes 在云原生环境中的应用日益广泛,然而集群管理的复杂性也随之增加。为了提高管理效率,本文推荐了七款专业工具,这些工具不仅能够简化日常操作,还能提升系统的稳定性和安全性。从自动化部署到监控和故障排查,这些工具覆盖了集群管理的各个方面,帮助管理员更好地应对挑战。 ... [详细]
  • 当 EXCLUDE_DEAD 设置为 1 时,为何没有容器被移除? ... [详细]
  • 本文探讨了使用Python进行微服务架构设计的合理性和适用性。首先,介绍了微服务的基本概念及其在现代软件开发中的重要性。接着,通过具体的业务场景,详细分析了Python在微服务架构设计中的优势和挑战。文章还讨论了在实际应用中可能遇到的问题,并提出了相应的解决方案。希望本文能够为从事Python微服务开发的技术人员提供有价值的参考和指导。 ... [详细]
  • CentOS 7环境下Jenkins的安装与前后端应用部署详解
    CentOS 7环境下Jenkins的安装与前后端应用部署详解 ... [详细]
  • Docker网络基础探讨了如何通过高效的技术手段实现跨主机容器间的顺畅通信与访问。本文深入分析了Docker网络架构,特别是其在多主机环境下的应用,为Go语言开发者提供了宝贵的实践指导和理论支持。 ... [详细]
  • 本文介绍了在Windows 10系统下使用VirtualBox虚拟机环境部署CentOS 7.2,并在其上安装Docker的具体步骤。针对宝塔面板在Docker容器中磁盘空间限制为8GB的问题,提供了详细的解决方案和优化建议,确保用户能够高效利用有限的存储资源。 ... [详细]
  • 本文详细介绍了在 Docker 环境中部署 Zookeeper 镜像的最佳实践与步骤。首先,通过 `docker search zookeeper` 命令查找可用的 Zookeeper 镜像。接着,使用 `docker pull zookeeper` 或 `docker pull jplock/zookeeper` 命令下载所需的镜像。文章还涵盖了配置文件的优化、网络设置以及容器运行时的注意事项,为用户提供了一套完整的部署方案。 ... [详细]
author-avatar
赵春柱_626
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有