今天分享主要内容有三部分。一个是给大家介绍一下雪球。第二部分给大家介绍一下我们如何使用容器技术,以及我们发展过程遇到的问题。第三个是发展规划。
我们雪球是干什么的?我们是投资者社区,很多有炒股的朋友在我们这里交流,我们又给他们提供A股的买卖的通道,还有行情,可以在我们这里做一些投资决策,比如说我想买什么股票。很多朋友可能说我自己炒股又耗时又耗精力,我不是很想炒股,我能不能有专业团队有信息的人给我们做这些事情,所以我们推出蛋卷基金,可以让不想花精力研究股票的人,可以在我们这里简单买卖基金。
我们业务比较多,如果我全都部署到物理机上,大家相互之间有一些影响,而且管理上比较复杂,如果我使用虚拟机的话,可能就会有虚拟机一些性能的损耗,所以我们当时调研了一下,这是2014年的时候,使用了容器技术。我们把一些基础设施的组件,比如说MySQL放到了上面,把一些业务无状态的东西放在了Docker里面,Docker是单机版的软件,我们最初做法把它当做虚拟机来用,我们把程序部署在里面,和原来的基础设施和使用物理机没有什么区别,操作起来跟一个虚拟机一模一样的。这是单机版的时候Docker的一个工作流。
我们这么搞得话,需要解决几个问题。一个网络连通性的问题,可能刚开始,Docker刚刚开始火数据分享,大家问你们多主机之间Docker网络连通性怎么搞得,不同物理机之间的(英文)不能互通的,第二个我们启动很多(英文),相当于多了很多机器,我们多节点部署更新这些东西,全都是手工操作复杂度非常高。第三点监控,监控跟规模也有关系,我们直接使用了(英文)来做。首先跟大家讲我们如何做得网络连通。左边这个图熟悉Docker的人了解比较清楚一些。因为Docker在启动的时候,创建Docker0的网桥,起一个VETH的网卡,就看到了Eth0的网卡,当我们流量想出去就走ETH0出去,我们做一些改造,我们不适用Docker默认创建的Docker0的网桥,我们ETH0有多数网卡,做了多数网卡绑定,我们创造了BR0的网桥,跟物理机的网段一样,启动BOND0的时候挂在BR0网桥上,到VETH,然后到ETH0,是二层可以连通的解决方案,现在这个方案也没有什么人用了,这是我们2014年的方案,优点就是二层网络互相连通,与所有设施都可以连接,跟物理机、MYSQL都可以连接,直接用硬件设施了。规模非常受限,二层可达,规模大有可能引发网络风暴。再有全都是互相连通的,因为我们和金融其实还是关系多一些,有一些安全性的要求,这全都是连通,如果我想实现网络隔离是比较复杂的。
接下来就是说刚刚遇到服务部署的问题,最开始当成虚拟机的用法用,我们用HOST管理这个文件,用Container执行,原理就是写一些脚本,然后下发到各个机器里面,好像用虚拟机一样再用这个东西。
我们用虚拟机用法,优点就是因为使用比较早,所以那个时候很多现在成熟的解决方案都没有,我们当时考虑优点就是和原有的基础设施迁移成本非常低,对开发用户来说直接相当于用虚拟机了。相比虚拟机启动非常快,没有虚拟机的损耗,我们最初需求就是做业务上的隔离,也满足了我们需求,随着我们接下来使用我们发现一些问题。首先迁移扩容非常繁琐,我想扩两个节点我登录到其他机器上,启动Docker,然后是一个镜像的过程,这样非常复杂。第二个管理非常复杂,没有现成的平台,我们记录某一台机器上跑了什么内容,分给了某一个业务,具体使用什么资源,这些都是靠文档记录的,靠文档记录导致一些问题,比如说我有变更的时候没有及时更新,后来可能有一些问题。再有没有流程控制和权限控制,这个是DevOps大家说得比较多的东西,我们面对这些缺点接下来做了一个解决方案。
也是因为早的原因,现在成熟解决方案没有,我们做了这么一个东西,叫做Roling,管理物理机上面的容器以及我们部署流程。这是我们2014年末开始做的发布流程。就是提交代码,对于开发来说非常简单,只要把代码提交上来,我可以自动触发构建出一个镜像,把镜像存在Registry,他像部署测试环境就部署测试环境,测试环境测试通过了就发布环节上。
我们从Ubuntu加一些base,我们针对不同业务,有java我们把Resin打进去,然后使用Nodejs语言等,最后构建出来一个APP,这个APP跑起来就是一个业务的镜像。做这个系统依赖一些相关的东西,比如说我做扩容怎么服务发现出来,我多个节点日志收集怎么做?还有我刚刚说的网络模式以及监控。
服务发现有两类,一类HTP协议,我们是NjinX+LUA,当这个Roling起来然后告诉它你又增加了一个Flume。日志收集也是分两类,一类是Nginx的日志,Nginx代码不想侵入进去,我们做了对这个服务部可见,直接收集硬盘上的文件这样的方式,用flume收集,我们自己业务程序,把自己日志打到KAFKA里面,这个阶段我们网络模式使用Bridge的模式。
监控后端用graphite,graphite展示我们数据的图像。
我们构建镜像做着做着发现这个镜像非常大,我部署节点发现非常慢,其实Image非常慢,Docker1.0之前,一方面它实现本身有一些原因,单线程比较慢,再一个确实比较大,传输网络IO就是这样。第一个思路精简镜像去除无用的内容,肯定要做的,而且相关文档非常多,大家搜索一下Docker官方也有一些讲这些地方。第二个写Docker build的时候,每一个里面的命令,都会打一个镜像层级进去,其实很多层级在我做业务镜像没有必要用到,我只要把这个业务代码打进去做一曾就可以了,我们使用Docker去写很难做到这样,我们把代码放进去还要做目录变更等东西,我们利用DockerCP和DockerCommit模拟这个东西,构建出来只有一层的镜像。做完以后一个镜像从两三K缩减到几百兆。这套流程和直接用虚拟机相比,在编译、分发、节点分发、节点变更、流程控制、权限控制都有非常大的提升。
这个优缺点都有,优点就是和之前相比流程控制、权限控制环境和代码固化,我回滚部署某一个版本非常方便,扩容效率提升、部署效率提升,开发用起来非常爽。缺点就是这个平台实现的问题,部署是比较复杂的东西,里面各种逻辑非常多,之前有人说灰度部署,我们可能想线上跑多个版本,里面也有一些流程的东西,跟机器管理耦合非常严重,管理的很粗放,主要靠运维人员决定,当我增加一个节点的时候,我把这个节点放在哪台物理机上,这个物理机到底用什么IP也是我要自己手动分配的,一台机器挂掉以后,整个平台也没有自愈的功能。
针对这些问题我们引入Swarm,Swarm和Docker本身的接口相容性非常好,没有花很多成本就引入进来了,所以当时选了Swarm这个东西,引用之后让它帮我们管理这个机器,启动container的时候,这个部署到哪一台机器上,这些我们交给Swarm来做。
接下来我手动分配IP感觉不是很好,调研当时的一些方案,我们用得是Dockerbridge的方式。我们最后选了Calico做这个。两台机器之间网络是如何连通的?从源的物理机,找路由表看看到底走哪一跳,然后在下一跳继续找路由表,然后做到Swarm在的物理机上,然后最后走到Calico上。一个包从ETH0进来找11.0.0.1的容器到底是哪里?通过路由表转到Calico里面。我们使用感觉非常稳定的,之前基础设施非常稳定,我们大概用了一年多,遇到的问题比较少,可能遇到一个问题就是说当这个机器挂掉之后,它的IP没有把原来分配好的,已经分配到这个机器上的IP回收,需要我们手动做一下有这样一个问题,我们使用这跟我们角色也有关系,我们本身是运维的角色,交换机都在我们手里,我们可以这样去配置,我们交换机都配置一个自愈,去别的地方可以走最少跳数可以走过去。
我们没有做到自动的扩容缩容和系统自愈,我们调研一下,其实也可以自己做,还是不想跟业界脱离出来,我们进来比较早,我们并不是引领这个潮流的,我们是FLOW这个潮流的,接下来我们在Kubernetes引入Swarn。我们现在做这些事情非常缺人手,有同学感兴趣把简历发给我,谢谢,这就是我今天的演讲。