Kubernetes即服务:扩展Kubernetes Cluster API

作者:徐亚松,百度云原生团队资深研发工程师,负责容器监控日志、Kubernetes 多集群管理、稳定性建设等工作。

Kubernetes 逐渐成为云原生时代的基础设施,越来越多的企业级服务运行在 Kubernetes 平台上 ,但随着集群拆分和业务规模的扩张,Kubernetes 的多集群管理越来越复杂,也出现了如 cluster-api/KOK 等开源、业内方案,本文将分享百度云原生团队在大规模集群管理中遇到的问题,以及云基础架构的设计、改造的经验。

阅读之前可以先了解一下 开源的 cluster-api 的设计思想: https://cluster-api.sigs.k8s.io

背景介绍

百度以 Kubernetes 作为底座,支撑了AI、教育、函数计算、边缘计算等内部业务上云,以及不同场景的外部客户需求,管理了上千个集群、上万台节点,这些集群节点规模不同、Kubernetes 版本不同、机器异构,有些还要求定制化参数。在 Kubernetes 集群的生命周期中,会有节点自动扩缩、配置变更,以及繁琐的漏洞修复和集群升级,这些操作复杂且危险,如何方便地管理大规模集群,并且保证业务系统的稳定性呢?

如上图所示,面临的挑战主要是:

  1. 兼容不同的机器类型和 OS 版本: 无论是标准云环境、内部定制化还是私有化环境,能够做到一套代码兼容,或者一套基础定义(Interface),不同环境只是不同的接口实现。
  2. 涵盖各种集群类型: 如独立 Master、托管 Master、纳管已有集群、Serverless 集群等,用户只需要自己的集群类型。
  3. 处理集群的各种操作: 机器创建、部署、扩容、缩容等,以及最复杂的集群升级和漏洞修复、配置变更。
  4. 插件管理和组件自定义: 抽象常用的插件,如必选和可选插件,插件变更与升级,Kubelet 动态配置、Feature Gate 自定义等。

以集群和节点两种资源为例,实现的目标主要是:

集群操作:

  • 创建
  • 删除
  • 扩容
  • 缩容
  • 移入
  • 移出
  • 纳管
  • 集群升级
  • 自动伸缩

节点操作:

  • IAAS 资源操作
  • 部署操作
  • 节点组管理
  • 自恢复

实现方案

为了实现上边的目标,我们借鉴了 Cluster API 的设计思想,并结合自身需求,定义了自己的 CRD 和 Operator,将原有平台中的命令式 API 改造为声明式 API,辅助全局的监控和事件,实现真正的用 Kubernetes 来管理 Kubernetes (KOK)。

示意图:

声明式 API

Kubernetes 的声明式 API 颠覆了传统的过程式运维模式,用户只需要在 Spec 里定义自己所期望的状态,Kubernetes 的 Controller 会进行一系列操作帮助使用者达到期望状态,只要不满足要求,Controller 会一直尝试。

命令式 API 和声明式 API 的对比:

Kubernetes 中声明式 API 的理念:

  • 使用 YAML 来定义 K8S 中的所有对象
  • 最终一致性
  • 方便观察状态变化
  • 易扩展、更稳定
  • 只需要实现 controller 的reconciliation

我们定义了 Cluster、Instance、InstanceGroup、Plugin 等 CRD,通过 YAML 来声明集群配置,各种 controller 来保证符合用户期望。

Meta Cluster

Meta Cluster 是元集群,即管理员侧的 Kubernetes 集群,也是 Kube-On-Kube 中底层的 Kube 集群,CRD 和 controller 都属于 Meta Cluster, 每一个 Cluster CRD 的实例都对应了一个 User 用户集群。

Kube-On-Kube 这个词有几种含义延伸,User 集群的 Master 机器可以运行在 Meta Cluster中,即 Master 容器化,所有用户共用 Master 资源池,或者 User 集群的 Master 机器完全隔离,与 Meta Cluster的资源池毫无关系,也是完全不同的 VPC 和机型,百度使用的是后者。

Cluster

以创建集群为例,大致流程是:

  1. 用户提交 Cluster CRD,一般是由用户填写语义化的表单,Service 层将表单转化为 YAML,提交给 Meta Cluster 的 Apiserver。
  2. Cluster CRD 落库到 Meta Cluster 的 ETCD中。
  3. Cluster Controller 监听到新的 Cluster 对象,准备创建集群,开始 reconciliation流程。
  4. Cluster Controller 会创建负载均衡,创建 n 台 Master 机器,并完成证书签发、公网 IP 绑定、组件初始化等。
  5. 不断检查确认期望状态和实际状态一致。

