写点什么

京东如何打造 K8s 全球最大集群支撑万亿电商交易

  • 2020-04-15
  • 本文字数:5827 字

    阅读完需:约 19 分钟

京东如何打造K8s全球最大集群支撑万亿电商交易

在过去一年里,Kubernetes 以其架构简洁性和灵活性,流行度持续快速上升,我们有理由相信在不远的未来,Kubernetes 将成为通用的基础设施标准。而京东早在 2016 年年底上线了京东新一代容器引擎平台 JDOS2.0,成功从 Openstack 切换到 JDOS2.0 的 Kubernetes 技术栈,打造了完整高效的 PaaS 平台。


6 月 28 日京东基础架构部技术总监、集群技术部负责人鲍永成受邀出席了 Rancher Labs 举办的Container Day 2018容器技术大会,并做了题为 《京东如何打造 kubernetes 全球最大集群支撑万亿电商交易》 的主题演讲,本文根据演讲内容整理而成。


鲍永成,2013 年加入京东,负责京东容器平台 JDOS 研发工作,带领团队完成京东容器大规模落地战略,全量承载京东全部在线系统、中间件、数据库以及大数据离线计算任务。目前聚焦在京东 JDOS2.0、阿基米德调度平台(特别抢占式智能数据中心调度系统、京东大幅提升数据中心资源使用率的利器)、“云+端”线下门店生态基础设施以及新一代数据中心研发工作。


在演讲中鲍永成分享了京东在大规模实际生产过程对 Kubernetes 做深入重构的经验,以及京东如何围绕 K8s 启动一些内部新项目,服务 JDOS2.0 大规模生产环境稳定高效运行。


感谢 Rancher 邀请我们来做京东在容器方面的分享。京东的分享可能跟业内的很多做向外输出的公司有点不一样,我们的容器主要是自用。京东的数据中心现在规模已经比较大,实际上我们用 Kubernetes 或者是以前用 Openstack 的思路完全是克隆谷歌数据中心管理的理念。

容器生态建设


其实数据中心就是围绕着几个东西来说:服务器、网络以及一些基础软件,剩下的就是集群的管理。这里要说明一下,我们认为基础软件是数据中心非常重要的一个环节,比如,域名解析、负载均衡、时钟这些东西,虽然 Kubernetes 管理了整个集群,但是这些东西它依然没有。也就是说,要是想把它用得非常好的话,这些软件也要进行一些适当的变革。



京东在使用 Kubernetes 管理大数据中心的时候,也围绕着 Kubernetes 在我们内部的数据中心建了很多生态。首先是适合容器化的 DNS,以及适合容器化的负载均衡,还有适合容器化的文件系统、镜像中心等等。这里面特别要说明一点,就是 DNS 跟 LB,Kubernetes 1.9 合入了高性能的负载均衡。


如果在大规模生产环境中,高性能的负载均衡是必不可少的,但这个负载均衡又涉及到另外一些问题。首先,要跟现有的数据中心适配,京东自主研发了一套负载均衡以及 DNS。虽然社区里有 CoreDNS 等等,但是这些 DNS 存在一个问题,就像昨天某厂的一个故障那样,你把所有的东西这个引导这个,那个引导那个。如果你的 DNS 不在容器内的话,带来的后果是很难料想的。因为京东容器已经发展了很多年,数据中心也比较大,我们单个 Kubernetes 集群能够做到 8000 到 10000 台。因为我们的机器实在太多,如果不做大集群的话,人力管理的投入上会非常大。后面我会解释怎么做到这么大规模的集群。


京东容器化的数据中心建设已经四五年了,已经比较稳定了,虽然我们的 Kubernetes 还比较老,是 1.6 版本,但是我们已经有很多改进,我们现在的重点就是往阿基米德,也就是往数据中心的资源调度这个方向发展。去年双十一的时候阿基米德已经上线了,Kubernetes 使用到后期的时候,你会发现 Kubernetes 并不能解决数据中心资源使用率的问题,它其实仅仅解决了你的发布,或者是管理资源的容器这方面的一些东西。



