1. Operator概述: 如何对 Kubernetes 进行扩展

注:本文所有示例代码都可以在 blog-code 仓库中找到

最近有点太忙了,所以更新比较慢,然后之前 Go 进阶训练营更新的有点太久了,准备换换脑子,虽然我工作上一直和 Kubernetes 打交道但是还一直没有更新过这一块的相关内容,所以就有了接下来的这个系列。

PS: 对于这一块作者本身也是一个初学者,有所错漏,在所难免,希望发现的大佬可以帮助指正,万分感谢

Kubernetes扩展: Operator 这个系列文章主要面向的是对 Kubernetes 的基本概念已经有了一定的了解,想对 Kubernetes 进行一些扩展开发或者是对 Kubernetes 的工作模式能够有更深入了解的同学(PS:和我差不多)。这个小系列会更新 9 - 10 篇文章,这是第一篇 Operator概述: 如何对 Kubernetes 进行扩展,接下来两周工作日每天会更新一篇,想要及时获取更新可以移动到文章底部关注微信订阅号。

Kubernetes 有哪些扩展点?

Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用[1]

虽然现在 Kubernetes 已经是容器编排的事实标准,其本身的功能也非常丰富并且灵活,但是也不能满足所有人的需求,在遇到 Kubernetes 提供的能力无法满足我们需求的时候,我们就可以利用其强大的扩展能力进行定制。

所以问题来了: Kubernetes 有哪些扩展点呢?

kubernate 扩展

如上图所示,从客户端到底层容器运行时,绝大部分地方 Kubernetes 都为我们预留了扩展点,我们从上往下一个一个的来看

1. kubectl

kubectl 是我们平时和 Kubernetes 交互使用的最多的客户端工具,常见的运维操作都会通过 kubectl 来完成,kubectl 为我们提供了插件机制来方便扩展。

kubectl 插件其实就是以kubectl-为前缀的任意可执行文件 ,执行 kubectl 插件的时候可以通过 kubectl 插件名 参数 的方式运行插件。

就像 Ubuntu 使用 apt 管理软件,mac 可以使用 brew 一样,kubectl 也有类似的插件管理工具 krew [4] ,同时我们可以从 https://krew.sigs.Kubernetes.io/plugins/ 查找是否已经存在我们需要的插件

2. APIServer

聚合层

从 Kubernetes v1.7 版本之后 APIServer 引入了聚合层的功能,这个功能可以让每个开发者都能够实现聚合 API 服务暴露它们需要的接口,这个过程不需要重新编译 Kubernetes 的任何代码[3]

如果我们将下面这个资源提交给 Kubernetes 之后,用户在访问 API 服务器的 /apis/metrics.Kubernetes.io/v1beta1 路径时,会被转发到集群中的 metrics-server.kube-system.svc 服务上

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: apiregistration.Kubernetes.io/v1
kind: APIService
metadata:
name: v1beta1.metrics.Kubernetes.io
spec:
service:
name: metrics-server
namespace: kube-system
group: metrics.Kubernetes.io
version: v1beta1
insecureSkipTLSVerify: true
groupPriorityMinimum: 100
versionPriority: 100

准入控制

除此之外无论是从 kubectl 还是 client-go 等其他客户端发起的请求都会发送到 APIServer 经过 认证 -> 鉴权 -> 准入控制 的步骤,这其中的每一步我们都可以对其进行扩展,而这其中用的最多的就是准入控制的扩展,这一块后续会一篇文章详细讲到。

准入控制当中又会先经过,变更准入控制 MutatingAdmissionWebhook,然后再经过验证准入控制 ValidatingAdmissionWebhook,任何一个准入控制器返回了错误这个请求都会失败,例如这两个准入控制器我们可以做很多事情,例如注入 sidecar,验证资源,调整 pod 的配额等等。

3. Kubernetes 资源

我们常用的 Deployment、Pod、Node 等都是 Kubernetes 官方提供的内置资源,但是有的时候内置的资源无法满足我们的需求的时候,就可以使用 CustomResource 也就是自定义资源。自定义资源常常会和 Controller 一起配合使用,不过需要注意的是使用自定义资源的时候需要思考一下如果只是一些配置可能 ConfigMap 会更加适合,不要滥用这个特性。

4. Controller 控制器

Kubernetes 中资源的状态的维护都是 Controller 来实现的,Controller 会不断的尝试将一个资源调整为我们描述的状态,这其实也就是我们常说的声明式 api,声明式 api 背后具体的活都是 Controller 干的。Controller 一般会配合着 CRD 一起使用。

5. Schedule 调度器

调度器是一种特殊的控制器,负责监视 Pod 变化并将 Pod 分派给节点,调度器可以被直接替换掉或者是使用多个调度器,除此之外官方默认的调度器也支持 WebHook。[5]

6. CNI 网络插件

CNI 网络插件,全称 Container Network Interface(容器网络接口)包含一组用于开发插件去配置 Linux 容器中网卡的接口和框架。一般我们不会去对网络插件做定制开发,而是采用开源的组件,例如 Flannel、Cilium,如果使用云服务的 Kubernetes 还会遇到一些定制的网络插件, 例如阿里云有 Terway。

7. CSI 存储插件

CSI 存储插件,全称 Container Storage Interface,可以通过 CSI 接口支持不同的存储类型

8. CRI 容器运行时

CRI 容器运行时,全称 Container Runtime Interface,是一组用于管理容器运行时和镜像的 gRPC 接口,利用这个接口可以支持 docker、containerd 等不同的容器运行时

Operator

Kubernetes 是一个高度可扩展的系统,虽然它的扩展点这么多,但是一般来说我们接触的比较多的还是 自定义资源,控制器,准入控制,有些还会对 kubectl 和 调度器做一些扩展,其他的大部分使用成熟的开源组件就可以了。而我们这个系列关注的 Operator 就会涉及到 自定义资源,控制器和准入控制。

Operator 遵循 Kubernetes 的理念,它利用自定义资源管理应用及其组件, Operator 模式会封装你编写的任务自动化代码。

Operator 常见使用范围包括:[6]

  • 按需部署应用
  • 获取/还原应用状态的备份
  • 处理应用代码的升级以及相关改动。例如,数据库 schema 或额外的配置设置
  • 发布一个 service,要求不支持 Kubernetes API 的应用也能发现它
  • 模拟整个或部分集群中的故障以测试其稳定性
  • 在没有内部成员选举程序的情况下,为分布式应用选择首领角色

从 Operator 理念的提出到现在已经有了很多工具可以帮助我们快速低成本的开发,其中最常用的就是 CoreOS 开源的 operator-sdk 和 k8s sig 小组维护的 kubebuilder,我们这个系列选用 kubebuilder。

除了我们自己开发之外还可以在 https://operatorhub.io/ 上找到别人开发的现成的 Operator 进行使用

总结

Kubernetes 从 2014 年发布至今已经 7 年了,我从毕业加入到现在的团队从事周边的工作也已经快 3 年了,期间虽然对 Kubernetes 已经有了基本的了解但是还是一直都没有对 Kubernetes 本身进行过扩展的开发,这篇文章写完之后算是对 Kubernetes 扩展开发有了一个基本的了解,希望对你也能有所帮助。

参考文献

关注我获取更新

wechat
知乎
开发者头条
github

猜你喜欢