• Kubernetes API 基础


    APIServer#

    在kubernetes架构概念层面上,Kubernetes由一些具有不同角色的服务节点组成。而master的控制平面由 Apiserver Controller-managerScheduler 组成。

    Apiserver 从概念上理解可以分为 apiobject 的集合,api 可以理解为,处理读写请求来修改相应 object 的组件;而 object 可以表示为 kubernetes 对象,如 PodDeployment 等 。

    基于声明式的API#

    在命令式 API 中,会直接发送要执行的命令,例如:运行停止 等命令。在声明式API 中,将声明希望系统执行的操作,系统将不断将自身状态朝希望状态改变。

    为什么使用声明式#

    在分布式系统中,任何组件随时都可能发生故障,当组件故障恢复时,需要明白自己需要做什么。在使用命令式时,出现故障的组件可能在异常时错过调用,并且在恢复时需要其他外部组件进行干预。而声明式仅需要在恢复时确定当前状态以确定他需要做什么。

    External APIs#

    在kubernetes中,控制平面是透明的,及没有internal APIs。这就意味着Kubernetes组件间使用相同的API交互。这里通过一个例子来说明外部APIs与声明式的关系。

    例如,创建一个Pod对象,Scheduler 会监听 API来完成创建,创建完成后,调度程序不会命令被分配节点启动Pod。而在kubelet端,发现pod具有与自己相同的一些信息时,会监听pod状态。如改变kubelet则修改状态,如果删除掉Pod(对象资源不存在与API中),那么kubelet则将终止他。

    为什么不使用Internal API#

    使用External API可以使kubernetes组件都使用相同的API,使得kubernetes具有可扩展性和可组合性。对于kubernetes中任何默认组件,如不足满足需求时,都可以更换为使用相同API的组件。

    另外,外部API还可轻松的使用公共API来扩展kubernetes的功能

    API资源#

    从广义上讲,kubernetes对象可以用任何数据结构来表示,如:资源实例、配置(审计策略)或持久化实体(Pod);在使用中,常见到的就是对应YAML的资源清单。转换出来就是RESTful地址,那么应该怎么理解这个呢?即,对资源的动作(操作)如图所示。但如果需要了解Kubernetes API需要掌握一些概念才可继续。

    Group#

    出于对kubernetes扩展性的原因,将资源类型分为了API组进行独立管理,可以通过 kubectl api-resources查看。在代码部分为 vendor/k8s.io/api

    也可以通过 kubectl xxx -v 6 来查看 kubectl 命令进行了那些API调用

    $ kubectl get pods -v 6
    I0513 21:54:33.250752   38661 round_trippers.go:444] GET http://localhost:8080/api?timeout=32s 200 OK in 1 milliseconds
    I0513 21:54:33.293831   38661 round_trippers.go:444] GET http://localhost:8080/apis?timeout=32s 200 OK in 0 milliseconds
    I0513 21:54:33.299741   38661 round_trippers.go:444] GET http://localhost:8080/apis/discovery.k8s.io/v1beta1?timeout=32s 200 OK in 3 milliseconds
    I0513 21:54:33.301097   38661 round_trippers.go:444] GET http://localhost:8080/apis/autoscaling/v2beta1?timeout=32s 200 OK in 4 milliseconds
    I0513 21:54:33.301128   38661 round_trippers.go:444] GET http://localhost:8080/apis/authorization.k8s.io/v1beta1?timeout=32s 200 OK in 3 milliseconds
    I0513 21:54:33.301222   38661 round_trippers.go:444] GET http://localhost:8080/apis/rbac.authorization.k8s.io/v1beta1?timeout=32s 200 OK in 1 milliseconds
    I0513 21:54:33.301238   38661 round_trippers.go:444] GET http://localhost:8080/apis/authentication.k8s.io/v1beta1?timeout=32s 200 OK in 4 milliseconds
    I0513 21:54:33.301280   38661 round_trippers.go:444] GET http://localhost:8080/apis/certificates.k8s.io/v1beta1?timeout=32s 200 OK in 4 milliseconds
    ....
    No resources found in default namespace.
    

    Kind#

    kubectl api-resources 中可以看到,有Kind字段,大部分人通常会盲目的 kubectl apply ,这导致了,很多人以为 kind 实际上为资源名称,PodDeployment 等。

    根据 api-conventions.md 的说明,Kind 是对象模式,包含三种类型:

    • Object,代表系统中持久化数据资源,如,Service, Namespace, Pod
    • List,是一个或多个资源的集合,通常以List结尾,如 DeploymentList
    • 对Object的操作和和非持久化实体,如,当发生错误时会返回“status”类型,并不会持久化该数据。

    Object#

    对象是Kubernetes中持久化的实体,也就是保存在etcd中的数据;如:Replicaset , Configmap 等。这个对象代表的了集群期望状态和实际状态。

    例如:创建了Pod,kubernetes集群会调整状态,直到相应的容器在运行

    Kubernetes资源又代表了对象,对象必须定义一些字段

    • 所有对象必须具有以下字段:
      • Kind
      • apiVersion
    • metadata
    • spec:期望的状态
    • status:实际的状态

    前面讲到的 kubectl api-resources 展示的列表不能完整称为API资源,而是已知类型的kubernetes对象,要对展示这个API对象,需要了解其完整的周期。以 kubectl get --raw / 可以递归查询每个路径。

    kubectl get --raw /
    {
      "paths": [
        "/api",
        "/api/v1",
        "/apis",
        "/apis/",
        "/apis/admissionregistration.k8s.io",
        "/apis/admissionregistration.k8s.io/v1",
        "/apis/admissionregistration.k8s.io/v1beta1",
        "/apis/apiextensions.k8s.io",
        "/apis/apiextensions.k8s.io/v1",
    ...
    

    对于一个Pod来说,其查询路径就为 /api/v1/namespaces/kube-system/pods/coredns-f9bbb4898-7zkbf

    kubectl get --raw /api/v1/namespaces/kube-system/pods/coredns-f9bbb4898-7zkbf|jq
    	
    kind: Pod
    apiVersion: v1
    metadata: {}
    spec:{}
    status: {}
    

    但有一些资源对象也并非这种结构,如 configMap ,因其只是存储的数据,所以没有 specstatus

    kubectl get --raw /api/v1/namespaces/kube-system/configmaps/coredns|jq
    
    kind
    apiVersion
    metadata
    data
    

    API组成#

    一个API的组成为 一个 API 组Group , 一个版本 Version , 和一个资源 Resource ; 简称为 GVR

    转换为实际的http路径为:

    • /api/{version}/namespaces/{namespace_name}/resourcesPlural/{actual_resources_name}
    • /api/v1/namespaces/default/pods/pods123

    而GVR中的R代表的是RESTful中的资源,转换为Kubernetes中资源应为 Kind,简称为 GVK,K在URI中表示在:

    • /apis/{GROUP}/{VERSION}/namespaces/{namespace}/{KIND}

    请求和处理#

    这里讨论API请求和处理,API的一些数据结构位于 k8s.io/api ,并处理集群内部与外部的请求,而Apiserver 位于 k8s.io/apiserver/pkg/server 提供了http服务。

    那么,当 HTTP 请求到达 Kubernetes API 时,实际上会发生什么?

    • 首先HTTP请求在 DefaultBuildHandlerChain (可以参考k8s.io/apiserver/pkg/server/config.go)中注册filter chain,过滤器允许并将相应的信息附加至 ctx.RequestInfo; 如身份验证的相应
    • k8s.io/apiserver/pkg/server/mux 将其分配到对应的应用
    • k8s.io/apiserver/pkg/server/routes 定义了REST与对应应用相关联
    • k8s.io/apiserver/pkg/endpoints/groupversion.go.InstallREST() 接收上下文,从存储中传递请求的对象。

  • 相关阅读:
    linux内核基本知识一
    网易数帆陈谔:低代码平台,应对企业应用开发复杂性的一剂良方
    JSON数据 保存到指定文件,解析成指定格式 FileUtils
    设计模式之观察者模式
    epoll 定时器
    SpringCloudAlibaba系列微服务搭建笔记二-RestTemplate+Ribbon
    linux主机信息
    淘宝(tmall)店铺旗舰店商品数据分析接口代码教程
    【前端源码解析】数据响应式原理
    利用AI快速跨过新手区:用DevChat编写Python程序-CSV导入TDengine
  • 原文地址:https://www.cnblogs.com/Cylon/p/16277723.html