从零开始入门 K8s | Kubernetes API 编程范式

简介: 在 Kubernetes 里面, API 编程范式也就是 Custom Resources Definition(CRD)。我们常讲的 CRD,其实指的就是用户自定义资源。为什么会存在用户自定义资源问题呢?本文将会从其需求来源出发,对此概念进行逐步深入的讲解。

作者 | 陈显鹭  阿里巴巴高级技术专家

本文整理自《CNCF x Alibaba 云原生技术公开课》第 23 讲,点击“阅读原文”直达课程页面。
关注“阿里巴巴云原生”公众号,回复关键词“入门”,即可下载从零入门 K8s 系列文章 PPT。

导读:在 Kubernetes 里面, API 编程范式也就是 Custom Resources Definition(CRD)。我们常讲的 CRD,其实指的就是用户自定义资源。为什么会存在用户自定义资源问题呢?本文将会从其需求来源出发,对此概念进行逐步深入的讲解。

一、需求来源

首先我们先来看一下 API 编程范式的需求来源。

在 Kubernetes 里面, API 编程范式也就是 Custom Resources Definition(CRD)。我们常讲的 CRD,其实指的就是用户自定义资源。

为什么会有用户自定义资源问题呢?

随着 Kubernetes 使用的越来越多,用户自定义资源的需求也会越来越多。而 Kubernetes 提供的聚合各个子资源的功能,已经不能满足日益增长的广泛需求了。用户希望提供一种用户自定义的资源,把各个子资源全部聚合起来。但 Kubernetes 原生资源的扩展和使用比较复杂,因此诞生了用户自定义资源这么一个功能。

二、用例解读

CRD 的一个实例

我们首先具体地介绍一下 CRD 是什么。

CRD 功能是在 Kubernetes 1.7 版本被引入的,用户可以根据自己的需求添加自定义的 Kubernetes 对象资源。值得注意的是,这里用户自己添加的 Kubernetes 对象资源都是 native 的、都是一等公民,和 Kubernetes 中自带的、原生的那些 Pod、Deployment 是同样的对象资源。在 Kubernetes 的 API Server 看来,它们都是存在于 etcd 中的一等资源。

同时,自定义资源和原生内置的资源一样,都可以用 kubectl 来去创建、查看,也享有 RBAC、安全功能。用户可以开发自定义控制器来感知或者操作自定义资源的变化。

下面我们来看一个简单的 CRD 实例。下图是一个 CRD 的定义。

1.png

首先最上面的 apiVersion 就是指 CRD 的一个 apiVersion 声明,声明它是一个 CRD 的需求或者说定义的 Schema。

kind 就是 CustomResourcesDefinition,指 CRD。name 是一个用户自定义资源中自己自定义的一个名字。一般我们建议使用“顶级域名.xxx.APIGroup”这样的格式,比如这里就是 foos.samplecontroller.k8s.io。

spec 用于指定该 CRD 的 group、version。比如在创建 Pod 或者 Deployment 时,它的 group 可能为 apps/v1 或者 apps/v1beta1 之类,这里我们也同样需要去定义 CRD 的 group。

  • 图中的 group 为 samplecontroller.k8s.io;
  • verison 为 v1alpha1;
  • names 指的是它的 kind 是什么,比如 Deployment 的 kind 就是 Deployment,Pod 的 kind 就是 Pod,这里的 kind 被定义为了 Foo;
  • plural 字段就是一个昵称,比如当一些字段或者一些资源的名字比较长时,可以用该字段自定义一些昵称来简化它的长度;
  • scope 字段表明该 CRD 是否被命名空间管理。比如 ClusterRoleBinding 就是 Cluster 级别的。再比如 Pod、Deployment 可以被创建到不同的命名空间里,那么它们的 scope 就是 Namespaced 的。这里的 CRD 就是 Namespaced 的。

下图就是上图所定义的 CRD 的一个实例。

2.png

  • 它的 apiVersion 就是我们刚才所定义的 samplecontroller.k8s.io/v1alpha1;
  • kind 就是 Foo;
  • metadata 的 name 就是我们这个例子的名字;
  • 这个实例中 spec 字段其实没有在 CRD 的 Schema 中定义,我们可以在 spec 中根据自己的需求来写一写,格式就是 key:value 这种格式,比如图中的 deploymentName: example-foo, replicas: 1。当然我们也可以去做一些检验或者状态资源去定义 spec 中到底包含什么。

带有校验的 CRD

我们来看一个包含校验的 CRD 定义:
3.png

可以看到这个定义更加复杂了,validation 之前的字段我们就不再赘述了,单独看校验这一段。

它首先是一个 openAPIV3Schema 的定义,spec 中则定义了有哪些资源,以 replicas 为例,这里将 replicas 定义为一个 integer 的资源,最小值为 1,最大值是 10。那么,当我们再次使用这个 CRD 的时候,如果我们给出的 replicas 不是 int 值,或者去写一个 -1,或者大于 10 的值,这个 CRD 对象就不会被提交到 API Server,API Server 会直接报错,告诉你不满足所定义的参数条件。

