2024-04-03 Kubernetes API

简介 #

kube-apiserver 组件是 k8s 中非常重要的组件,每个组件都只能和 kube-apiserver 进行通信,kube-apiserver 提供所有的 API。 #

资源与 API #

在 k8s 中,一般都说某某资源,并不说接口。比如 Deployment,Service 等资源,这些资源就是 k8s api 操作的实体,最终这些资源都会存储到 etcd 中,其实最终就是对 etcd 中的这些资源做 CRUD。 #

例子 #

当我们使用 kubectl get deployment查看集群 default 命令空间的 deployment时,其实 kubectl 最终是将命令语言转化为 API 发送给 kube-apiserver,然后将 kube-apiserver 返回的数据再转成特定格式打印出来。 #
$ kubectl get deployment
--> https://apiserver.cluster.local:6443/apis/apps/v1/namespaces/default/deployments
# apiserver.cluster.local:6443 这个是 kube-apiserver 的访问 url
# apis: 表示下面有多组 api
# apps: 表示 api 组
# v1: 表示 api version
# default: 表示命名空间
# deployments: 表示操作的具体资源类型
下面详细看看一个 url 的设计 #

API 组 #

k8s 将每一个 api 都设置组和版本即 groupVersion。 #
例如:/apis/apps/v1/deployment,apis 表示有多组 api,apps 是 group,v1 是 version #
但是 /api/v1 这一组 API 例外,因为在 k8s 刚开发时,并没有预料到后面会发展这么多的 API,当时并没有设置 group,现在都认为 /api/v1 都是核心组,可以这么理解 /api/core/v1,这样就和目前所有 API 结构对应上了。 #
例如:/api/v1/service,api 表示只有一组 api 及核心组,v1 是 version #

API 版本 #

每一个 API 除了有 group,还需要拥有 version 属性,因为每一个 API 都需要经历多次打磨才能稳定,k8s 是这样定义 API version 的。 #
  • • Alpha 级别,例如 v1alpha1 默认情况下是被禁用的,可以随时删除对功能的支持,所以要慎用 #
  • • Beta 级别,例如 v2beta1 默认情况下是启用的,表示代码已经经过了很好的测试,但是对象的语义可能会在随后的版本中以不兼容的方式更改 #
  • • 稳定级别,比如 v1 表示已经是稳定版本了,也会出现在后续的很多版本中。 #

image-20240319151739640


举例 #

