DockOne微信分享( 八十八):PPTV聚力传媒的Docker与DevOps

本文讲的是DockOne微信分享( 八十八):PPTV聚力传媒的Docker与DevOps【编者的话】DevOps是2009年前后提出的一个概念,提倡开发(Development)和运维(Operations)这两个领域的高度协同。从而在完成高频率部署的同时,提高生产环境的可靠性、稳定性、弹性和安全性。本次分享介绍了PPTV聚力传媒以Docker技术为支撑,在DevOps方面做的优化,包括:

  1. DevOps简介
  2. Docker在PPTV的应用
  3. DevOps与Docker的结合
  4. 实现方案

DevOps简介

首先简单介绍一下DevOps,DevOps通常指的是2009年前后兴起的一个概念,提倡开发和IT运维之间的高度协同,主要目的在于提高用户和业务需求提高产品的交付能力与效率。

相信对很多朋友来说DevOps已经不是陌生的词。到今天为止,可能已经有很多公司在尝试通过Docker实现DevOps。可至今也并没有一个完善的DevOps实现方案和标准。

Docker在PPTV的应用

PPTV基于Docker打造的DCOS平台。底层基于Mesos + Marathon为核心,结合Docker和Nginx,在此基础上开发了DCOS管理平台。包括权限管理模块、统一日志管理模块、IP池管理模块、存储管理模块、服务发现模块,并与持续集成平台jenkins集成,实现应用容器的创建、运行。

Mesos、Marathon、Docker、Jenkins大家应该都有了解,这里就不多说了。下边主要介绍PPTV的Docker使用情况。

目前为止PPTV的测试环境基本上都已经迁移到了Docker上,生产环境的容器化还在进行中。所以后边的内容主要是与测试环境的架构相关。

功能框架

图 1

当前架构和发布流程

图 2

容器网络

我们采用了网络桥接的方式,基于Docker的bridge模式,将默认的docker bridge网桥替换为linux bridge,把linux bridge网段的IP加入到容器里,实现容器与传统环境应用的互通。

创建一个使用linux bridge的docker network :

docker network create --gateway 10.199.45.200 --subnet 10.199.45.0/24 -o com.docker.network.bridge.name=br-oak --aux-address "DefaultGatewayIPv4=10.199.45.1"  oak-net

该命令中创建了一个docker bridge网络,并与Docker所在主机的br-oak网桥做桥接。该网络的使用了10.199.45.0/24这个子网,同时通过--aux-address "DefaultGatewayIPv4=10.199.45.1"这个参数将容器启动时的网关指向到10.199.45.1。

关键参数:--aux-address "DefaultGatewayIPv4=10.199.45.1"。

使用桥接的方式,需要考虑IPAM。我们在DCOS管理平台中加入了IP池管理模块,实现全局的IP管控,并提供请求申请IP的接口。

图 3

思路是以Marathon上的App信息作为数据源,定期去调用Marathon的API更新IP列表。当我们要在Marathon上创建一个使用固定IP的容器时,首先会请求IP池管理模块的IP分配接口,请求的时候把App ID发给分配接口,管理平台根据App ID判断这个应用是否是新应用,如果是新应用则从IP池中返回一个未使用的IP,并将此IP与应用关联。

容器run起来的时候自动添加 -- net 和-- ip 参数指定容器IP。

图 4

容器存储

容器存储驱动

我们的OS用的是CentOS。所以在过去的一段时间,使用Loop模式的DeviceMapper作为存储驱动,是Docker默认的,在使用过程中遇到一些问题。

图 5

如上面所示问题,不只一次出现,目前都没有完全解决,最终只能用重启Docker的方法。如果在生产环境中遇到这样的问题,应该是大家不希望看到的。

经过对比(对比文章为:《PPTV聚力传媒DCOS Docker存储方式的研究选型》,这里不详细说明),我们决定在Btrfs和DeviceMapper的Direct LVM中选定一个存储驱动。对于我们目前打算用Docker上线的服务,主要关注从几百KB到几MB大小的文件,只需考虑读,写的操作是采用挂载volume的方式,不会直接写在容器里。在读的方面,DeviceMapper比Btrfs性能略好。在稳定性方面的比较,由于线下的试验并不能完全模仿线上的场景,初步打算上线时一部分容器运行在DeviceMapper存储驱动的环境下,一部分容器运行在Btrfs存储驱动的环境下,进行观察、比较。

