Docker 在 Bilibili 的实战:由痛点推进的容器化

数人云上海&深圳两地“容器之 Mesos/K8S/Swarm 三国演义”的嘉宾精彩实录持续更新^_^今天小数带来的是 Bilibili 运维开发工程师吴佳兴的分享。相信很多小伙伴都是 B 站的粉丝,快来看看他们在业务高峰是如何利用容器技术应对各类压力的吧。web

吴佳兴, Bilibili 运维开发工程师
同时也是 Dockone.io 社区译者,在配置管理、运维自动化、 Python 开发、 CICD 及容器方面有必定经验。网络

今天主要讲 B 站在 Docker 的一些收获和实践经验。我叫吴佳兴,现任 Bilibili 运维开发工程师,同时也是 dockone.io 社区翻译,过去作过 Salt 配置管理、基础运维,目前工做重点是容器方面的一些建设。 Bilibili 是一家弹幕视频网站,深耕于垂直领域,流量可观,有一亿的活跃用户, 100 万的活跃 UP 主,主要作直播、游戏、视频等。并发

上图是本次演讲的纲要, B 站定位是一家创业型的公司,并非为了容器化而容器化,使用容器技术是为了解决问题。 B 站在 2015 年曾作过容器的尝试,把 SLB 的节点容器化,当时用的版本是 1.9 ,去年 8 月份重点评估了可否解决线上或者测试环境遇到的问题。app

Problems :不少……

主要存在以下列出的问题。首先应用部署不够标准化,有不少历史存留的问题,有些应用是 supervisord 跑起来的,有些应用没有服务脚本,并且物理机上的混布很是严重,好比直播弹幕的一些消息组件在业务高峰的时候把物理机打爆,其余的应用可能会误伤掉。 B 站也分 BU ,各个业务方有调用的关系,这个调用的关系在测试环境没有一个稳定的集成环境来作集成测试,也是须要解决的。运维

B 站常常遇到测试环境炸了的状况,这是运维一直比较头疼的问题,也是推进容器的一个出发点,即用故障或者是痛点来推进,这样的推进进程会更快一点,解决方案天然就是容器化。工具

解决方案: Jenkins married Mesos !

如何产出镜像,是首先要解决的问题。有两种方案,一种是运维帮忙作好镜像,能够直接用,可是代码没有办法打包进去, B 站选择的方案是用 Jenkins 加上 Mesos 来作动态可扩缩的 CI 基础设施,实际用到的组件核心是 Mesos plugin , Jenkins-Master 能够经过 Mesos plugin 在 Mesos Master 起一个 Jenkins framework , framework 是一个调度层,能够在 Mesos Slave 上进行调度和决策,用 Mesos Plugin 组件至关于在 Slave 上动态地起 Jenkins Slave 进行构建,主要的构建就是从 Gitlab push 触发第一次构建。构建用到了 Jenkins2.0 的 Pipeline ,就是 Pipeline as Code ,全部均可以用 groovy 脚本实现。咱们会为每一种语言都定制一种 Pipeline 模版。单元测试

这是实际运行状况的截图,指定 Jenkins Slave 在 Mesos 上面起起来,而且定义环境变量,一些用来作构建的变量,调用 Pipeline 实现镜像的产出,经过它能够直接构建镜像。另外, Jenkins2.0 也有很是多值得吸引人的特性,由于 Jenkins 在 1.0 的时候是主打是 CI 部分, 2.0 重点在 CD 部分有耕耘,主要是并发测试包括与 Docker 的结合。 Jenkins Pipeline 会分为几个步骤,从构建、打包、 Docker build 以及最终在 Marathon 运行起来。测试

B 站测试环境一直面临一个问题。举例来讲,一个依赖服务有一个 V1 的稳定版本,假如这个依赖服务须要进行迭代,发布 V2 版本,但在集成环境发布 V2 版本,其余的依赖方调用可能会有问题。 B 站的作法与业界没有大差别,即作一些环境的区分。若是使用容器化基础设施,环境的区分会很是的弱化,能够简单理解为在 Slave 上有一个环境的属性, attribute 就是 Env 等于 UAT 或者 FAT 。 B 站作到了一个效果,在跑完单元测试后,根据用户的需求,去部署到 FAT 环境或者是 UAT 环境,为每个跑起来的 API 对应地绑上一个 DNS 的域名,好比功能测试环境想访问集成环境的服务,能够经过 Add-host 的方式进行访问。此外,从集成环境到生产环境是有一个 tag image 的过程,在集成环境产出的镜像,通过测试经过的步骤,通过 retag 的方式,最后产出一个正式环境能够用的镜像。大数据

