Vis/skjul meny Yingchi Blog

理解 Kubernetes 的 Resource 设计概念

Kubernetes 是一个完全以资源为中心的容器编排平台,这一点从 kube-apiserver 对外暴露的 REST API 设计上其实就能很明显地感受到。Kubernetes 的生态系统围绕着诸多组件资源的控制维护而运作,因此也可以认为它本质上是一个「资源控制系统」

Group / Version / Resource

针对于资源这一概念,如果在一个庞大而复杂的容器编排平台上仅设计这么一个简单的「资源」语义显然是有点单薄,或者说表达力过于欠缺,因此对于资源这么一个概念,在 Kubernetes 上又进行了分组和版本话,于是就有了我们平时运维与开发中常见到的一些术语:Group / Version / Resource / Kind,分别代表的意义:资源组 / 资源版本 / 资源 / 资源种类

他们之间的关系是这样的:

  • Kubernetes 系统支持多个 Group(资源组);
  • 每个 Group 支持多个资源版本(Version);
  • 每个资源版本又支持多种资源(Resource),部分资源还拥有自己的子资源;
  • Kind 与 Resource 属于同一级概念,Kind 用于描述 Resource 的种类;

定位一个资源的完整形式如下:

<GROUP>/<VERSION>/<RESOURCE>[/<SUBSOURCE>]

以 Deployment 为例:apps/v1/deployments/status

在 Kubernetes 中还有一种描述资源的概念叫做「资源对象」(Resource Object),其描述形式为:

<GROUP>/<VERSION>, Kind=<RESOURCE_NAME>

以 Deployment 为例:apps/v1, Kind=Deployment

资源概念的一些基本特点:

  • 每个资源都有一定数量的操作方法,称为 Verbs,如 create / delete / update / get / list / watch …(8种);
  • 每个资源 Version 至少有两种,包括一个面向用户请求的外部版本,还有 api-server 内部使用的内部版本;
  • Kubernetes 资源整体上分为内置资源以及 Custom Resources 自定义资源,其中 CR 通过 CRD 自定义资源定义实现;

Group

资源组,Kubenetes API Server 也称为 APIGroup,其有如下特点:

  • 资源组的划分依据是资源的功能
  • 支持不同资源组中拥有不同资源版本,从而方便组内资源迭代升级;
  • 支持不同 Group 内有同名 Kind 的 Resource;
  • 支持通过 CRD 扩展自定义资源;
  • 使用 kubectl 命令进行资源交互时,可以不指定 Group;

有组名 Group 及无组名 Group

包含拥有组名的 Group 和没有组名的 Core Groups(如 v1/pods),其 HTTP 请求方式也有差别:

有组名 Group 资源: .../apis/<GROUP>/<VERSION>/<RESOURCE>
无组名 Group 资源: .../api/<VERSION>/<RESOURCE>

Version

Kubernetes 的资源版本 Version 采用的是语义化的版本号,版本号以 v 开头,版本号后面跟着版本的测试阶段(Alpha -> Beta -> Stable),例如:v1alpha1、v1beta1、v2stable1

版本的各个测试阶段情况如下:

  • Alpha 阶段:内部测试版本,存在很多的缺陷和漏洞,版本极其不稳定,官方随时可能会放弃支持该版本,仅仅用于开发者的测试使用,Alpha 版本中的功能默认情况下会被禁用。常见命名方式如 v1alpha1;
  • Beta 阶段:相对稳定版本,经过了官方和社区的测试,版本迭代时会有些许改变,但不会像 Alpha 版本一样不稳定,Beta 阶段下的功能默认是开启的。常见命名方式如 v2beta1;
  • Stable 阶段:正式发布版本,功能稳定版本,基本形成了产品,默认情况下所有功能全部开启,命名方式一般不加 stable,直接是 v1、v2 这种;

Resource

Resource 是 Kubernetes 中的核心概念,Kubernetes 的本质就是管理、调度及维护其下各种 Resources。

  • Resource 实例化后称为一个 Resource Object;
  • Kubernetes 中所有的 Resource Object 都称为 Entity
  • 可以通过 Kubenetes API Server 去操作 Resource Object;

Kubernetes 目前将 Entity 分为两大类:

  • Persistent Entity:即 Resource Object 创建后会持久存在,绝大部分都是 PE,如 Deployment / Service;
  • Ephemeral Entity: 短暂实体,Resource Object 创建后不稳定,出现故障/调度失败后不再重建,如 Pod;

资源操作方法

虽然在 Etcd 层面而言,对于资源的操作最终也只转换为增删改查这些基本操作,但是抽象到资源层面,Kubernetes 赋予了资源比较多的操作方法,之前提到过,称之为「Verbs」,分别是 create / delete / deletecollection / patch / update / get / list / watch,我们仍然可以把它们归到增删改查四大类:

  • 增:
    • create:Resource Object 创建
  • 删:
    • delete:单个 Resource Object 删除
    • deletecollection:多个 Resource Objects 删除
  • 改:
    • patch:Resource Object 局部字段更新
    • update:Resource Object 整体更新
  • 查:
    • get:单个 Resource Object 获取
    • list:多个 Resource Objects 获取
    • watch:Resource Objects 监控

Resource 与 Namespace

Kubernetes 同样支持 Namespace(命名空间)的概念,可以解决 Resource Object 过多时带来的管理复杂性问题。Namespace 有如下几个特点;

  • 每个 Namespace 可以视作「虚拟集群」,即不同的 Namespace 间可以实现隔离;
  • 不同的 Namespace 间可以实现跨 Namespace 的通信;
  • 可以对不同的用户配置对不同 Namespace 的访问权限;

因此我们知道,Namespace 即可实现资源的隔离,同时有能满足跨 Namespace 的通信,是一个非常灵活的概念,在很多场景下,比如多租户的实现、生产/测试/开发环境的隔离等场景中都会起到重要作用。

Resource Manifest File 资源对象描述文件

无论是 Kubernetes 的内置资源还是通过 CRD 定义的 Custom Resource,都是通过资源对象描述文件进行 Resource Object 的创建。

Kubernetes 中 Manifest File 可以通过两种格式来定义:YAMLJSON,无论格式如何,Manifest File 各个字段都是固定的意义:

  • apiVersion:注意这里的 APIVersion 其实指的是 APIGroup/APIVersion,如 Deployment 可以写为 apps/v1,而对于 Pod,因为它属于 Core Group,即无名 Group,因此省略 Group,写为 v1 即可;
  • kind:Resource Object 的种类;
  • metadata:Resource Object 的元数据信息,常用的包括 name / namespace / labels;
  • spec:Resource Object 的期望状态(Desired Status)
  • status:Resource Object 的实际状态(Actual Status)

参考

  • 《Kubernetes 源码剖析》郑东旭