V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dataman
V2EX  ›  Docker

实录分享 | 那些年容器落地,企业为 Docker 填过的坑

  •  
  •   dataman · 2016-09-05 11:57:04 +08:00 · 3455 次点击
    这是一个创建于 3007 天前的主题,其中的信息可能已经有所发展或是发生改变。

    数人云“容器助力产品迭代力 MAX ”沙龙干货分享实录持续上新,今天是来自人人贷高级运维工程师杜天鹏的分享,与我们细数了人人贷容器化实践过程中遇到的问题以及解决方法。

    很高兴站在这里和大家一起交流容器技术,我叫杜天鹏,是人人贷的运维工程师。人人贷是一家做 P2P 的互联网公司,现在业务量上升比较快,业务组件也比较多,这个过程给运维增加了很大的压力,所以人人贷考虑了容器化技术。

    为什么使用容器技术

    Docker 官网有一句话: build once , run anywhere ,容器一次构建,在其他服务器上就可以运行。第二,容器使用的是 Unionfs ,在传输的过程中,实际上传递的是变更的部分,而不需要拉取完整的 image 。第三,容器为人人贷提供了一个隔离的环境,在测试的过程中,一台机器可能运行了很多服务,一旦测试或者开发人员更改服务器环境或者其他参数,会导致其他的测试环境运行不起来。容器带来了环境的隔离性,一个容器只需运行一个 Docker ,可以避免很多问题。第四,容器能够结合 Jenkins 以及如 Hudson 、 Teamcity 这些持续交付软件来进行持续交付、持续集成、持续部署。第五,容器可以结合如 K8S 、 Mesos 、 Swarm 等调度器然后进行横向扩展。

    这是人人贷的传统上线流程。首先开发人员推送他们的代码到 Git 仓库,人人贷使用的是 Stash ,测试人员在测试的时间输入仓库名称和版本号,来进行使用 Jenkins 构建。在测试环境中,测试完成之后会重新构建一次,然后推送代码到类生产环境。这个类生产环境实际上使用的是生产环境的配置,只不过再做一次校验,防止出现问题。最后运维人员使用 Ansible 推送代码到生产环境,在这个过程中会产生很多问题。

    比如刚才说的环境不统一,或者是无意中修改了环境,或者有临时的需求上线的时间,需要准备新的虚拟机。这个临时的需求或许非常着急,但是从运维的角度来看,创建服务器,修改配置,初始化操作都需要一个过程,因此会影响整体的工作进展。 Docker 解决了这个问题,因为可以使用提前准备好的 Docker 镜像进行所有的初始化操作,让运维可以从容应对突发的情况。

    还有资源浪费的问题。在开发或者测试环境,人人贷运维人员为开发创建了很多测试虚拟机,假如不做定期巡检的话,就无法得知这个虚拟机是否正在被开发或者测试人员使用,导致了资源的浪费。使用了 Docker 技术后,运维就可以随时为开发或者测试同事部署一套环境,并且做定期的清理。对于大规模的部署过程,可以实现灵活调度,因为人人贷的业务峰值是不一样的。比如白天交易系统比较繁忙,可以调整交易系统节点数量;晚上要做计算和统计,计算资源则会多跑一些任务。

    为什么选择 Mesos

    人人贷在使用 Docker 时,考虑了三种容器技术,分别是 Mesos , Kubernetes 以及 Swarm 。最终选择 Mesos 主要基于三点考虑:最主要的是学习成本,对于 Kubernetes ,它的功能很多也很强大,但是它更新迭代非常快,里面很多功能现在仍处于 Beta 版本,但是官方并没有明确其使用环境。第二,成熟度的问题, Mesos 推出时间早,实践的公司也比较广泛,成熟度高于其他两个技术。第三, Mesos 有很多调度器例如 Marathon ,在界面上可以有一个直观的展示。而 Kubernetes 和 Swarm 之前是没有界面的,现在 Kubernetes 有一个 Dashboard ,但是功能尚不完整。

    迁移到虚拟机的种种问题

    人人贷从物理机迁移到虚拟机过程中遇到很多问题,一个完整的技术就是一个成熟的技术在应用到生产环境中,这个过程中的问题并不是技术引起的,而是落地的过程中没有标准,所以人人贷需要有一个标准化来面对需求。

    首先,配置不可见。运行在 Docker 内部的程序,并不不推荐进入容器,因为 Docker 就是一个容器,需要连接到里面来看配置项。在 Marathon 上面就可以看到配置项,具体配置项是通过 ENV 传入的。

    第二,项目无法相互调用。人人贷的业务比较多,所有的项目需要相互调用,包括交易所、 P2P 以及基金,它们之间需要进行资源交互。但是由于人力精力有限, Docker 技术在整套系统的实现尚需要一个过程。

    第三,无法通过 SSH 连接 Docker 。比如在测试环境中测试或开发进行一些 debug 操作,需要通过 SSH 连接上去,了解 Docker 现在的配置。

    第四,容器 IP 不可见。

    如何解决这些问题

    接下来我会通过运用的技术来为大家解释人人贷是如何解决这些问题的, Docker 落地过程中主要有七点需要关注。

    第一,编排。 Marathon 是使用 json 文件进行部署的,里面会写到具体的资源配置,镜像名称以及挂载目录。首先进行配置文件模板化,在人人贷,运维人员分别负责不同业务部门的运维工作,所以运维并不清楚其他部门是如何配置的,模板化之后只需要让开发人员按照规则来表述,就可以清晰地传递和表达。

    例如上图中两个配置,这是 exchange (人人贷的一个项目名)环境里面的 MySQL 以及服务。开发只要按照这个标准往里面写配置,运维就可以明白项目和配置项。然后进行配置项 ENV 化,配置都是通过 ENV 传入,通过命令进行渲染,当然也可以使用 shell 命令或者其他的程序进行配置渲染。之后修改上线 json ,因为每一次 json 文件并不是一成不变的,需要更改文本配置。

    第二,网络。人人贷使用的是 Calico ,它本身可以划分网段,来指定范围。我们在路由器上面添加了路由,让开发环境可以直接访容器内部的网络。 Calico 本身可以支持 Docker1.10 版本后,可以通过 - 指定 --IP 。人人贷使用的是 CNM 模式, Calico 是支持 CNI 与 CNM 的,人人贷使用的是 calico-containers ,因此可以使用 Docker 命令,并且指定驱动为 Calico ,非常便于管理。指定路由后,可以直接访问,不再需要使用例如 Marathonlb 这些指定端口,也不需要维护端口列表。 Calico 使用 BGP 协议,不需要封包。对于 Mesos 来说,我比较推荐使用 Calico 。

    第三,服务发现。人人贷使用 Calico 可以固定 IP 地址,虽然并不推荐把容器作为一个虚拟机来使用,但是对于固定 IP 地址这种情况可能仍需要一个容器。当其他服务需要灵活调度时,则需要 IP 动态划分。人人贷使用 Mesos-DNS 来获取动态分配的 IP ,所有的组件配置域名相互调用,测试环境同样使用的配置域名化,即服务调度之间都是使用域名来调用的。因此 Mesos-DNS 只需要转发现有域名服务器的域名解析,就可以直接调用原有的服务,在里面写域名,而不需要知道其 IP 地址,亦不需要配置。

    第四,存储。对于一些需要持久化的数据,人人贷使用的是本地化持久卷,这个绑定在 host 上,当这个容器挂掉之后,它会在物理机上重新起一个容器。 Docker 通常运行的都是无状态应用,所以如果 MySQL 里面的数据非常重要,我还是更推荐使用物理机或者虚拟机进行部署。对于分布式如 MongoDB 或者其他具有高可用性的数据库,部署在 Docker 里面也还是可以的。

    第五,监控。人人贷使用的就是 Cadvisor+Influxdb+Grafana 这套开源方案, Cadvisor 是谷歌的一个开源产品, Influxdb 是一个时序数据库, Grafana 是一个漂亮的界面展示。对于 Zabbix ,人人贷用过一个叫 Zabbix-Grafana 的插件,可以在 Grafana 里面显示 Zabbix 的数据。 Cadvisor 主要起到作用就是收集容器里面的资源使用情况,例如内存, CPU 以及磁盘 IO ,然后存入到 Influxdb 中。当然监控的同时,也可以使用 Dockerstats 等实现一些数据采集。

    第六,日志收集。人人贷现在主要使用的是 ELK 的数据方案。为了实现 SSH 登录容器内部, Docker 是需要一个前台进程来保持 Docker 程序不退出的,因此人人贷所有的容器都是使用 SSHD 守护进程,来保持 Docker 一直运行下去。

    人人贷有一个 start 的脚本,例如 Tomcat ,我们会在这个 SSHD 进程启动之前来启动它。所以日志通过 Docker logs 是看不到的,只能在容器里面部署一个 Logstash agent ,但是会加重容器的负担。对于没有接入容器内部需求的同学,可以直接接入运行进程,将日志打入到 Docker 控制台,通过 Docker logs 进行日志收集,在 Docker 的宿主机上面指定 Docker 日志的产出目录实现收集,而不再需要在 Docker 里面部署 agent 。

    第七,镜像仓库。 Docker 官方的镜像仓库本身是没有认证功能的,但是在真实生产环境中,需要有镜像的权限划分。现在 Registry 用的比较多就是 Apphouse 以及 Habor ,据我之前了解, Habor 的 BUG 比较多一点,所以人人贷使用了 Apphouse 。但是现在我了解到 Habor 支持分布式以及主从关系进行主从复制,所以将来人人贷可能会弃用 Apphouse ,使用 Habor 来做私有仓库。 Habor 是一个开源产品,可以看到它内部的实现原理, Apphouse 虽然免费,但是它是闭源的。

    最终流程及总结

    最终人人贷落地实现了这个过程,由开发人员提交代码到 Stash ,输入版本号以及分支名通过 Jenkins 进行构建,推送到 image 。在发布的时间通过调用 Marathon 的 API 进行发布,拉取 image ,最终运行在 Mesos Slave 节点上。

    接下来人人贷希望实现部署多套环境,对于项目名称进行模板化处理,并且通过 Jenkins 实现完全自动化。个人认为落地的过程中,主要问题就在于配置管理。谢谢大家。

    附 PPT : http://imgur.com/JJIsGoK

    1 条回复    2016-09-06 16:52:18 +08:00
    dataman
        1
    dataman  
    OP
       2016-09-06 16:52:18 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2795 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:45 · PVG 22:45 · LAX 06:45 · JFK 09:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.