中兴软创(ZTEsoft)基于Jenkins和Docker的CI实践 (3)

8.png


4)执行发布计划

使用Docker Java API连接docker daemon启动容器

记录容器ID

9.png


5)容器管理

主机检测(能检测主机上是否安装了docker,如果没有可以自动安装Docker)

容器节点增加、缩减,用户选择的应用镜像版本和实际运行版本一致时执行伸缩

容器状态监测

基于Dubbo的跨主机的容器连接 一开始我们在测试环境上将所有容器都放在一台主机上,测试过程很顺利,但在移到准生产环境上时,由于要模拟生产环境只能将容器部署到不同的主机上,这时候就发现了一个奇怪的现象,应用之间调不通了,这里要说一下,我们应用程序是由20多个服务组成的、通过Dubbo【阿里提供的一个服务框架】作为服务总线串连起来的,Dubbo提供了一个方便的服务发现机制,各个服务(称为服务提供者)只要向 Dubbo注册中心注册过,注册中心就会将服务的地址发送给同样在注册中心注册的服务调用方(称为消费者),之后即使dubbo注册中心挂了也不影响服务的调用。

10.png

当服务提供者部署在容器中时,这时候发现其在Dubbo中心注册的是容器的IP地址,而对处于另一个主机上的消费者来说这个IP是不可访问的,我们当时也参考了多种方式,想让消费者能够连接上服务提供者的IP,查阅资料总结起来大概有两种做法:

设置容器的IP与主机IP在同一网段内,使容器IP可直接访问【会占用大量的IP地址,且IP会限制在同一网段,在生产环境中往往不可能】。

通过复杂的iptables路由规则,通过多层桥接方式打通网络【此法是可行的,也是我们今后要考虑的,但当时一堆开发人员对网络这块都不是太熟悉】。


考虑到当时公司技术委员会下属另一个研发团队正在做dubbo的研究和改造,于是拉他们进来讨论,结果他们说这个很容易解决,由于主机之间是连通的,而容器在创建时也映射了主机和端口,只需要在服务注册时注册的是映射的主机IP和端口就可以连通了,该研发团队的效率很高,讨论的当天就给出了实现,考虑到局方要求严格管理容器和主机间的映射,我们将主机IP和端口作为环境变量在容器启动时传入【扩展了dubbo protocol配置,增加了两个配置项 publish host、 publishport,对应主机的ip port,并且在注册服务时将主机的ip port写到注册中心】,果然解决了这个问题。
当然这是一种特殊情况下的跨主机容器连接方式,更为普遍的方式目前我们正在讨论当中,基于ovs的连接方式是正在考虑的一个方案。 困难与展望 目前我们对Docker的使用还比较初步,虽然基本满足了项目的要求,但考虑到将来云平台要求自动扩展、服务发现,这些还有待我们进一步研究。 Q&A Q:你好,问一个问题,我们前段时间也把Dubbo框架运行在Docker里面,也是采用你们现在的把宿主机和端口作为环境变量传入的方式实现的,我比较想了解的是后继你们有什么更好的方式实现,我看你提到了基于OVS的方案? A:有两种解决办法:

一种是将显式传递环境变量做成隐式的自动获取宿主机和端口,从而减少配置工作;

另一种则是通用的Open vSwitch(OVS)方案,这是与Dubbo无关的。