带有状态字段的 CRD

再来看一下带有状态字段的 CRD 定义。

4.png

我们在使用一些 Deployment 或 Pod 的时候,部署完成之后可能要去查看当前部署的状态、是否更新等等。这些都是通过增加状态字段来实现的。另外,Kubernetes 在 1.12 版本之前,还没有状态字段。

状态实际上是一个自定义资源的子资源,它的好处在于,对该字段的更新并不会触发 Deployment 或 Pod 的重新部署。我们知道对于某些 Deployment 和 Pod,只要修改了某些 spec,它就会重新创建一个新的 Deployment 或者 Pod 出来。但是状态资源并不会被重新创建,它只是用来回应当前 Pod 的整个状态。上图中的 CRD 声明中它的子资源的状态非常简单,就是一个 key:value 的格式。在 "{}" 里写什么,都是自定义的。

5.png

以一个 Deployment 的状态字段为例,它包含 availableReplicas、当前的状态(比如更新到第几个版本了、上一个版本是什么时候)等等这些信息。在用户自定义 CRD 的时候,也可以进行一些复杂的操作来告诉别的用户它当前的状态如何。

三、操作演示

下面我们来具体演示一下 CRD。

我们这里有两个资源:crd.yaml 和 example-foo.yaml。

6.png

首先创建一下这个 CRD 的 Schema 让我们的 Kubernetes Server 知道该 CRD 到底是什么样的。创建的方式非常简单,就是 "kuberctl create -f crd.yaml"。
7.png

通过 "kuberctl get crd" 可以看到刚才的 CRD 已经被创建成功了。

8.png

这个时候我们就可以去创建对应的资源 "kuberctl create -f example-foo.yaml":

9.png

下面来看一下它里面到底有什么东西 "kubectl get foo example-foo -o yaml" :

10.png

可以看到它是一个 Foo 的资源,spec 就是我们刚才所定义的,被选中的部分是基本上所有的 Kubernetes 的 metadata 资源中都会有的。因此,创建该资源和我们正常创建一个 Pod 的区别并不大,但是这个资源不是一个 Pod,也不是 Kubernetes 本身内置的资源,这就是一个我们自己创建的资源。从使用方式和使用体验上来说,和 Kubernetes 内置资源的使用几乎一致。

四、架构设计

控制器概览

只定义一个 CRD 其实没有什么作用,它只会被 API Server 简单地计入到 etcd 中。如何依据这个 CRD 定义的资源和 Schema 来做一些复杂的操作,则是由 Controller,也就是控制器来实现的。
 
Controller 其实是 Kubernetes 提供的一种可插拔式的方法来扩展或者控制声明式的 Kubernetes 资源。它是 Kubernetes 的大脑,负责大部分资源的控制操作。以 Deployment 为例,它就是通过 kube-controller-manager 来部署的。

比如说声明一个 Deployment 有 replicas、有 2 个 Pod,那么 kube-controller-manager 在观察 etcd 时接收到了该请求之后,就会去创建两个对应的 Pod 的副本,并且它会去实时地观察着这些 Pod 的状态,如果这些 Pod 发生变化了、回滚了、失败了、重启了等等,它都会去做一些对应的操作。

所以 Controller 才是控制整个 Kubernetes 资源最终表现出来的状态的大脑。

用户声明完成 CRD 之后,也需要创建一个控制器来完成对应的目标。比如之前的 Foo,它希望去创建一个 Deployment,replicas 为 1,这就需要我们创建一个控制器用于创建对应的 Deployment 才能真正实现 CRD 的功能。

控制器工作流程概览

11.png

这里以 kube-controller-manager 为例。

如上图所示,左侧是一个 Informer,它的机制就是通过去 watch kube-apiserver,而 kube-apiserver 会去监督所有 etcd 中资源的创建、更新与删除。Informer 主要有两个方法:一个是 ListFunc;一个是 WatchFunc。

  • ListFunc 就是像 "kuberctl get pods" 这类操作,把当前所有的资源都列出来;
  • WatchFunc 会和 apiserver 建立一个长链接,一旦有一个新的对象提交上去之后,apiserver 就会反向推送回来,告诉 Informer 有一个新的对象创建或者更新等操作。

Informer 接收到了对象的需求之后,就会调用对应的函数(比如图中的三个函数 AddFunc, UpdateFunc 以及 DeleteFunc),并将其按照 key 值的格式放到一个队列中去,key 值的命名规则就是 "namespace/name",name 就是对应的资源的名字。比如我们刚才所说的在 default 的 namespace 中创建一个 foo 类型的资源,那么它的 key 值就是 "default/example-foo"。Controller 从队列中拿到一个对象之后,就会去做相应的操作。

下图就是控制器的工作流程。

12.png

首先,通过 kube-apiserver 来推送事件,比如 Added, Updated, Deleted;然后进入到 Controller 的 ListAndWatch() 循环中;ListAndWatch 中有一个先入先出的队列,在操作的时候就将其 Pop() 出来;然后去找对应的 Handler。Handler 会将其交给对应的函数(比如 Add(), Update(), Delete())。