上图是我们数据中心的基础架构,其实比较传统,我们会把负载均衡、域名,以及我们包的这个 Kubernetes 的 API 统一抽象出来,整个就是一套。然后在每个数据中心部署若干套 Kubernetes 集群,每一个 Kubernetes 集群,会管理三个物理 Pod,大概是一万台的规模。



为了配合这个规模,我们做了一些工作。DNS 最早的时候,还没有 CoreDNS 来适配,大家知道每个数据中心最老的 DNS 是 bind9,适配起来是非常痛苦的,它缺 API,缺很多东西。所以我们就自己研发了一套基于 Etcd 的分布式 DNS,当时提供了 RestfulAPI,直接对接的 Kubernetes 的 watch,这样的话我们就能够做一个非常好的适配。但是后来我们发现一个问题,原来你有可能 10 万台物理机,也就假设就是你的 hostname 的解析也就 10 万个,现在不一样了,一台物理机是 100 多个容器,即你增长了 100 倍。这时运维解析的请求量会激增,增长之后会带来一个问题,抖动、延迟都非常大,间接的就影响了你的业务的 TP 响应。因此我们后来又把我们域名解析的服务,改成了 DBTK 的服务,现在的性能是 bind9 的 19 倍,是 CoreOS 的 60 多倍,每秒查询率能冲到 800 万 QBS。

化繁为简 Kubernetes 重构

有人问,京东做一个这么大的 Kubernetes 集群,是不是特别复杂特别容易出错。确实,如果你的集群非常多,假设你有 50 个集群,那么你误操作的概率可能就是这 50 的概率相加。因此京东会把整个 Kubernetes 的集群做减法,并没有做加法,当然这是代表京东的一家之言了,因为我们是自用,并不是往外卖,所以我们主要是做减法,以适合我们使用。



为了适用上万台 Server 的这种规模,最大的问题就是 API 的负载容易崩溃。比如你把 config-map 存到 etcd 里面去,这个设计本身就是有问题的。如果你的规模比较大的话,一定要去改,如果不改,你的集群很快就会崩溃。其实我们的做法其实还比较传统,就是采用一些缓存技术,就比如说 config-map 我们压根是不会放在 etcd 里去的。因为如果你把 config-map 放到 etcd 里去的话,首先假设有一个用户,给你传一百个 20M 的配置文件,你就完蛋了。


其次,京东对 controller 也做了很多重构,虽然社区提供了很多 controller,但我可以保证,这些 controller 绝对没有做严格的关联性测试,也就是说有些 controller 之间互相是有影响的。建议启用任何一个 controller 前都要做严格的分析跟测试。想做大集群的 Kubernetes,必须得去改,而且是做减法式的改。



还有一点,Kubernetes 号称有各式各类功能,我可能要泼一下冷水。京东很多东西的确是基于 Kubernetes 建设起来的,Kubernetes 对我们的帮助非常大,但是它也不是万能的。


Kubernetes 号称的 deployment、金丝雀发布等等一切都非常美好,但是我来自京东基础架构部门,基础部门要服务业务,而业务会给你提很多需求,第一次你听上去可能觉得这需求非常扯,但是你跟他仔细沟通之后,你会发现人家的需求是非常合理的。比如说,他说你金丝雀发布的时候,副本数随机的挑几个,升级了 50%,但有的业务方会要求就要升级某一个特定 IP。他不是对这个 IP 特别有感情,而是因为他配了很多 host,除了有研发还有测试等等,所以你不得不去面临这个问题,像 IP 不变等等这样的一些需求就会蹦出来,我们都要满足他,才能继续往下走。


还有比如说你的节点被物理故障重启等等,这个时候你要充分的考虑是先拉起新调度过来的容器,还是先拉起原来老的容器,这些策略都要针对你自己的业务去改变。