容器外部卷使用GlusterFS,以分布式存储支持容器持久化数据。比如应用日志和应用静态文件。选GlusterFS的原因,因为GlusterFS此前公司内部一直在使用,足以满足测试环境的存储需求。

容器日志管理

将应用日志统一收集到GlusterFS上。在Gluster上建了一个log volume ,将此volume挂载到每一台mesos slave主机上,比如 /home/logs。

容器启动的时候加上volume参数,比如容器APP1启动的时候添加 –v /home/logs/app1:/home/logs。

这种做法可以在测试环境中解决容器数据持久化的问题,但是在线上环境中不建议这样做。线上环境我们目前考虑的做法是,将容器日志目录挂载到宿主机上,再通过Logstash或其他方式,统一收集。

服务发现

服务发现模块订阅了Marathon的消息,我们对Marathon App的label属性做了约定,属性里包含了这个App的IP、服务端口、服务域名等信息。每当Marathon上有App创建、停止、删除。服务模块都能接收到相应的消息,并将获取到这些信息后处理后更新到Nginx和DNS中。

Label属性:

图 6

图 7

图 8

DevOps与Docker的结合

Docker的口号是Build, Ship, and Run Any App, Anywhere。所以使用Docker的理想状态是这样的 :

图 9

而通过Docker实现DevOps的理想流程应该是这样的:

图 10

但是实际的情况通常是:

图 11

在测试环境里测试通过的镜像,很有可能是不能直接拿到线上RUN起来的。因为测试环境和线上环境的架构不一致,或者是配置不一致。

比如上边图里的App1 -> Redis1 ,就有可能存在两个问题:

  1. 线上环境的配置文件里Redis1的链接地址可能是线上环境Redis IP。而线下的配置是线下的Redis IP。
  2. 线上的Redis有可能是Redis集群,比如端口是19000。而线下Redis可能是单节点,服务端口是6379。 除此之外可能还有其他的配置参数不一致的问题。

解决上边两个问题的方法就是保证线下线上配置一致。

在过去的解决办法中:

对于问题1,通常各项目各组件之间调用的时候通过域名去调用,线上环境通过DNS解析域名,线下环境一般会绑host。

对于问题2,需要在项目初期就规划好,线下和线上是否使用相同的端口。如果后期想要统一配置则修改服务端口,有可能会导致很多未知的问题产生,代价太大。

线上线下配置不一致,应该是在很多公司都存在的情况,而且这样的情况很有可能会造成线上发布的问题。以我们自己的实际情况为例。再看看上边提到我们当前的发布流程:

图 12

我们通过Jenkins编译好了测试环境的应用包,在编译的过程中将应用包里的配置文件替换成线下的配置,然后通过挂载的方式,把应用包放到容器中运行。当测试通过之后,再通过Jenkins编译线上环境的应用包,这次编译的过程中会将配置文件替换成线上的配置。最后将应用包提交给线上运维发布。也就是说我们最终发布到线上的应用包,其实是没有经过测试的。也因此出过生产事故,幸运的是有灰度发布,同时及时回退,降低了影响范围。

为了尽量接近上边的Docker实现DevOps的理想流程,我们要达到的目标:

  1. 在Jenkins构建项目的产出物为包含了应用包(代码+线上配置)和环境(例如Tomcat)的Docker 大镜像。
  2. 在测试环境中模拟线上架构,保证环境尽量一致。
  3. 测试环境下测试通过的大镜像可以直接在线上发布。在测试环境部署大镜像,执行测试任务,测试通过后,运维将大镜像发布到线上环境。

而要达到这个目标,我们需要解决的问题:

  1. 在Docker集群中运行DB、ZooKeeper、MySQL等需要持久化数据的组件。
  2. 保证线上线下配置一致,包括访问链接和服务端口统一。 3.测试环境可能同时存在多套相同应用,需要实现环境隔离,保证每套环境能使用相同的配置,并行进行不同测试。

实现方案

问题 1