Q:容器中的Dubbo注册问题,扩展Dubbo的protocol配置,增加publishhost和publishport解决了注册问题,能不能说的详细一点? A:目前我们硬编码了Dubbo的protocol,在里面加了两个字段,这种扩展方式有点野蛮,但Dubbo本身提供的扩展方式目前很难支持传递环境变量方式,我们在考虑将环境变量隐式获取,这样就不用硬编码了。 Q:你们用的还是端口映射吧,那么也会存在很多个端口的问题吧,像IP可以访问一样? A:在这个项目中作端口映射是运营商的要求,他们要求能通过配置来设置每个容器的端口映射,这与他们现有的运维方式有关,一开始我们考虑的是docker的自动端口映射,当然这种需求将来肯定是趋势,我们的“云应用管理平台”中也有考虑。 Q:为何考虑Dubbo而不是etcd做服务发现,Dubbo的优势是什么? A:选中Dubbo是很偶然的,公司本身有ESB产品,但相对来说比较重,一般用于多个产品间的调用,而Dubbo我们一般用于产品内部多个模块之间的调用,是一种轻量级的服务总线,Dubbo这种方式不依赖于硬件和操作系统,etcd并不是所有操作系统都能支持的吧,当然我也没有对etcd作深入的研究。 Q:Jenkins的slave是选用了虚拟机还是直接物理机? A:我们的Jenkins的master和slave都是用的虚拟机。 Q:代码提交上去,如果测试有问题,回滚是肿么处理,也是通过Jenkins? A:这里要分情况来说,一种是测试发现问题,提单子给开发修改,开发修改完代码提交到scm,然后触发Jenkins下一轮的编译和部署;另一种情况是如果某次部署失败,则会用部署前的备份直接还原。 Q:请问用的Registry V1还是V2 ,分布式存储用的什么,有没有加Nginx代理? A:目前我们用的是V1。生产环境多是集群环境,需要加Nginx作分发。目前应用中分布式存储用的并不多,一般来说用hdfs来存储一些日志便于后面分析,也有用FastDFS和MongoDB的。 Q:底层云平台用的是私有云? A:底层平台一开始想用私有云,但运营商已经有了vCenter的环境,因此后来我们改用Ansible来管理各类物理机和虚机,用Docker API来管理容器。 Q:Dubbo实现的服务发现是否具备failover功能,自动检测并迁移失败容器? A:Dubbo目前不具备迁移容器的功能,其failover是通过负载均衡和心跳连接来控制的,自动检测和容器迁移我们一般会考虑放在监控系统里面来做,如果放在Dubbo里面会加重Dubbo,只所以用Dubbo也是考虑到它的轻便性。 Q:能否谈下对Jenkins+Mesos的看法,这个涉及到docker-in-docker的必要性? A:Mesos我们才刚刚接触,我了解的不太多,至于docker-in-docker我觉得生产上很难用,因为性能方面损失比较严重,我们做过性能测试,非--net=host方式的容器性能损失接近30%。 Q:能具体介绍下利用Dockerfile打包镜像吗,jar包也是在这一步编译出来的吗,这样发布出去的镜像会既包括代码又包含jar包吧? A:我们的镜像中是不包含代码的,镜像里面是产品包,编译是在打镜像之前做的。 Q:对不生产环境中不适合以容器运行的组件,Jenkins+Docker是否就没有优势了? A:开发和测试环境还是很有优势的,当然有些有大量IO操作的服务其实不适合放在容器里面,这主要是性能方面的考虑。 Q:云平台是怎么管理容器的,有没有使用Docker生态系统相关的组件? A:目前没有用到Swarm\Compose之类的组件,将来要看这块的发展了,也有可能会引入k8s或者Mesos来作管理,这些目前都在考虑当中 。 Q:在怎么判断部署Docker服务不可用,不可用后自动迁移还是如何操作? A:目前云应用平台只在发布时才对Docker容器进行状态检测,如果检测到失败,会根据指定的容器数目进行重新创建。后续我们会把对容器状态的持续检测统一放到监控系统中。 Q:我是不是可以这么理解,你们的Jenkins是主要用来CI,而实际集群管理则是云应用平台做的? A:是的,这个是严格分工的,当时作云应用管理平台时,是以测试交付物为起始点的,这里的测试交付物就是CI的产物,容器方式下就是镜像了。 Q:我可以理解Docker是部署在实体机,实体机上都有一个agent的东西负责与管理端通信,主要负责Docker的管理(安装,部署,监控等)吗? A:我们的Docker目前都是部署在虚拟机上的,操作系统是Redhat 7.1,你所谓的agent其实应该就是Docker daemon吧。
徐新坤:这个我补充一下,作为Jenkins的slave,会向slave里面启动一个agent来执行相关脚本命令的。这个属于Jenkins的功能,可以去体验下。 Q:一个应用多个容器你们怎么负载均衡? A:前面其实回答过,要加Nginx的。 Q:利用Dockerfile打包镜像并上传到Registry更像是CD环节的事情,那在单元测试、集成测试环境是否有利用到Docker呢,是否使用Jenkins中Docker相关的插件了? A:当前项目的单元测试、集成测试都用到docker容器的。Jenkins中没有用Docker插件,试过感觉都不太成熟,目前还是Docker命令行最方便。 Q:开始的时候有讲如果没有Docker自动部署会自动部署,这个是如何部署的? A:这个前面讲过,是通过lftp脚本比对编译环境与待部署的远程目录。 Q:也就是你们在虚拟机里面部署的Docker? A:是的,当前的项目是在虚拟机里面部署Docker的,但我个人观点从长远看来,其实在物理机上部署Docker会更好,所以现在很多私有云比如OpenStack、CloudStack都能支持直接管理容器,不过目前虚拟机还是不能缺少的,容器的隔离性不如VM。 Q:如果用nat模式 容器如何指定IP啊? A:不需要指定容器IP,只需要映射端口。 Q:有通过Dubbo做服务路由么? A:Dubbo本身就有服务路由的功能。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwgxfg.html