还有,比如有人说京东大促的时候,我们 Kubenetes 整个的弹性速度非常快等等。但是我可以向你保证,如果真正是那种流量高峰瞬间来的时候,这个弹性是绝对跟不上的。因为等你还没弹完,老的已经被打死了,弹几个死几个,所以一般来说,你要用更多的实例,用调度的方式来做,而不是说通过 scale out 这种弹来做,来不及的。



刚才也提到这些策略 IP 不变,还有我们这有一个很有意思的东西,就是支持容器的 rebuild。我们的资源使用率,通过阿基米德调度之后,我们的资源使用率非常紧张,因为少买了很多机器,同时业务又在不断地增长,这个时候我们资源的限额都会被耗尽,在某些情况下甚至调度器也无能为力。


这怎么办?我们采取了一种古老的方法, 跳过调度器,进行本地 rebuild 。因为你的调度有的在排队,有的 depending,但是有一些业务在发布的时候,他会提出一个问题,我原来有 100 个容器,我发布完之后只剩 80 了,另外 20 个容器的资源被别的业务抢走了,这是不能接受的,所以我们也有了这种所谓的优先 rebuild,就是就地 rebuild,这会带来很多好处。


这么做最明显的一个好处,就是拉镜像至少省了一些时间。还有一个明显的好处是,虽然在数据中心依然很复杂,但当业务部署在某一台容器机器上之后,调用的依赖、调用数据库的链路都是经过了大量压测的,已达到相对最优的状态。如果你今天把这容器从 pod1 搬到 pod2,我说物理 pod,从房间 1 搬到房间 2 去了,那可能会带来抖动或者等等情况。当然这并不代表你损失了 Kubernetes 的很多特性。


补充前面的一点,我们的 deployment 做了大量定制,原生的 deployment 其实还是很难满足这样的要求。比如说在线上,因为是面向生产环境,但是生产环境不会那么美好。首先业务,可能上 100 个容器就有两个容器,它的响应很差,这个时候要去排查或者要去进行其他的操作,这个时候用 deployment 做不到,因为一升级就没了。而我们,让它可以指定把这两个停掉,或者是其他操作,反正就是能够指定,就相当于你要改一些东西,改动量不大,只是在它原来基础之上改。

阿基米德调度器


下面说说我们目前的工作重点。京东整个数据中心规模很大,有老有新,整体的资源使用率会有明显的波峰波谷。比如上图黑底图上蓝色的线,1 点到 6 点时中国整个互联网的流量都比较低,但是到 8 点以后流量就开始逐渐攀升。那么 1 点到 6 点是一个非常浪费的阶段,因为我们有大量的计算资源,这时候我们就可以跟大数据产生互补,把在线应用的波谷算力贡献给大数据做离线计算,刚好大数据也是后半夜,相对来说离线任务更多,因为第二天早上要出报表,于是我们做了一个融合的混合部署的项目,就叫阿基米德,就是把大数据的业务给调到在线业务的平台上去。


这里面就涉及到一个问题,就是隔离性。大家都觉得 Docker 的隔离性已经很优秀了,其实并非如此,它的隔离性没有大家想象的那么好,你看到的隔离都是 Namespace 的隔离,真正的性能隔离其实并没有完全做到位。例如内存回收,它其实是操作系统统一进行回收的。比如上面 10 个容器有 5 个容器狂读小文件,这时候突然内存已经到一定阀值了,它就要做一次 slab 回收。一旦 slab 回收,它就都被 block 住了,其他的在线业务都会被卡住,虽然只是毫秒级的,但是会有毛刺,业务就会来问你发生了什么。特别是在线大数据进来之后,这个问题就会被无限放大,因此在这块你要做适当的改动。京东做得比较早,从 2013 年就开始做容器,在过去几年我们在这块已经做了很多工作。