在没有Docker之前,在测试环境中模拟线上环境的架构,是很不现实的,需要大量的人力和物力。而借助Docker,我们可以轻松的创建很多套环境出来,只要有相应的镜像。而对于需要持久化数据的文件,因为在测试环境中访问压力小,我们采用GlusterFS存储,同时对CPU,内存等计算资源超配,最大限度的压榨服务器资源。

问题 2、3

我们希望实现的方案尽量的简单,影响尽量小。所以结合服务发现模块,我们对App的label重新做了约定,将测试环境隔离为一套集成环境、多套功能环境。同时每套环境使用各自的一套DNS。尽可能的在测试环境中模拟线上的架构。

图 13

如上图,最终达到的效果:

一套完整的集成测试环境,包括主服务、Redis、MySQL、DB、ZooKeepoer等,供其他功能环境测试调用。环境内部各项目各组件调用,都使用与线上一致的地址。比如域名,DNS负责解析测试环境内部域名。

多套功能测试环境(上图只画了一套),包含需要进行功能测试的项目,各项目在功能环境中有各自的Redis、MySQL、DB等服务,配置与集成环境相同,跨项目调用的时候,默认调用集成环境。通过dns解析区分集成测试环境和功能测试环境。

完成到这一步,我们基本上能够保证大部分项目的配置、环境一致了。同时因为在Jenkins构建的产出物就是Docker镜像,在环境一致的前提下,通过测试的镜像是可以直接在线上环境中正常运行的。当然也不能排除,有一些配置和项目,确实是无法做到完全一致,那就只能尽量减小差异化。特殊项目通过其他特殊途径处理。

简单小结一下我们将Docker与DevOps结合的主要思路:在尽可能的减小测试环境与线上环境的差异的前提下,在测试环境同时部署多套运行环境进行测试,同时借助Docker的Build、Ship、and Run特性,提高开发和IT运维之间的协同度,提高项目的交付能力与效率。

Q&A

Q:线上和线下环境不一致的问题,通过配置中心,比如文件或者安全变量,容器App启动读取文件或者变量,就能过去正确的配置,这样方式pptv实践为什么不采用这个方法呢?

A:我们线上环境是有配置中心的,但是因为管理上的原因,配置中心主要是管理系统级别的配置,和业务相关的配置不放在配置中心里。而且我们想要做到的效果是使用相同的配置在线下线上环境跑,通过配置中心来做的话,只是把配置项做成了变量,配置实际上还是有差异的。

Q:DB变更流程怎么控制的,PPTV的业务中是否涉及到分库分表,又采用了哪些手段来针对测试库与生产库的数据变更带来对业务的影响?

A:DB变更主要通过流程去规范,比如分库分表、表结构变更,需要提前1天以上申请,由DBA评估审核,涉及数据库的更新必须避开业务高峰期,选择凌晨或者早上8点前。技术上,要求业务方在数据库变更应该有备份脚本,备份需要更新的数据。

Q:如何解决发布的时候Nginx频繁reload问题?对容器的Swap有限制么?

A:Marathon上有变更的时候不会立即触发reload,首先会将变更的信息记录到DB中,然后有间隔的批量同步触发reload,Swap目前没有做配置

Q:1、Redis、MySQL、DB、ZooKeeper这些如果跑在容器,数据初始化持久化的方案是什么,2、linux bridge网络方案 有没有对比过Calico Contiv等?

A:1. 挂载外部卷GlusterFS实现持久化存储 。 2.对比过Calico,可以参考之前的一篇文章《PPTV Docker集群的网络方案选型》,Contiv没有做过对比。

Q:持续组件ZooKeeper、MySQL之类的是怎么和应用集成的,是一个整体镜像还是单个镜像组合的?

A:ZooKeeper、MySQL是不同镜像,运行在不同容器中。

Q:请问服务自动发现怎么搞的?新手,不知如何将Node注册进HAProxy或Nginx?

A:对Marathon的label属性进行约定,默认label属性是没有意义的,可以在程序中判断label是否符合约定条件,并触发注册、修改操作。

Q:您好,请问你们的DNS是怎么做的,单点故障问题是如何解决的?

A:DNS也运行在由Marathon调度的容器中,Marathon实现故障自愈,DNS重启的同时将触发服务发现的同步操作。