一个函数一般会有多个 Worker。多个 Worker 的意思是说比如同时有好几个对象进来,那么这个 Controller 可能会同时启动五个、十个这样的 Worker 来并行地执行,每个 Worker 可以处理不同的对象实例。

工作完成之后,即把对应的对象创建出来之后,就把这个 key 丢掉,代表已经处理完成。如果处理过程中有什么问题,就直接报错,打出一个事件来,再把这个 key 重新放回到队列中,下一个 Worker 就可以接收过来继续进行相同的处理。

五、本文总结

本文的主要内容就到此为止了,这里为大家简单总结一下:

  • CRD 是 Custom Resources Definition 的缩写,也就是用户自定义资源,用户可以使用这个功能扩展自己的Kubernetes 原生资源信息;
  • CRD 和普通的 Kubernetes 资源一样,都可以受 RBAC 权限控制,并且支持 status 状态字段;
  • CRD-controller 也就是 CRD 控制器,能够实现用户自行编写,并且解析 CRD 并把它变成用户期望的状态。

直播海报.png

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
存储 Kubernetes 监控
K8s集群实战:使用kubeadm和kuboard部署Kubernetes集群
总之,使用kubeadm和kuboard部署K8s集群就像回归童年一样,简单又有趣。不要忘记,技术是为人服务的,用K8s集群操控云端资源,我们不过是想在复杂的世界找寻简单。尽管部署过程可能遇到困难,但朝着简化复杂的目标,我们就能找到意义和乐趣。希望你也能利用这些工具,找到你的乐趣,满足你的需求。
1086 33
|
Kubernetes API 网络安全
当node节点kubectl 命令无法连接到 Kubernetes API 服务器
当Node节点上的 `kubectl`无法连接到Kubernetes API服务器时,可以通过以上步骤逐步排查和解决问题。首先确保网络连接正常,验证 `kubeconfig`文件配置正确,检查API服务器和Node节点的状态,最后排除防火墙或网络策略的干扰,并通过重启服务恢复正常连接。通过这些措施,可以有效解决与Kubernetes API服务器通信的常见问题,从而保障集群的正常运行。
992 17
|
机器学习/深度学习 设计模式 API
Python 高级编程与实战:构建 RESTful API
本文深入探讨了使用 Python 构建 RESTful API 的方法,涵盖 Flask、Django REST Framework 和 FastAPI 三个主流框架。通过实战项目示例,详细讲解了如何处理 GET、POST 请求,并返回相应数据。学习这些技术将帮助你掌握构建高效、可靠的 Web API。
|
机器学习/深度学习 开发框架 API
Python 高级编程与实战:深入理解 Web 开发与 API 设计
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧以及数据科学和机器学习。本文将深入探讨 Python 在 Web 开发和 API 设计中的应用,并通过实战项目帮助你掌握这些技术。
|
存储 运维 Kubernetes
容器数据保护:基于容器服务 Kubernetes 版(ACK)备份中心实现K8s存储卷一键备份与恢复
阿里云ACK备份中心提供一站式容器化业务灾备及迁移方案,减少数据丢失风险,确保业务稳定运行。
|
存储 Kubernetes Docker
Kubernetes(k8s)和Docker Compose本质区别
理解它们的区别和各自的优势,有助于选择合适的工具来满足特定的项目需求。
1667 19
|
Kubernetes 应用服务中间件 nginx
二进制安装Kubernetes(k8s)v1.32.0
本指南提供了一个详细的步骤,用于在Linux系统上通过二进制文件安装Kubernetes(k8s)v1.32.0,支持IPv4+IPv6双栈。具体步骤包括环境准备、系统配置、组件安装和配置等。
4813 11
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
本文源自2024云栖大会苏雅诗的演讲,探讨了K8s集群业务为何需要灾备及其重要性。文中强调了集群与业务高可用配置对稳定性的重要性,并指出人为误操作等风险,建议实施周期性和特定情况下的灾备措施。针对容器化业务,提出了灾备的新特性与需求,包括工作负载为核心、云资源信息的备份,以及有状态应用的数据保护。介绍了ACK推出的备份中心解决方案,支持命名空间、标签、资源类型等维度的备份,并具备存储卷数据保护功能,能够满足GitOps流程企业的特定需求。此外,还详细描述了备份中心的使用流程、控制台展示、灾备难点及解决方案等内容,展示了备份中心如何有效应对K8s集群资源和存储卷数据的灾备挑战。
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
JSON Kubernetes API
k8s技术预研14--kubernetes API详解
1、kubernetes API概述 Kubernetes API是集群系统中的重要组成部分,Kubernetes中各种资源(对象)的数据通过该API接口被提交到后端的持久化存储(etcd)中,Kubernetes集群中的各部件之间通过该API接口实现解耦合,同时Kubernetes集群中一个重要且便捷的管理工具kubectl也是通过访问该API接口实现其强大的管理功能的。
4623 0

相关产品

  • 容器服务Kubernetes版
  • 推荐镜像

    更多