互联网金融创业公司Docker实践
Posted 高可用架构
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了互联网金融创业公司Docker实践相关的知识,希望对你有一定的参考价值。
高磊 雪球运维架构师。2012年主持研发和运维 Redis 集群等分布式系统,专注于中小型公司运维架构和运维体系建设,目前在雪球负责技术保障工作,在Docker容器及其周边生态系统积累了大量一线经验。
本次分享主要聊聊创业公司在实践Docker方面的一些经验,内容分为以下六个部分:
一、背景介绍
二、容器选型
三、应用迁移
四、弹性扩容
五、未来规划
六、Q&A
一、背景介绍
雪球( 是一家涉足证券行业的互联网金融公司,成立于2010年,去年获得C轮融资。雪球的产品形态包括社区、行情、组合、交易等,覆盖沪深港美市场的各个品种。
与传统社交网络的单一好友关系不同,雪球在用户、股票基金及衍生品、组合三个维度上都进行深度的相互连接。同时雪球的用户活跃度和在线时长极高,以致我们在进行技术方案选型和评估的时候必须提出更高的要求。
目前雪球的 DAU 为1M,带宽为1.5G,物理机数量为200+,云虚拟机数量约50个。雪球采用了 Docker 容器作为线上服务的一个基本运行单元,雪球的容器数量近1k。
二、容器选型
我们的服务面临的操作系统环境大致有五种:物理机、自建虚拟机、云虚拟机、LXC 容器、Docker 容器。
(图1)
我们主要的考虑的选型指标包括“成本”、“性能”、“稳定性”三个硬性基础指标,以及“资源隔离能力”、“标准化能力”、“伸缩能力”这几个附加指标。
这五类操作系统环境在雪球的实践如下:
(图2)
三、应用迁移
我们 SRE 团队借助 Docker 对整个公司的服务进行了统一的标准化工作,在上半年已经把开发测试、预发布、灰度、生产环境的所有无状态服务都迁移到了 Docker 容器中。
雪球借助 Docker 对服务进行的标准化和迁移工作,主要是顺着 Docker 的 Build -> Ship -> Run 这三个流程进行的。同时在迁移过程中填了许多坑,算是摸着石头过河的阶段。
我们首先设计了自己的 Docker Image 层级体系。在 Base 这一层,我们从 ubuntu-upstart 镜像开始制作 base 镜像。
这里做了动静分离,静态的部分(static.sh 和对应的 static 文件)和动态的部分 ( runtime.sh ) 都会被添加进 base 镜像,静态部分会在构建 base 镜像过程中被执行,而动态部分会在启动 project 镜像的过程中被执行。详情如下图所示:
(图3)
其中静态部分我们更推荐灵活的使用 shell 脚本来完成多个基础配置,而不是写冗长的 Dockerfile。下图是一个很好的对比,左面是gitlab官方的dockerfile,右面是我们的动静分离实践。
(图4)
然后基于 base 镜像,我们又添加进入了 JDK、NodeJS 等运行环境,并在JDK的基础上进一步构建了 Resin 镜像。
在上述镜像中再添加一层业务执行代码,则构成了业务镜像。不同的业务镜像是每个业务运行的最小单元。
在雪球我们大力的推进了服务化,去状态。这样的一个业务镜像就具备了迁移部署、动态伸缩的能力。
需要提醒的是 docker build 镜像的过程中会遇到临时容器的一些问题,主要涉及访问外网和dameon能力。
Docker 构建这块就跟大家分享这么多。接下来咱们聊聊分发这一步。
分发的过程痛点不多,主要是 Registry 的一些与删除相关的 Bug、Push 镜像的性能,以及高可用问题。
而本质上高可用依赖于存储的高可用。在雪球我们使用了硬件存储,接下来计划借助 Ceph 等分布式文件系统去解决。
说完分发,我们谈谈运行这个环节,Docker 运行的部分可以探讨的内容较多,这里分为网络模型、使用方式、运维生态圈三部分来介绍。
绝大多数对 Docker 的网络使用模型可以汇总为三类:bridge(NAT)、bridge(去NAT)、host。
在雪球我们对 Bridge 模式去掉了 NAT,也即把宿主机的 IP 从物理网卡上移除,直接配置到网桥上去,并且使用静态的 IP 分配策略。
据了解,有好多其他公司在自己的IDC机房中也是采用了去NAT的桥接模式,这样的好处是 Docker 的 IP 可以直接暴露到交换机上,性能最高。
而端口映射方案不容易做服务发现,雪球并没有使用。
其中去 NAT 的 Bridge 模式需要在宿主机上禁用 iptables 和 ip_forward,以及禁用相关的内核模块,以避免网络流量毛刺风暴问题。
说完网络,我们看下一些使用场景。
(图5)
同时我们按照雪球统一的运维规范在运行时修改了容器 Hostname、Hosts、DNS 配置。
在交互上,我们在容器中提供了 sshd,以方便业务同学直接 ssh 方式进入容器进行交互。
Docker 原生不提供 /sbin/init 来启动 sshd 这类后台进程的,一个变通的办法是使用带 upstart 的根操作系统镜像,并将 /sbin/init 以 entrypoint 参数启动,作为 PID=1 的进程,并且严禁各种其他 CMD 参数。这样其他进程就可以成为 /sbin/init 的子进程并作为后台服务跑起来。
然后跟大家介绍下我们在 docker 周边做的一些运维生态圈。
首先我们对容器做了资源限制。一个容器默认分配的是 4core 8G 标准。
CPU 上,我们对 share 这种相对配额方式和 cpuset 这种静态绑定方式都不满意,而使用了 period + quota 两个参数做动态绝对配额。
在内存上我们禁用了 swap,原因是当一个服务 OOM 的时候,我们希望服务会 Fast Fail 并被监控系统捕捉到,而不是使用 swap 硬撑。死了比慢要好,这也是我们大力推进服务化和去状态的原因。
对了,顺便提一下 docker daemon 挂掉,或者升级,我们也是靠应用层的分布式高可用方案去解决。只要去掉状态,什么都好说。
在日志方面,我们以 rw 方式映射了物理机上的一个与 Docker IP 对应的目录到容器的 /persist 目录,并把 /persist/logs 目录软连接为业务的相对 logs 目录。这样对业务同学而言,直接输出日志到相对路径即可,并不需要考虑持久化的事宜。这样做也有助于去掉 docker 的状态,让数据和服务分离。
日志收集我们在 java 中使用 logback appender 方式直接输出。对于少数需要 tail -F 收集的,则在物理机上实现。
在监控方面,分成两部分,对于 CPU、Mem、Network、BlkIO 以及进程存活和TCP连接,我们把宿主机的 cgroup 目录以及一个统一管理的监控脚本映射到容器内部,这个脚本定期采集所需数据,主动上报到监控服务器端。
对于业务自身的 QPS、Latency 等数据,我们在业务中内嵌相关的 metrics 库来推送。不在宿主机上使用 docker exec API 采集的原因是性能太差。据说 docker 1.8 修过了这个 docker exec 的 bug,我们还没有跟进细看。
以上是我们在上半年的一些工作,主要方向是把业务迁移入 docker 中,并做好生态系统。
四、弹性扩容
大家知道上半年时,股市异常火爆,我们急需对业务进行扩容。
而通过采购硬件实现弹性扩容的,都是耍流氓。雪球活跃度与证券市场的热度大体成正相关关系,当行情好的时候,业务部门对硬件资源的需求增长是极其陡峭的。
在无法容忍硬件采购的长周期后,我们开始探索私有云+公有云混合部署的架构。我们对本地机房和远端云机房的流量请求模型做了一些抽象,如下:
(图6)
我们把服务栈分为接入层、服务层、数据层三层。
第一个阶段,只针对接入层做代理回源,目的可以是借助公有云全球部署的能力实现全球就近接入。
第二个阶段,我们开始给远端的接入层铺设当地的服务层。演进到第三个阶段,远端的服务层开始希望直接请求本地数据。
这里比较有趣的一点是,如果远端服务是只读逻辑,那么我们只需要把数据做单向同步即可。
如果要考虑双向同步,也即演进到第四个阶段,也即我们所说的双活。
其中不同机房之间的流量切换可以使用 DNS 做负载均衡,在雪球我们开发了一套 HTTP DNS 较完美的解决此问题。
目前雪球的混合云架构演进到第三个阶段,也即在公有云上部署了一定量的只读服务,获得一定程度的弹性能力。
在公有云上部署 Docker 最大的难题是不同虚拟机上的 Docker 之间的网络互通问题。我们与合作厂商进行了一些探索,采用了如下的 Bridge (NAT) 方案。
(图7)
这本质上是一个路由方案。首先虚拟机要部署在同一个 VPC 子网中,然后在虚拟机上开启 iptables 和 ip_forward 转发,并给每个虚拟机创建独立的网桥。网桥的网段是独立的 C 段。最后在 VPC 的虚拟路由器上设置对应的目标路由。
这个方案的缺点是数据包经过内核转发有一定的性能损失,同时在网络配置和网段管理上都有不小的成本。
庆幸的是越来越多的云服务商都在将 Docker 的网络模型进行产品化,例如据我们了解,阿里云就在向 docker 提交 docker machine 的 driver。
除了路由方案外,另一个方案是隧道方案。也即铺设 ovs 之类的 overlay。
但是,在公有云上本来底层网络就是一层 overlay,再铺设一层软件 overlay,性能必然会大打折扣。
我们最希望的,还是公有云自身的 SDN 能够直接支持去 NAT 的 bridge。
当使用 Docker 对服务进行标准化后,我们认为有必要充分发挥 Docker 装箱模型的优势来实现对业务的快速发布能力,同时希望有一个平台能够屏蔽掉本地机房与远端公有云机房的部署差异,进而获得跨混合云调度的能力。
于是我们开发了一套发布系统平台,命名为 Rolling,意喻业务系统如滚雪球般不断向前。
在此之前,雪球有一套使用开源软件 Capistrano 构建的基于 ssh 分发的部署工具,Rolling 平台与其对比如下:
(图8)
大家可以点开图细看下,Rolling 帮助我们解决了非常多的痛点。像编译时机、环境干净程度、代码验证、版本控制,等等。
Rolling 的上下游系统如下图所示:
(图9)
下面截取了几张 Rolling 平台在部署过程中的几个关键步骤截图
(图10)
上图显示了 Rolling 在部署时的第三个步骤:资源选择。目前雪球仍然是靠人力进行调度配置,接下来会使用自动化的调度工具进行资源配置,而 Rolling 已经赋予我们这种可能性。在真正开始部署之后,还有一键暂停、强制回滚、灰度发布的功能。
(图11)
上图显示了某业务在使用 Rolling 部署后的运行状态。
Rolling 平台的带来的质变意义有两方面:
其一从运维同学的角度,Rolling 使得我们对服务的调度能力从静态跃迁为动态。而配合以大力推进的服务去状态化,Rolling 完全可以发展成为公司内部私有 PaaS 云平台的一款基石产品。
其二从业务同学的角度,其上线时不再是申请几台机器,而是申请多少计算和存储资源。
理想情况下业务同学甚至可以评估出自己每个 QPS 耗费多少 CPU 和内存,然后 Rolling 平台能够借助调度层计算出匹配的 Docker 容器的数量,进而进行调度和部署。也即从物理机(或虚拟机)的概念回归到计算和存储资源本身。
五、未来规划
一方面,我们非常看好公有云弹性的能力,雪球会和合作厂商把公有云部署 Docker 的网络模型做到更好的产品化,更大程度的屏蔽底层异构差别。
另一方面,我们考虑在资源层引入相对成熟的开源基础设施,进而为调度层提供自动化的决策依据。
六、Q&A
Q1:同时维护五类操作系统环境,是不是太多了?
多套环境,是确实有多种需求,很难砍掉。
物理机,不用说了,上面要部署nginx/redis等等。
KVM,因为雪球要装一些windows,来对接券商等传统行业(必须要求windows)。
LXC,确实是历史遗留,不排除切换到物理机,但是目前没有动力。
Docker,无状态服务。
PS. 我们实践中,只把无状态的服务放到 Docker 中,有状态的不会放。
Q4.发布系统中有无考虑ansible还是基于ssh直接上的?
发布系统早期Capistrano,本质上就是ssh,与ansible/saltstack没有质的区别。现在写了一套 Rolling,是基于 docker registry 和docker api的,与 ssh 没有任何关系。
Q5:为啥是4核8g?
主要大多数业务,其的每个节点,大概会用略低于这个配置的资源,我们就拍了这套 Default 值。
Q6. 调度参考监控系统的哪些指标?
我们调度目前还没真正做起来,参考的值必然会包括操作系统层面的指标(CPU/Mem/Network/BlkIO),同时应该会参考业务的指标(QPS、Latency)等等。
Q7:能详细说一下用shell脚本配置如何做,雪球是不是已经自研一套shell脚本组件来管理配置,代替dockerfile?
shell 脚本(也即capistrano这套基于ssh的发布系统),逻辑上就是git拉取代码,然后执行编译,然后打包,然后基于不同项目的配置,scp到不同的目标机上,启动起来。我们并没有替代 dockerfile,而是简化dockerfile,而且这一步是在构建base镜像时做的。跟业务部署并没有关系。
Q8.有没有评估过lxd?
刚搜了下,LXD 好像是 LXC 的管理 hypervisor,我们没有评估过,没有去看他的优缺点。我觉得技术选型的时候,除了技术本身,一定也会着重考察生态。Docker 生态系统非常好,也是我们选型的主要考虑因素。
Q9.目前雪球有多少个业务(核心的)跑在docker上?
我们的 docker 总体数量大概是1000个左右,其中大约有1/5是测试、预发布环境的,剩下的800个左右线上。我们总共有40个左右的业务,有的大,有的小。
Q10.如何管理docker集群?
对docker集群的管理,或者说对资源层的管理,是我们下一个milestone的目标。有可能会去考虑mesos,目前还在试验环节。
Q11.容器和业务有做为一个整体做弹性和自愈吗?还是分开的?
我们是把容器和业务是绑死在一起的。一个容器里,就是一个业务进程。所以要弹的就是容器。
Q12.使用docker之前,每个业务也是用很多台主机么?
没有,之前是在物理机上裸着混部署的状态。我们在去年下半年和今年上半年经历的大扩张以及微服务化。
以上是关于互联网金融创业公司Docker实践的主要内容,如果未能解决你的问题,请参考以下文章