可以用 kubectl get - - raw / 命令查看 k8s 集群中有哪些 API #
$ kubectl get --raw /
{
  "paths": [
    "/.well-known/openid-configuration",
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1",
    "/apis/apiextensions.k8s.io",
    "/apis/apiextensions.k8s.io/v1",
    "/apis/apiregistration.k8s.io",
    "/apis/apiregistration.k8s.io/v1",
    "/apis/apps",
    "/apis/apps/v1",
    "/apis/authentication.k8s.io",
    "/apis/authentication.k8s.io/v1",
    "/apis/authorization.k8s.io",
    "/apis/authorization.k8s.io/v1",
    "/apis/autoscaling",
    "/apis/autoscaling/v1",
    "/apis/autoscaling/v2beta1",
    "/apis/autoscaling/v2beta2",
    "/apis/batch",
    "/apis/batch/v1",
    "/apis/batch/v1beta1",
    "/apis/builder.moss.iflytek.com",
    "/apis/builder.moss.iflytek.com/v1",
    "/apis/certificates.k8s.io",
    "/apis/certificates.k8s.io/v1",
    "/apis/cluster.moss.iflytek.com",
    "/apis/cluster.moss.iflytek.com/v1",
    "/apis/coordination.k8s.io",
    "/apis/coordination.k8s.io/v1",
    "/apis/crd.projectcalico.org",
    "/apis/crd.projectcalico.org/v1",
    "/apis/discovery.k8s.io",
    "/apis/discovery.k8s.io/v1",
    "/apis/discovery.k8s.io/v1beta1",
    "/apis/events.k8s.io",
    "/apis/events.k8s.io/v1",
    "/apis/events.k8s.io/v1beta1",
    "/apis/flowcontrol.apiserver.k8s.io",
    "/apis/flowcontrol.apiserver.k8s.io/v1beta1",
    "/apis/metrics.k8s.io",
    "/apis/metrics.k8s.io/v1beta1",
    "/apis/networking.k8s.io",
    "/apis/networking.k8s.io/v1",
    "/apis/node.k8s.io",
    "/apis/node.k8s.io/v1",
    "/apis/node.k8s.io/v1beta1",
    "/apis/openebs.io",
    "/apis/openebs.io/v1alpha1",
    "/apis/operator.tigera.io",
    "/apis/operator.tigera.io/v1",
    "/apis/policy",
    "/apis/policy/v1",
    "/apis/policy/v1beta1",
    "/apis/projectcalico.org",
    "/apis/projectcalico.org/v3",
    "/apis/rbac.authorization.k8s.io",
    "/apis/rbac.authorization.k8s.io/v1",
    "/apis/scheduling.k8s.io",
    "/apis/scheduling.k8s.io/v1",
    "/apis/storage.k8s.io",
    "/apis/storage.k8s.io/v1",
    "/apis/storage.k8s.io/v1beta1",
    "/healthz",
    "/healthz/autoregister-completion",
    "/healthz/etcd",
    "/healthz/log",
    "/healthz/ping",
    "/healthz/poststarthook/aggregator-reload-proxy-client-cert",
    "/healthz/poststarthook/apiservice-openapi-controller",
    "/healthz/poststarthook/apiservice-registration-controller",
    "/healthz/poststarthook/apiservice-status-available-controller",
    "/healthz/poststarthook/bootstrap-controller",
    "/healthz/poststarthook/crd-informer-synced",
    "/healthz/poststarthook/generic-apiserver-start-informers",
    "/healthz/poststarthook/kube-apiserver-autoregistration",
    "/healthz/poststarthook/priority-and-fairness-config-consumer",
    "/healthz/poststarthook/priority-and-fairness-config-producer",
    "/healthz/poststarthook/priority-and-fairness-filter",
    "/healthz/poststarthook/rbac/bootstrap-roles",
    "/healthz/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/healthz/poststarthook/start-apiextensions-controllers",
    "/healthz/poststarthook/start-apiextensions-informers",
    "/healthz/poststarthook/start-cluster-authentication-info-controller",
    "/healthz/poststarthook/start-kube-aggregator-informers",
    "/healthz/poststarthook/start-kube-apiserver-admission-initializer",
    "/livez",
    "/livez/autoregister-completion",
    "/livez/etcd",
    "/livez/log",
    "/livez/ping",
    "/livez/poststarthook/aggregator-reload-proxy-client-cert",
    "/livez/poststarthook/apiservice-openapi-controller",
    "/livez/poststarthook/apiservice-registration-controller",
    "/livez/poststarthook/apiservice-status-available-controller",
    "/livez/poststarthook/bootstrap-controller",
    "/livez/poststarthook/crd-informer-synced",
    "/livez/poststarthook/generic-apiserver-start-informers",
    "/livez/poststarthook/kube-apiserver-autoregistration",
    "/livez/poststarthook/priority-and-fairness-config-consumer",
    "/livez/poststarthook/priority-and-fairness-config-producer",
    "/livez/poststarthook/priority-and-fairness-filter",
    "/livez/poststarthook/rbac/bootstrap-roles",
    "/livez/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/livez/poststarthook/start-apiextensions-controllers",
    "/livez/poststarthook/start-apiextensions-informers",
    "/livez/poststarthook/start-cluster-authentication-info-controller",
    "/livez/poststarthook/start-kube-aggregator-informers",
    "/livez/poststarthook/start-kube-apiserver-admission-initializer",
    "/logs",
    "/metrics",
    "/openapi/v2",
    "/openid/v1/jwks",
    "/readyz",
    "/readyz/autoregister-completion",
    "/readyz/etcd",
    "/readyz/informer-sync",
    "/readyz/log",
    "/readyz/ping",
    "/readyz/poststarthook/aggregator-reload-proxy-client-cert",
    "/readyz/poststarthook/apiservice-openapi-controller",
    "/readyz/poststarthook/apiservice-registration-controller",
    "/readyz/poststarthook/apiservice-status-available-controller",
    "/readyz/poststarthook/bootstrap-controller",
    "/readyz/poststarthook/crd-informer-synced",
    "/readyz/poststarthook/generic-apiserver-start-informers",
    "/readyz/poststarthook/kube-apiserver-autoregistration",
    "/readyz/poststarthook/priority-and-fairness-config-consumer",
    "/readyz/poststarthook/priority-and-fairness-config-producer",
    "/readyz/poststarthook/priority-and-fairness-filter",
    "/readyz/poststarthook/rbac/bootstrap-roles",
    "/readyz/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/readyz/poststarthook/start-apiextensions-controllers",
    "/readyz/poststarthook/start-apiextensions-informers",
    "/readyz/poststarthook/start-cluster-authentication-info-controller",
    "/readyz/poststarthook/start-kube-aggregator-informers",
    "/readyz/poststarthook/start-kube-apiserver-admission-initializer",
    "/readyz/shutdown",
    "/version"
  ]
}
从上图中我们也可以看出 Kubernetes 的 API 对象的组织方式,在顶层,我们可以看到有一个核心组(由于历史原因,开发过程不可能完全预示以后的api这么丰富,当时把所有的资源对象 api 全部放在 /api/v1 下面。是 /api/v1 下的所有内容而不是在 /apis/core/v1 下面)和命名组(路径 /apis/$NAME/$VERSION)和系统范围内的实体,比如 /metrics。所以例如,pod, serivce 等资源的 api 不存在 group #