Instance

机器和集群的逻辑类似,主要是完成 Node 节点的创建、部署、网络初始化、存储初始化等操作,同时支持自定义脚本或不同的容器运行时。

Instance Group

节点组主要用于人为定义一组同功能的机器,如 一组 GPU 机器、一组存储优化型机器等,主要作用有:

  1. 物理隔离业务容器: 通过对节点组内的机器批量打上 label,让不同的服务调度到同一集群的不同节点组内,保证服务之间做到节点隔离。
  2. 批量变更: 如某种 OS 的机器为一组,如果 OS 出现安全漏洞,可以批量进程安全维护,方便管理且不影响其他机器。
  3. 自动扩缩容: 节点组的核心能力是用于配合 cluster autoscaler 进行节点的自动伸缩,节点组内都是同配置的机型,一旦出现资源不足就会自动触发扩容新机器,一个集群允许存在多个节点组。在云场景下,节点组和 autoscaler 的配合可以把云的伸缩能力发挥到极致。

InstanceGroup 类似于 K8S 中的 RS,可以管理多个 Instance 副本(Pod),且这些副本都是由同一个 InstanceTemplate 产生(PodTemplate)。不过在实际业务中,Pod 和 Instance 还有些差异:

  • Pod 副本之间没有任何区别,删除一个会新建新的 pod,但 Instance 因为 IAAS 资源的固定性,Instance 之间还是有着本质的区别(机器 IP),大多数情况下 Instance 的变更是针对机器上的进程,而不会销毁机器重建,如集群升级中原地替换的场景。
  • RS 和 Pod 的关联是通过 selector 来完成,是一种”弱关联”,但 InstanceGroup 中的机器,OS 和内核一般都是一致的,会通过多种 Check(如登录机器校验)来判定是否属于同一个InstanceGroup 配置,否则在后续的业务运行中会出现问题。
  • 因为 Instance IP 的唯一性,用户可能希望在变更一个 InstanceGroup时,按照特定的机器顺序来完成,如先执行机器 A,再执行机器 B,这看起来和 Pod 的设计理念有些区别,不过可以通过定义 Instance 优先级来满足。

如下图所示:

多集群管理的可观测性

多集群管理的另一个挑战就是如何观察 Kubernetes 集群的状态,一旦客户集群遇到了问题,管理员可以迅速做出反应以进行修复,甚至可以提前预警,将问题消灭在萌芽之中。因此我们需要进行全局视图的监控、日志、事件和审计。

对于监控,我们使用 Prometheus + Thanos 作为主要架构。Meta 集群会收集所有 User 集群中的各种指标,如:

  • 机器指标:包括 Master 机器和 Node 机器,如 CPU,内存,磁盘等
  • 进程指标:包括核心进程如 Apiserver、Etcd、Kubelet、Docker 等
  • 性能指标:如 Apiserver的 Metric、Etcd 和 Scheduler 的 Metric 等
  • Cadvisor 和 Kube-state-metrics 指标
  • 自定义 Exporter 指标
  • Node-problem-detector 监测 Node 异常,联动 Autoscaler

对于日志,我们采集容器内日志和标准输出,将日志推动到 ES 中做后续的处理和分析,日志的产出一般有两种:

  • 日志直接推送到 ES 存储
  • 日志转 Metric,存入 Prometheus

对于事件和审计,我们收集 Kubernetes Events 推送到 ES 中,分析后配置 Events 报警,如 Pod Crash、Image Pull 失败等,通过 Webhook 收集 Apiserver 的 审计信息,统一推送到内部的审计中心。

如上图所示,Meta 集群中收集的监控和事件信息,检索分析后一方面提供监控图、日报给用户,另一方面反馈到用户集群中,如 HPA、节点伸缩、异常节点替换等。

总结

本文介绍了百度云原生在 Kubernetes 多集群管理遇到的一些问题和实践方案,Kubernetes 生态越来越繁荣,对集群管理平台的稳定性和扩展性的要求越来越高,相信不久未来会有更多的探讨和理念。本文内容是 kubecon 2020 中国云原生线上峰会的 topic 。

转载请注明来源,谢谢:中国开源协会(OSCNA) » Kubernetes即服务:扩展Kubernetes Cluster API

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址