还有另外一个,大家也都感同身受。业务说我需要 100 个容器,每个容器八个核,其实之后发现每个容器只跑了不到 10%的 CPU,这种情况是有可能的。那怎么办?你不能粗暴地只给业务两个核,出问题谁负责?那怎么办?我们就告诉业务我们给了他八个核(其实没有),只要不出事就行了,出了事解释也无用。这会带来一个巨大的收益,就像上图,绿色的部分是我们给的 CPU,红色是实际使用的,那我们至少给他砍一半。这样做了之后你就会发现,即使一年不买机器,机器也是够的。



调度方面的问题,京东整个数据中心都是用 Kubenretes 来管,我们取名为 JDOS,即 JD Datacenter OS,封包了 Kubernetes 然后做了大量的定制。往上层看,JDOS 支持京东的在线业务。在线业务在 2016 年 6·18 之前全部迁完了。然后 2017 年双十一的时候数据库全部都迁完了,到 2018 年初的时候,我们基本上像中间件类的也都大部分迁上来了,也就是说现在我们除了单纯的存储图片,还在用物理机那种存储型的服务器之外,剩下的全在容器上,现在京东已经看不到物理机了。现在正在做的就是把大数据也往上面导。这会带来一个非常好的收益。



但是把大数据及很多其他业务放上 JDOS 之后我们发现,整个调度变得非常复杂,原来的调度器只是考虑哪一台适合放就可以了,用一句话说,它只负责杀,不负责埋。这会带来一个问题,容器运行之后,带来的影响 Kubernetes 是无能为力的,除非崩溃了,它给你再重新拉副本等等。这看上去会很美好,实际上业务会天天投诉你。


为解决这一问题,我们应用上线的时候会要选优先级,如果你的优先级不高的话,有可能会被优先级高的驱逐掉,相当于我们单独对 Kubernetes 重新做一个东西,即我们的驱逐器。驱逐器会对 pod 打上很多标签,比如优先级、容忍度、副本数等等(例如只有一个副本的话,它优先级再低也不能杀)。这很像 OM 的排序,当宿主机的 CPU、内存 load 达到一定上限的时候,我们就会启动这种排序,很快地把它排出来,立马就驱逐,而且驱逐之后,会告诉调度器不要再往这台上调了。因为有可能资源满了,它又给调回来了,你又给驱逐,就形成一个死循环了。其实基本的理念也非常简单,就是 保障优先级的系统 ,大数据是最先优先级,但是在线业务的话,也要往下放,这样就能在有限资源的情况下发挥最大的作用,特别是大促的时候,如果都是靠买机器来支撑的话,这是非常恐怖的一件事情。因为每次大促我们都要按 20 倍来估,这要买多少机器啊。

总结

最后我想分享一些经验与心得体会。


京东最早是 Openstack,在 2016 年切换到了 Kubernetes,这两种系统我一直做下来的,我的感受就是, Kubernetes 正在往 Openstack 这条路上走,越做越庞大,这是一个非常大的问题。诚然,它有很多 feature 要加,这个也可以理解,可它还是得拆,拆成非常小的模块来做。像现在 CNI、CRI、CSI 这些模块的拆离应该是比较好的一个开始。Kubernetes 在中小规模集群是没有问题的,但是它肯定没有官方号称的那样 5000 台没问题,如果是非常大的规模的话,肯定要去改,否则的话会崩溃。我们在早期的时候,上了一些非重要的系统,经历了非常痛苦的一段时间,它时常崩掉了。


有时候 Etcd 跑着跑着就发现版本差异越来越大,那只能把另外两个干掉,把另外一个副本用来复制另外两份,这会带来巨大的问题。Etcd 的运维现在应该没有特别成熟的一些方案,它不像数据库有很成熟的运维方案,毕竟数据放在里面,如果它崩了,数据就很难找回来,这是非常麻烦的一件事。


