容器化管理演进
演进过程
swarm
单集群,共享宿主机端口,服务发版有一定时间服务不可用。
k8s 原生控制器
多集群支持,支持简单的发布策略
主要为黑盒操作,即以修改 k8s 原生资源配置为主,无法实现灰度发布,蓝绿发布等高级功能。
随着容器化的持续进行,越来越多的业务跑到 k8s 集群上,目前已有 6 个不同集群对外提供服务。
目前 k8s 社区十分活跃,为了稳定性和安全性,版本升级较频繁,目前由 1.10,1.14,1.15,1.16 多个版本的集群并存。
此外,阿里云、私有云并行存在,基础设施不同。
多集群,公有云、多版本,集群差异较大,统一管理逻辑复杂,维护困难。
服务状态主要靠同步查询,难以渐进式控制发布过程。用户体验不够友好,查看状态需要手动刷新。
边界不清晰, 管理系统(chons)关注点太多,越来越复杂,不好维护。
封装不够完善,暴露了较多 k8s 内部细节给前端、以及用户,增加其认知成本。
扩展不方便,每暴露一个配置项,都需要新加接口,成本高。
组件控制器
k8s 是一个伟大的项目,为很多服务管理过程中常用的资源做了高度抽象,并且 k8s 系统高度通用、高度灵活,能够完成服务管理和维护的多种多样的需求。
因此同时 k8s 系统也是一个较复杂的系统。除了 k8s 专家,不论是开发和运维同学,拿到 k8s 的资源配置文件都显得过于复杂,搞得人一头雾水。
解决复杂计算机系统的问题的一个通用的方法就是利用分层的思想,在复杂系统之上再抽象出一层,分层管理:
- 高级编程语言在汇编语言之上
- 操作系统在驱动之上
- 网络七层模型层层抽象
按照这个思路,为了依托 k8s 生态为公司服务管理平台持续赋能,以及更好地解决多集群精细化管理的问题,我们在 k8s 原生资源之上抽象出组件层,并采用 k8s CRD operator 的模式开发了组件控制器,每个控制器独立管理每个集群的服务:
- 屏蔽 Deployment, StatefulSet, Service, Ingress 等内部实现细节,降低研发人员心智负担
- 集群管理与上层业务调度解耦
- 接近 k8s 原生资源的保障
- 集群生命周期管理
- 接近 k8s 原生资源的体验
设计思路
组件是一等公民
deployment 由 deployment controller 控制;
service 由 service controller 控制;
组件(component) 由 component controller 控制。
自定义 spec 以简洁的方式支持公司业务类型
采用 Config As A Service 支持灵活扩展,减少接口,减少开发成本。
例如最简单的服务定义可能包括:开发语言,服务类型,端口和镜像即可,如下 spec 部分所示。
apiVersion: component.luojilab.com/v1alpha1
kind: Component
metadata:
name: nginx
spec:
workloadType: Deployment
developLanguage: python
runType: server
image: python-demo:latest
port: 8080
在尽可能保持简洁的基础上,如果用户有特殊需求,必须也能支持。
向下兼容
支持老服务无感升级
方便升级
需要能够方便的进行集群级别的批量调整,比如配置调整,性能优化等。
灵活扩容
性能不足时,需支持灵活扩容
资源定义
type(GVK):
- group(luojilab.com)
- version(v1alpha1)
- kind(Component)
meta:
- label
- annotation
- create_datetime
- update_datetime
- delete_datetime
spec:
控制器的基本本原理
reconcile
所有接口幂等性
触发机制
level based trigger
edge based trigger
level + edge based trigger
模板化管理
集群差异管理
负载类型模板
开发语言模板
部署发版流程
滚动发布
灰度发布
状态变更感知
status 变更
event 事件推送
controller 升级/灰度
annotation:
"component.luojilab.com/unmanaged": true 则不会触发控制器,可用于选择组件是否接受控制器管理
资源定义升级
每个资源定义都有一个 GVK, group version kind
通过通用的 hub 可实现版本自动转换
比如 component v1alpha 时我们使用阿里云 slb 做负载均衡,在 v1beta 中我们改为采用自建 lb,可简单的通过定义一个转换器来实现。
component v1alpha
spec.svc.type = 'aliyun-slb'
component v1beta
spec.svc.type = 'luoji-slb'
并调用自建 lb 服务的接口创建并绑定新的 lb。
变更将在任何一次对资源的变更后自动触发,完成 spec 升级,同时切换至新的 lb ,业务方无感知。
分布式--高可用
多备单活,抢占锁
主备每个服务维护一个 workqueue 队列,每次更新请求和状态变更同时向主备的队列中发布,然后拿到抢占锁的队列执行操作。
分布式--水平扩展
k8s 默认监听机制下,资源控制器会监听全部资源。
如果遇到性能瓶颈,可以添加 controller id 索引,不同资源使用不同的控制器。
监控
metrics
参考
OAM
未来展望
1 serverless
2 弹性伸缩
3 服务亲和力感知
4 容器自动创建 --> 自动添加 worker 节点 --> 集群自动搭建
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。