Q:灰度发布回退是回退images还是直接回退Docker中的应用包呢,回退前如果改过Volume中数据库话,数据库也一起回退?遇到什么问题么?

A:目前线上环境的容器化还在进行中,将来会是回退images。线上的数据库不会跑在容器中,回退的时候数据库也回退,和没有用容器的时候流程一样。

Q:在生产环境,一个App ID会存在需要多个容器的情况,也就需要多个IP。按上述使用方式应该会有问题。这块是如何解决呢?

A:在生产环境中在Marathon上层封装了一套发布系统,同一个项目创建多个容器,会在Marathon上创建多个App ID,Marathon上的信息对外不可见。

Q:我想问,使用bridge,10.199.45.0/24,会不会IP耗尽?还有有没有测试过bridge的效率?

A:10.199.45.0/24 只是举个例子,实际场景下会有多个IP段,或者使用一个大的网段。只做了简单的测试,bridge效率基本能达到原生网络的90%以上。

Q:选择CentOS而不是Ubuntu或者CoreOS的原因是什么?DNS和IP地址池如何协调?

A:技术栈原因,公司一直在用RedHat和CentOS。DNS和IP由DCOS管理平台进行管理。

Q:Mesos和Marathon结合时,关闭容器后会产生stop状态的容器而不自动清理,只能脚本清理,这个请问你们有什么方案处理么?

A:目前我们也是脚本。将来可能会和Mesos的hook做到一起,Mesos发现task结束时删除容器,或者通知管理平台,由管理平台定期批量处理。

以上内容根据2016年10月11日晚微信群分享内容整理。分享人李周,PPTV聚力传媒 DCOS技术主要负责人,专注于Docker网络解决方案,容器监控,DevOps。之前在中小创业公司长期负责客户现场实施工作,积累了大量关于网络,监控,权限认证,大数据,Oracle,中间件等经验,同时喜欢研究各种新兴技术。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesz,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。

原文发布时间为:2016-10-24

本文作者:李周

本文来自合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:DockOne微信分享( 八十八):PPTV聚力传媒的Docker与DevOps

时间: 2024-12-02 19:28:25

DockOne微信分享( 八十八):PPTV聚力传媒的Docker与DevOps的相关文章

DockOne微信分享(一一八):容器技术在企业级服务里的实践

本文讲的是DockOne微信分享(一一八):容器技术在企业级服务里的实践[编者的话]邻盛在做面向中小微企业做服务的时候, 实际遇到很多情况, 比如对方IT基础过于薄弱, 比如基础设施过于简陋, 比如产品要解决行业需求, 企业个性需求等等,经过几年积累目前摸索出了一套完整的产品方案.目前产品是以容器为核心的一套完整的PaaS平台+全新的微服务架构+底层能力构成的完整解决方案, 目前也进入到了几家传统大型制造企业协助他们完成新一代的信息升级. [深圳站|3天烧脑式Kubernetes训练营]培训内容

DockOne微信分享(九十八):Insta360容器化&DevOps之路

本文讲的是DockOne微信分享(九十八):Insta360容器化&DevOps之路[编者的话]作为一个全景/VR创业公司,随着公司人员增加以及全球化方向转变,刀耕火种的CI/CD方式已经不能满足当前的需求.综合考虑当前的人员状况与技术架构的拓展性后,我们采用一套以阿里云为基础,Docker为核心,第三方服务为工具的开发.测试.部署流程,以及内部的代码提交,版本管理规范. 背景 我司是一家集硬件研发与软件开发为一体的互联网创业公司.2016被称为全景/VR元年,预示了机遇到来的同时,也注定了我们

为更好实现公司战略目标,引入原联想全球高级副总裁吕岩任PPTV聚力CEO

据悉,吕岩将全面负责公司的日常运营管理:而陶闯博士将把精力重点转入董事会,负责公司战略方向.战略资源并对公司运营做指导:姚欣依旧负责公司的技术产品和OTT家庭互联网工作. 以下为陶闯内部邮件原文: 亲爱的PPers: 大家好! 我和BY(姚欣,在公司内部的简称)在长期思考公司的下一步发展,尤其是家庭互联网的到来,PPTV如何能在这个行业大潮中抓住这个关键机会.我们在引入高管人才的同时,也在思考如何建立更具规模的集团化企业.这里我想清楚了,能让企业走上新的台阶,我们应该采取更加大胆,更有魄力的举动