还有它的 API,因为它是长链接,一般的负载均衡要特别注意起 API 的时候不能一个一个起,起完了它都来连,搞不好都堆到一台上去了,会导致负载不均衡,所以正常来说要先把 API 起好,再去起 Kubernetes,这样负载均衡才会起到作用。


另外,大家一定要特别注意 Kubernetes 对心跳的判断,因为它发生 not ready 的概率太高了。一旦发生节点 not ready 的话,会产生一系列难以预料的状态,比如网络抖动,某台交换机坏了,有可能它就会这样。所以我们建议心跳检测这一块尽量用另外一套系统来做,把你检测的结果反馈给 Kubernetes,这样可能会更好一些。


2020-04-15 23:04900

评论

发布
暂无评论
发现更多内容

今天 2 点:关于龙蜥社区云原生 SIG 及安全容器 runD 介绍 | 第 24 期

OpenAnolis小助手

开源 云原生 虚拟化 sig 龙蜥大讲堂

Ajax入门教程

倔强的牛角

ajax 6月月更

Linux开发_文件发送与接收

DS小龙哥

6月月更

C#入门系列(二十一) -- 面向对象之继承

陈言必行

C# 6月月更

实践 DevOps 时,可能面临的六大挑战

SoFlu软件机器人

SRE Lesson One -- Day1 准备你的工作环境

耳东@Erdong

SRE 6月月更 SRE Lesson One

浅谈DOM中的类型

大熊G

JavaScript 前端 6月月更

知识管理系统有效推动中小企业信息化发展

小炮

MySql 过滤查询(以字母开头,以数字开头,非数字开头,非字母开头)

迷彩

数据库 MySQL 数据库 6月月更

一条命令开启监控之旅!

TanCloud探云

开源 监控系统

PingCAP 入选 2022 Gartner 云数据库“客户之声”,获评“卓越表现者”最高分

Geek_2d6073

如何写出同事看不懂的Java代码?

码农参上

后端 Java’

InfoQ 极客传媒 15 周年庆征文|分布式设计介绍

No Silver Bullet

6月月更 InfoQ极客传媒15周年庆 分布式设计

深度学习编程常用工具Jupyter Notebook

Damon

深度学习 Jupyter Notebook jupyterlab 6月月更

浅聊一下数据监控(针对MSSQL)

为自己带盐

SqlServer 数据监控 6月月更

全面双录倒计时,融云助力泛金融业务办理高效合规可回溯

融云 RongCloud

Eureka的TimedSupervisorTask类(自动调节间隔的周期性任务)

程序员欣宸

Java SpringCloud 6月月更

Java 中的Comparator使用技巧

Nick

Java stream 6月月更 Comparator nullsFirst

如何使用物联网低代码平台进行设备调试?

AIRIOT

低代码 物联网 低代码开发

应用配置管理,基础原理分析

Java 微服务 构架

【LeetCode】 移除字母异位词后的结果数组Java题解

Albert

LeetCode 6月月更

Flutter 中的 Flash 错误消息

坚果

6月月更

剖析 SPI 在 Spring 中的应用

vivo互联网技术

spring Java’ JavaSPI Spring SPI Dubbo SPI

设计微博系统中“微博评论”高性能高可用计算机构

Fan

架构师实战营

Python 设计模式:单例模式

宇宙之一粟

Python 单例模式 6月月更

视频一对一源码,简单的搭建方式也有技术要求

开源直播系统源码

软件开发 二次开发 一对一源码

mysql中的查询计划及sql语句性能分析:explain

乌龟哥哥

6月月更

我把 b 站拉黑了!

博文视点Broadview

NodeJS mysql需要注意sql注入 🎈

德育处主任

Node SQL注入 6月月更

DOM操作

Jason199

js DOM事件 6月月更

电商增长红海突围,借势小程序生态

Speedoooo

小程序 小程序生态 电商 移动开发 小程序运行时

京东如何打造K8s全球最大集群支撑万亿电商交易_文化 & 方法_Rancher_InfoQ精选文章