1. 唯品会Noah云平台的构建历程
Noah云平台从2017年初开始调研,3月份确定选型和架构,7月份已经开始接入业务,到现在已经研发了1年半时间,现在部署了5个IDC,共9个Kubernetes集群(有些IDC部署了两套Kubernetes集群),其中两套Kubernetes集群供AI使用。
1.2 云平台的目标
这里讲些我们建设云平台的目标,主要从资源利用率提升,开发测试运维一致性和对DevOps的进化三个目标,其实就是提高人效和机器效率。
Noah云平台整体架构按架构层次,分为主机层、容器层、云平台层(后面说的Noah Server),其中容器调度使用了业界开源的Kubernetes 1.9.8版本,容器层使用Docker 1.13.1版本,容器网络使用Contiv+Netplugin方案。
Noah云平台层(Noah Server),后面会说到,它是整个Noah云平台的粘合层,对外提供容器Lifecycle管理和集群管理,网络管理等API和UI。
Noah云平台也包括了CI/CD流水线,负责业务镜像的构建,提供功能联调环境(Pandora)测试,它支持业务开发快速创建自己的测试环境,把依赖的服务快速拉起。目的是提高业务测试的效率。
Noah云平台也提供了基础镜像和镜像存储。
运维的发布系统、CMDB、ITIL(变更系统),都会对接Noah云平台相关API或UI做集群和容器的相关操作。
Noah云平台也部署了一套跟生产完全一样的Noah Staging环境,只是规模不一样而已。它提供了业务镜像上线前的集成测试。
Noah云平台是基于Kubernetes+Docker技术框架构造的,虽Kubernetes已经成为容器编排的胜出者,但真正使用过程中,还是需要结合公司的实际情况使用。比如:
过于Cloud Native化
Kubernetes,包括CNCF下的开源项目,都是以Cloud Native为方向,而对于企业来说,都有历史包袱,比如物理机/VM 和容器混布一段时间,比如有自己的服务化框架和日志监控系统,容器化必须与公司的基础设施打通
功能复杂,偏分布式应用开发者
提供基于yaml文件的声明式API,运维和开发使用起来比较复杂,容易出错
Kubernetes提供丰富的功能,但都需要深入了解才能用好,对运维和开发要求高
功能很完美,但现实很骨感
Kubernetes Deployment的rolling upgrade策略不适用唯品会的发布流程
多集群管理Federation还不完善,Federation现在还处于Alpha阶段,不太稳定。依赖CoreDNS和ETCD,增加系统部署的复杂度。不支持Pod信息的聚合,不方便做watch
3.2 Noah Server的定位
摆在我们面前两条路,一个是修改Kubernetes源码支持我们的需求,但这会跟社区分岔路会走得越来越远,享受不了开源社区给我们带来的好处。因此我们在Kubernetes上构建一套Noah Server,来标准化和简化Kubernetes的使用。我们定义它为Noah云平台的粘合层。我们的思路,跟来自张磊的《Kubernetes项⽬目与基础设施“⺠民主化”的探索》workshop结语说的有点像,走扩展,组合机制,而不是硬改代码的机制。Noah Server主要解决以下问题:
UI支持,标准化使用流程
多机房多集群管理,同机房两套集群
灰度分批分部署池发布(每套Kubernetes集群相当于一个部署池,为了减少新版本发布导致的问题,使用分批发布分批验证)
与公司的发布系统和变更系统深度集成,提高运维操作的效率
容器生命周期管理(摘流量、隔离、Debug)
提供统一的注册发现机制,对业务透明
支持多种应用类型的Health Check
支持容器部署的高可用
支持一键容灾迁移(若某个集群不可用,可快速把该机房的容器迁移到其他机房)
3.3.1 基础镜像
Noah云平台提供了唯品会所有应用类型的基础镜像、OSP(唯品会服务化框架)应用、Tomcat应用、PHP应用等,云平台提供CI流水线让业务自己构建镜像,CI流水线自动根据应用类型选择最新发布的基础镜像来构建。
基础镜像的初始化脚步基于my_init开发了vip_init脚本,来管理基础镜像运行的Service。以下是容器启动和销毁的流程。包括了容器启动和关闭的关键步骤。
Noah镜像都是按照Docker的镜像分层来构建,基础镜像+业务镜像+配置 = 业务容器,Noah云平台调用唯品会运维的crab系统获取容器的运行时配置信息[环境变量配置]。
下图简单介绍了基础镜像层的分层结构:
3.3.2 镜像仓库
我们在开源的Harbor上做了二次开发,支持多机房同步,支持唯品会的分布式存储VOS存储镜像,支持镜像同步监控等功能。
镜像发布流程是这样的:
测试环境部署Harbor A,准备release的镜像发布到Harbor A,Harbor A也会存储测试的镜像
各机房部署Harbor B,但网络安全只开通gd9机房的Harbor B与测试环境的Harbor A相通
其他机房通过分布式存储VOS做镜像同步
3.3.3 灰度分批发布
灰度发布是减少发布故障的主要手段,Kubernetes管理的资源对象,如Deployment,StatefulSet等都提供了滚动升级的策略,但Kubernetes暂时不支持分批的滚动,因为每发布批次都需要验收测试。举个例子,比如说某个域有10个容器,我们希望能够分3批来发布,第一批发布容器个数为1,第二批为4,第三批为5,每批次都需要业务方确认没问题,再继续执行下一批操作。
我们也从京东了解过,他们修改了Kubernetes代码,增加了group controller来支持这种分批暂停的验证。但我们考虑以后Merge代码的复杂性,所以对于这个功能没有修改Kubernetes的代码,而是使用了下面介绍的方式。
下面我们介绍下我们灰度分批的方案,其实很简单,就是两个Deployment,一个Running Deployment,一个新版本Cannary Deployment。Running Deployment做scale down,Cannary Deployment做scale up,最后发布完成,删除旧的Running Deployment。若在发布中发现有问题,需要回滚,那做反操作即可。
灰度分批发布流程:
3.3.4 容器Auto Scaling
使用容器后的另一个好处是容器可以很方便的做伸缩,但其实有更高级的实现是Auto Scaling。
Kubernetes提供了HPA功能,是Kubernetes Controller Manager的一个组件,但使用HPA有些Limitation:
HPA依赖Heapster服务来获取容器的资源使用情况,而我们已经有自己的监控系统
提供Custom Metric的接入方式,但引入了Custom Metric Server后,需要在Kubernetes Controller Manager和Kubernetes API Server直接部署kube-aggregator(Reserve Proxy)组件, 对 /apis/* 请求,转发到 API Server 上。对于apis/custom-metrics.metrics.k8s.io/v1alpha1 请求, 转发到后端的 Custom Metric Server,这样增加了部署的复杂度
由于HPA有以上的Limitation,然后调研Kubernetes的HPA算法,我们决定自己做容器的HPA。
Noah云平台的HPA实现:
支持多种策略(CPU、IO)
多种策略同时计算,选最优的策略执行
支持多种因子
Cold down window(扩容冷却时间为3分钟,缩容为5分钟)
Tolerable factor(容忍Metric值上下波动5%)
Frustrated level(以Target值的1.4倍作为警戒线,若超出警戒线,忽略Cold down window继续扩容)
计算公式:TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target) ,Target为HPA规则设置的目标触发值。比如cpu usage > 50%
集群管理很多节点,所有操作多为批量操作:
Node Label自动同步
每台节点都需要打上node label,如rack信息,machine-type等。云平台从CMDB系统同步信息自动打上rack,machine-type等node label
批量查询/调整 节点上所有容器的流量权重
批量上/下线节点
3.3.6 多集群事件监控
Noah云平台管理了多套Kubernetes集群