容器化基础运行设施

为了支撑这套构建以及实际容器的运行,须要建设容器化的基础运行设施,在 CI 方面最终的产出物是一个镜像,如何支撑它的运行?首先是服务发现。由于 Docker 容器是飘动的,要作到在 LB 上可发现。 B 站使用的 Consul ,即 Marathon 的 app 在启动的时候会有 instance 出来,咱们会监听 Marathon 的 eventbus ,并把这个事件记录到 Consul 里面,同时对应的会有一个 APP-LB ,在上面绑定一个 consul template 作动态渲染,实现服务的注册和服务发现。网站

容器监控,以前也有调研过 Cadvisor 、普罗米修斯之类。由于一些痛点, B 站最终选择的方案是自研,主要是收集基础层面的还有应用层面的监控数据,应用层面能够复用现有的部分,好比代码埋点或者按期采集的数据,这里提供一个自研的 monitor agent ,能够经过 Docker exec 的方式去采集容器的监控数据,而后打到 influxdb 并用 grafana 作展现。

网络也是作容器的时候一个使人苦恼的问题, B 站以前花了不少时间在网络选型方面作调研,最终选择的方案是 Macvlan 。调研过 VXLAN 、 Calico ,最终选择 Macvlan 的缘由是由于 VXLAN 作过压力测试,发现私有云方面覆盖网络的损耗比较大。若是使用 Calico 的话要作一个 BGP 网络,当时网络工程师否决了这个建议,最终选择了 Macvlan 这个损耗和侵入性比较小的方式。咱们自研了一个 ipam plugin ,由于 Docker12 开始就支持 network plugin ,能够经过 ipam plugin 来实现 IP 地址的管理,而且注册到 consul 。

Logging 方面比较简单。 Docker 提供 log driver ,经过 syslog 的方式打到远端。另外 APP 应用层面的一些日志,直接与原有的 VM 同样,用 UDP 或者是 TCP 打到 Flume 。

Registry 没有使用 Harbor ,目前是 LVS 后面挂了两台 Docker Registry , registry 是 V2 版本。也遇到一些痛点,好比镜像, Docker Registry V2 版本以前许诺使能够实现镜像彻底删除的,但 Docker 官方也说暂时尚未实现这一点,若是要彻底删除一个镜像,还须要经过 GC 的手段,目前在考虑 Habor ,由于 Harbor 能够实现很关键的一点就是镜像权限的区分。

B 站开发了一套 BiliPaaS 管理工具,作用户的入口或者是镜像发布的需求,包括镜像的管理,并开发了一个 Web Console 直接登陆到容器进行操做,包括监控、告警、配置等。 Jenkins 发布出来的镜像,打到集成环境以后,经过 retag , retag 成 v5.1.3 ,在生产环境作一个灰度发布的界面。容器 Console 能够在 Web 上进行编辑。

Autoscale ,即弹性扩缩,目前决策的依据监控数据是基础的监控数据,也作过一些尝试,发现不太理想,由于 CPU 跟 memory 飙升极可能是异常状况形成的,并非业务的上升致使的,后期会考虑加入 QPS , SLB 或者 CDN 层面的监控数据业务层面来作这个 Autoscale 决策。

在容器的基础设施建设过程当中, B 站遇到了不少问题。咱们使用的是 1.12 ,在 3.16 的使用过程当中发现内核 CFS 支持的时候会有一个 crash 的状况,只能升到 4.4.27 ,可是 4.4.27 已经把 AUFS 默认的内置给取消掉了,因而只能被迫升到了 overlayfs2 , overlayfs2 也遇到了问题, XFS 与 overlayfs2 搭配起来后,好比镜像,会出现镜像文件的损坏,还有 Docker registry 删除的问题,以及 Docker 自身的问题、 Mesos 的问题,刚才提到的 Jenkins 拉起过程当中也遇到一些坑,它会忽然拉不起来了,变得不可控,由于是 Mesos Plugin 直接经过 Jenkins Framework 调用的。

后期展望

B 站会经过 QPS 的业务层指标实现弹性扩缩,另外想引入 Harbor 作开发环境的即开即用,这方面开发已经提过需求,好比但愿消费镜像,在开发环境作开发。 B 站目前实现的是 web 服务和无状态服务容器化,如大数据无状态服务的容器化,一些 TCP 应用包括 Cache 、 MQ 尚未实现容器化。 B 站会有短暂性的业务高峰或者是波动性的数次高峰,须要进行弹性扩缩,这方面也在调研,作混合云方面的基础建设。

分享就到这里,谢谢你们。

相关文章
相关标签/搜索