Kubernetes CRD 系列(二):Api Server 和 GVK(R)

概述

在上一篇中,我介绍了如何创建一个 CRD 以及通过这个 CRD 来创建 CR。这些关于 CR 的操作都是通过 kubectl 命令来完成的,但是,事实上,到目前位置,kubectl 是如何操作这些 CR 的我们还是不清楚。

对于后面还有很多内容都是需要代码和 CR 关联的,所以,我觉得在开始一些代码的工作之前,有必要先对 Kubernetes 的 Resource 机制进行一些介绍。在 Kubernetes 入门第二篇 中,我介绍了 API Server 是用于资源操作的组件,事实上,之前我是说可以认为是作为 etcd 的一个接口来理解,但是,实际上 API Server 完成的工作不仅仅这么简单,从上一篇的这张图可以看到:

API Server 完成了相当多的事情,但是,就目前而言,这些事情基本上都还不需要关心,这一篇要关心的就是,到底 kubectl 是如何操作 API Server 中的资源的。

GVK

从上一篇中的 CRD 定义中,可以发现在 Kubernetes 中要想完成一个 CRD,需要指定 group/kind 和 version,这个在 Kubernetes 的 API Server 中简称为 GVK。GVK 是定位一种类型的方式,例如,daemonsets 就是 Kubernetes 中的一种资源,当我们跟 Kubernetes 说我想要创建一个 daemonsets 的时候,kubectl 是如何知道该怎么向 API Server 发送呢?是所有的不同资源都发向同一个 URL,还是每种资源都是不同的?

这就得看回我定义 daemonsets 的描述文件了:

[root@liqiang.io]# head -4 00-sample-daemonsets.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter

这里我就声明了 apiVersion 是 apps/v1,其实就是隐含了 Group 是 apps,Version 是 v1,Kind 就是定义的 DaemonSet,而 kubectl 接收到这个声明之后,就可以根据这个声明去调用 API Server 对应的 URL 去获取信息,例如这个就是 /api/apps/v1/daemonset(kubetl 怎么知道 DaemonSet 对应的就是 daemonset?第一篇有说到)。

可能到这里你已经猜到了,Kubernetes 组织资源的方式是以 REST 的 URI 的形式来的,而组织的路径就是:

额,不对,不是说是 G(roup)V(ersion)K(ind) 的吗,怎么这里又是 G(roup)V(ersion)R(ource) ?嘿,是的,这就是 API Server 中的第二个概念,GVR。

GVR

其实,理解了 GVK 之后再理解 GVR 就很容易了,这就是面向对象编程里面的类和对象的概念是一样的:

KubernetesOOP
KindClass
ResourceObject

好理解吧,Kind 其实就是一个类,用于描述对象的;而 Resource 就是具体的 Kind,可以理解成类已经实例化成对象了。

REST Mapping

当我们要定义一个 GVR 的时候,那么怎么知道这个 GVR 是属于哪个 GVK 的呢?也就是前面说的,kubectl 是如何从 YAML 描述文件中知道该请求的是哪个 GVR URL?这就是 REST Mapping 的功能,REST Mapping 可以指定一个 GVR(例如 daemonset 的这个例子),然后它返回对应的 GVK 以及支持的操作等。

在代码中,其实就对应于这个接口:

这样,就把 GVK 和 GVR 联系起来了。

API Server

既然,前面都说了,API Server 可以通过 URI 的形式访问到资源,那么这里我就来实战一下,一般来说,如果是正常安装的 Kubernetes 集群,那么肯定会有 http 证书以及认证证书,这会让我的尝试很麻烦,所以,为了去掉这重麻烦,我会通过 kubectl proxy 来代理一个本地的 API Server 端口,这样就可以绕过认证了,直接可以以 http 的形式进行:

[root@liqiang.io]# kubectl proxy --port=9090
Starting to serve on 127.0.0.1:9090

然后直接访问 API Server:

[root@liqiang.io]# GET http://127.0.0.1:9090/apis/apps/v1/daemonsets/
{
  "kind": "DaemonSetList",
  "apiVersion": "apps/v1",
  "metadata": {
    "selfLink": "/apis/apps/v1/daemonsets/",
    "resourceVersion": "209282"
  },
  "items": [
    {
      "metadata": {
        "name": "svclb-traefik",
        "namespace": "kube-system",
        "selfLink": "/apis/apps/v1/namespaces/kube-system/daemonsets/svclb-traefik",
        "uid": "bd42f48c-42de-4df6-96bd-15e56bdfaec7",
        "resourceVersion": "176921",
        "generation": 2,
... ...

因为内容太多,就不一一展示了。

核心资源

如果想看系统支持哪些 GVK,那么可以通过 kubectl 的命令查看:

[root@liqiang.io]# k api-resources
NAMESHORTNAMESAPIGROUPNAMESPACEDKIND
podspotruePod
servicessvctrueService
mutatingwebhookconfigurationsadmissionregistration.k8s.iofalseMutatingWebhookConfiguration
validatingwebhookconfigurationsadmissionregistration.k8s.iofalseValidatingWebhookConfiguration
customresourcedefinitionscrd,crdsapiextensions.k8s.iofalseCustomResourceDefinition
apiservicesapiregistration.k8s.iofalseAPIService
controllerrevisionsappstrueControllerRevision
daemonsetsdsappstrueDaemonSet

这里可能你会发现一些特别的地方,就是对于 Pod 和 Service,它的 API GROUP 居然是空的,这又是什么意思?这其实就是 Kubernetes 核心资源的含义,也就是所谓的 Kubernetes 中的基础资源(Kubernetes Resource),他们不需要 Group,只有 Version 和 Kind,其实,我认为这是历史原因导致的,在 Kubernetes 的开始之初还不支持自定义类型的时候就没考虑过 Group。

Ref

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值