前言
本来计划这篇写一写k8s设计特点,但是最近在做技术路线规划方面的事情,笔者在旷视科技做一款名为devops的私有云产品(此devops非彼devops)后文称之为MDO(megvii devops私有云),自研了一套类似k8s的编排调度工具。k8s只是私有云中的一个子集,私有云不仅关注编排部署,还关注自身部署升级、易用性、稳定性、异构、安全性、监控告警、灾备、基础设施、文档在地化等。
从这个角度上看,对比MDO和k8s并不公平,因为k8s只是私有云中管理编排调度、网络存储等方面的一个核心组件。虽然对比并不全面,但是很有意义和价值,可以从架构组件,对于云管理的概念抽象两个角度纵向对比思考,加深对云管理的认知。
组件架构
MDO
mdo架构如下, 通过manager + agent两个概念管理集群,manager 和 agent上运行的都是无状态的服务,集群状态持久化到etcd中。
- manager
主要包括mdo-manager服务、etcd集群、Prometheus、Altermanager、Grafana监控告警系统、Ntp server时间同步组件、Nginx、keepalived、CoreDns高可用负载均衡网络组件。 -
agent
主要包括mdo-monitor自定义监控组件、mdo-ctl、Ntp Client、Node Exporter等。
devops架构.png
K8S
k8s架构如下也是manager + agent两个概念管理集群(我个人理解master + slave和manager+agent是一个意思,只不过狗屁的政治正确导致还是叫manager, agent文明一些)。集群的状态持久化到etcd中,这样天然好做高可用。
- manager
manager上有controller manager、scheduler、API server + etcd。其中API Server是etcd的入口,提供持久化的抽象。 -
agent(即Node)
包含CNI网络组件、Kubelet、CRI组件、持久化组件。
k8s-components.png
从架构上来看MDO和k8s基本一致,如果k8s加监控告警也基本上使用prometheus+altermanager+exporter三件套,时钟同步也会用ntp server+client两件套。但是,k8s的容器运行时和网络都采用组件化的方式。
抽象概念
K8S
k8s_components.png- Deployment
编排部署, 复杂应用一般还需要Deployment上 再有一层依赖。 - Ingress
对外暴露service,Ingress在k8s中是一层概念抽象,有多种实现,常见的有Nginx ingress, haproxy ingress。 - Service
对外暴露pod,由于Pod自身启动的ip不是固定的,k8s设计service这个概念,通过dns的方式对外代理服务,service是k8s proxy 完成(待续) - Pod
逻辑概念,k8s并不真实存在pod。 Pod的目的是为了解决容器进程的问题,容器的本质是进程,但是编排部署的时候,需要做进程组级别的管理,pod大致对标虚拟机,承担调度,网络,存储,安全方面的功能,在pod里提供sidecar功能。 - Container
服务容器化,k8s容器化的起点,以container的形式运行在k8s集群中 - CronJob
定期任务 - Job
任务, 通常我们关注的重点是job的并发机制,exit code != 0后,retry机制等。 - StatefulSet
有状态服务,主要包括两点,持久化存储的有状态,服务启动的有状态即服务之间的依赖关系,k8s通过给stateful set的pod编号,这样服务之间的依赖关系可以根据编号的顺序启动,MDO中使用rank来实现服务之间的依赖。持久化存储是依赖pv/pvc的编号实现的。 - DaemonSet
守护进程通常出现早于集群的出现,通常管理网络、安全、存储、日志等事宜。守护进程exp网络插件通常先运行在pod上,pod才能变成schedule,也就是说网络守护运行前,pod还没有进入schedule, 普通的进程是不能运行在unschedule的pod上的,这里就出现了悖论,不运行网络进程,pod并不会变成schedule,但是正常逻辑网络进程无法运行在unschedule的Pod上。
k8s并没有做黑魔法操作,而是引入了tolerations概念,即污点容忍,用来描述进程可以运行在某种污染比如unschedule的节点上。daemonset运行时自动加上tolerations字段,这样就可以运行在unschedule的pod上。 - Horizontal PodAutoscaler
水平扩展 - ConfigMap
Config配置 - Secret
数据安全相关
MDO 功能与抽象概念
-
Node
机器节点,运行的实体机器资源抽象,包括GPU、Memory、CPU、NVME等计算内存存储资源 -
Deploy
container组级别的服务部署:可以多个container部署在同一个Deploy中 -
生命周期
instance启动时,可以自定义Pre操作,结束时可以运行Post操作,pre和post是按照顺序执行的,instance运行状态为运行中和服务健康检查,对标k8s的liveness和readiness。 -
容器治理
mdo的服务治理策略和k8s完全不同,k8s主要用于公司内部有运维的治理,可以理解为是标准机房或者机房的基础设施较好。所以k8s对于pod等管理方法为当list到某个pod不存在(exp:防火墙断网等情况)会重新生成新的Pod调度资源。
mdo使用的场景为私有化机房,非标准、无运维、网络设施较差的场景,调度部署是manager来处理,但是调度部署后,对容器的运维拉起等在每个Node节点,依靠supervisor来管理。假设集群节点间断网,那么断网的Node上容器是正常运行的,还可以被supervisor治理。manager不会重新生成pod。 -
Service
Deploy组级别的服务部署,提供deploy之间公用的变量、配置、部署依赖等。提供patch、diff、回滚等功能 -
Job
- Runonce
只运行一次的job,job的运行状态会被记录到etcd中,如果失败不会自动retry,运行失败需要手动retry。 - Normal
可以retry,运行时exit code为0时标识Done否则会retry,和runonce区别在于normal job是幂等或者是可以重复执行的。
- Runonce
通常用来处理数据库初始化等。
- 网络
- instance独立IP
使用Flannel vxlan + etcd + coredns实现每个docker 容器有自己的ip。flannel vxlan模式通过分配子网的方式,提供三层上的两层网络,实现ip独立。 - 高可用
使用KeepAlived + VIP + nginx提供高可用入口,其他高可以服务。etcd自身高可用,备份,恢复 - 单向网络
通过隧道的方式实现manager到agent的单向网络。
- instance独立IP
- Debug
调试不是一个概念,而是MDO对用户提供的调试工具,mdo通过提供webterminal功能,是的用户可以通过界面登录到节点或者container中调试分析,同时webterminal还具有操作审计,回放历史等功能。 - 文档在地化
对于一个项目文档的重要性不言而喻,尤其对于像MDO这种toB的私有云,不同的版本,文档会有变动,靠内部wiki等记录文档是不好的。exp:某个现场部署的一年前的版本,某个现场部署的是两年前的版本,遇到这样的现场oncall问题,搜索内部wiki等方式是无法很好应对的。
MDO是把文档集成到repo中,直接在自身web服务的界面中显示。优点如下:
- 私有化现场出现问题可以在现场查阅文档,本地文档直接对应本地feature。
-
当一个同学开发新的feature或者有修改时,在commit同时必须包好文档的变动,可以review代码的时候也review到文档,甚至对于新入职的同学或者是不熟悉相关模块的同学根据文档的变化反过来review code的合理性。
image.png
网友评论