API 示例 #

namespaced resources

所谓的 namespaced resources , 就是这个 resource 是从属于某个 namespace 的, 也就是说它不是 cluster-scoped 的资源. 比如 pod, deployment, service 都属于 namespaced resource. 那么我们看一下如何请求一个 namespaced resources. #
http://localhost:8080/api/v1/namespaces/default/pods/test-pod
可以看出, 该 restful api 的组织形式是: #
这里 api version 如果是 v1 的话,表示这是一个很稳定的版本了, 以后不会有大的修改,并且当前版本所支持的所有特性以后都会兼容. 而如果版本号是 v1alpha1, v1beta1 之类的,则不保证其稳定性. #

non-namespaced resources

http://localhost:8080/apis/rbac.authorization.k8s.io/v1/clusterroles/test-clusterrole
这里可以观察到它 clusterrole 与 pod 不同, apis 表示这是一个非核心 api,rbac.authorization.k8s.io 指代的是 api-group, 另外它没有 namespaces 字段, 其他与 namespaced resources 类似.不再赘述. #

non-resource url

这类资源和 pod, clusterrole 都不同. 例如 #
http://localhost:8080/healthz/etcd
这就是用来确认 etcd 服务是不是健康的.它不属于任何 namespace ,也不属于任何 api 版本. #

custom api

当开发 operator 或者聚合 api 时,都会自定义 API,例如: #
http://localhost:8080/apis/custom.io/v1/test
custom.io[1] 表示自定义 group #
test 为自定义资源 #
k8s 的 REST API 的设计结构为: #
api/apis /  [api-group]   / api-version /  namespaces / namespace-name / resource-kind / resource-name

示例:

apis    /   rbac.authorization.k8s.io /  v1   /  namespaces / default      /  roles            /  test-role

总结 #

弄清楚 K8s 的 API 结构,对看源码以及后面开发自定义 API 都很有帮助。 #