DockOne微信分享( 八十九):恒生金融交易系统的Docker化实践

本文讲的是DockOne微信分享( 八十九):恒生金融交易系统的Docker化实践[编者的话]Docker可以显著改善企业软件研发流程.提升企业DevOps效率.借助Docker,企业可以对现有IT系统进行一次梳理,解决IT软件系统部署.升级难的顽疾,重新释放企业生产力,降低企业成本.本次分享介绍了恒生电子运用Docker技术,加上自研配套工具,实现金融交易系统配置.部署.运维自动化的心得,包括: Docker的优势以及我们为什么要使用Docker: 恒生Docker运用现状: 恒生金融交易系统

DockOne微信分享(六十八):应用容器env化实战

本文讲的是DockOne微信分享(六十八):应用容器env化实战[编者的话]随着Docker技术的火热发展, Docker在代码构建发布中扮演着越来越重要的角色.Docker让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到流行的Linux机器上.Docker非常适用于如下场景: 应用容器的自动化打包和发布: 自动化测试和持续集成.发布: 这次主要和大家聊聊应用容器在配置管理中遇到的问题.首先是介绍现有容器常用的配置文件加载方式,接下来重点介绍数人云组件在自动化打包和发布遇到的

DockOne微信分享(八十四):Docker在B站的实施之路

本文讲的是DockOne微信分享(八十四):Docker在B站的实施之路[编者的话]B站一直在关注Docker的发展,去年成功在核心SLB(Tengine)集群上实施了Docker.今年我们对比了各种Docker实施方案后选择了Mesos.结合CI&CD,打通了整个业务的Docker上线流程,并实现了全自动扩缩容.这次结合我们的实施之路,分享一下遇到的重点与难点: 自研Docker网络插件的介绍: Bili PaaS平台中的CD实现与优化: 应用全自动扩缩容的实现方案: Nginx动态Upstr

DockOne微信分享(七十八):中英人寿保险有限公司基于容器技术的实践分享

本文讲的是DockOne微信分享(七十八):中英人寿保险有限公司基于容器技术的实践分享[编者的话] 中英人寿在移动应用开发与运维上引入DevOps,极大的提升了开发效率,进而实现持续交付能力.持续交付让移动应用上线的速度从以月为单位提升到周甚至到天. 通过在企业云上使用(Docker.Git.Jenkins etc)搭建自动化部署流水线, 使软件的构建.测试.部署的过程自动化实现.随着IT架构向云架构的转型,在架构级管理工具上采用虚拟化容器管理,实现从IaaS到PaaS的转变.对移动应用系统进行

DockOne微信分享(八十):云计算应用技术发展与企业异构资源池统一管理案例分析

本文讲的是DockOne微信分享(八十):云计算应用技术发展与企业异构资源池统一管理案例分析[编者的话]本次分享介绍了企业用户私有云的建设与变迁过程.从VMware虚拟化起步到后期的管理多种类型计算池与存储池的异构云平台,用户的需求,软硬件选型都具有代表性.主要内容包括: 云平台管理CloudStack资源池拓扑介绍 CloudStack到OpenStack的变迁 OpenStack对接多种类型存储 云平台升级与对接多种类型资源池 大家好,今天分享一个私有云平台的实施和升级案例. 客户是一家研发

DockOne微信分享(八十五):Docker存储方式选型建议

本文讲的是DockOne微信分享(八十五):Docker存储方式选型建议[编者的话]Docker存储方式提供管理分层镜像和容器的可读写层的具体实现.最初Docker仅能在支持AUFS文件系统的Ubuntu 发行版上运行,但是由于AUFS未能加入Linux内核,为了寻求兼容性.扩展性,Docker在内部通过GraphDriver机制这种可扩展的 方式来实现对不同文件系统的支持.本次分享通过一次客户实施案例深入的看看Docker的几种存储方式,并给出一些技术选型的建议. Docker存储方式: AU