API Groups
As we've mentioned several times, any interaction with the server is done through an API that is managed by kube-apiserver.
To make studying easier and not have to keep passing certificates directly every time we make a direct request to kube-apiserver using REST, let's create a proxy.
The command starts a local proxy server on port 6443 that allows access to the Kubernetes API Server. It could be any port, I used the same 6443 just to know it's the server port. This way we can see everything through the browser.
kubectl proxy --port=6443 &
[1] 1735417
➜ files git:(main) ✗ Starting to serve on 127.0.0.1:6443
# If you don't want to pass the port just run the command below and it will use port 8001
kubectl proxy
kubectl proxy is not the same as kube-proxy. Kube-proxy is a Kubernetes component that manages services. In this case it's just a command that makes life easier.

Let's look at what we have here.
curl http://127.0.0.1:6443
{
"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/v2",
"/apis/batch",
"/apis/batch/v1",
"/apis/certificates.k8s.io",
"/apis/certificates.k8s.io/v1",
"/apis/coordination.k8s.io",
"/apis/coordination.k8s.io/v1",
"/apis/discovery.k8s.io",
"/apis/discovery.k8s.io/v1",
"/apis/events.k8s.io",
"/apis/events.k8s.io/v1",
"/apis/flowcontrol.apiserver.k8s.io",
"/apis/flowcontrol.apiserver.k8s.io/v1",
"/apis/flowcontrol.apiserver.k8s.io/v1beta3",
"/apis/networking.k8s.io",
"/apis/networking.k8s.io/v1",
"/apis/node.k8s.io",
"/apis/node.k8s.io/v1",
"/apis/policy",
"/apis/policy/v1",
"/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",
"/healthz",
"/healthz/autoregister-completion",
"/healthz/etcd",
"/healthz/log",
"/healthz/ping",
"/healthz/poststarthook/aggregator-reload-proxy-client-cert",
"/healthz/poststarthook/apiservice-discovery-controller",
"/healthz/poststarthook/apiservice-openapi-controller",
"/healthz/poststarthook/apiservice-openapiv3-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",
"/healthz/poststarthook/start-kube-apiserver-identity-lease-controller",
"/healthz/poststarthook/start-kube-apiserver-identity-lease-garbage-collector",
"/healthz/poststarthook/start-legacy-token-tracking-controller",
"/healthz/poststarthook/start-service-ip-repair-controllers",
"/healthz/poststarthook/start-system-namespaces-controller",
"/healthz/poststarthook/storage-object-count-tracker-hook",
"/livez",
"/livez/autoregister-completion",
"/livez/etcd",
"/livez/log",
"/livez/ping",
"/livez/poststarthook/aggregator-reload-proxy-client-cert",
"/livez/poststarthook/apiservice-discovery-controller",
"/livez/poststarthook/apiservice-openapi-controller",
"/livez/poststarthook/apiservice-openapiv3-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",
"/livez/poststarthook/start-kube-apiserver-identity-lease-controller",
"/livez/poststarthook/start-kube-apiserver-identity-lease-garbage-collector",
"/livez/poststarthook/start-legacy-token-tracking-controller",
"/livez/poststarthook/start-service-ip-repair-controllers",
"/livez/poststarthook/start-system-namespaces-controller",
"/livez/poststarthook/storage-object-count-tracker-hook",
"/logs",
"/metrics",
"/metrics/slis",
"/openapi/v2",
"/openapi/v3",
"/openapi/v3/",
"/openid/v1/jwks",
"/readyz",
"/readyz/autoregister-completion",
"/readyz/etcd",
"/readyz/etcd-readiness",
"/readyz/informer-sync",
"/readyz/log",
"/readyz/ping",
"/readyz/poststarthook/aggregator-reload-proxy-client-cert",
"/readyz/poststarthook/apiservice-discovery-controller",
"/readyz/poststarthook/apiservice-openapi-controller",
"/readyz/poststarthook/apiservice-openapiv3-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/poststarthook/start-kube-apiserver-identity-lease-controller",
"/readyz/poststarthook/start-kube-apiserver-identity-lease-garbage-collector",
"/readyz/poststarthook/start-legacy-token-tracking-controller",
"/readyz/poststarthook/start-service-ip-repair-controllers",
"/readyz/poststarthook/start-system-namespaces-controller",
"/readyz/poststarthook/storage-object-count-tracker-hook",
"/readyz/shutdown",
"/version"
]
}
Analyzing the first level we have a set.
- /api : Core groups
- /apis : Named groups
- /healthz (deprecated) : Same as livez. It's obsolete, it's here for backward compatibility for now.
- /livez : Used to monitor cluster health
- /logs : Used to integrate with third-party log extraction applications
- /metrics : Used to monitor cluster health
- /openapi : Documentation
- The OpenAPI specification defines a machine-readable interface for RESTful APIs, allowing developers to easily understand the structure and functionality of available APIs.
- /openid : Documentation
- /readyz : Used to monitor cluster health
- /version : Used to identify information about the cluster version
livez and readyz only return ok which is a 200 code for each of these paths. They have different purposes.
Starting with the simplest one, version.
/version
curl http://127.0.0.1:6443/version
{
"major": "1",
"minor": "29",
"gitVersion": "v1.29.1",
"gitCommit": "bc401b91f2782410b3fb3f9acf43a995c4de90d2",
"gitTreeState": "clean",
"buildDate": "2024-02-02T01:12:58Z",
"goVersion": "go1.21.6",
"compiler": "gc",
"platform": "linux/amd64"
}
## And if I wanted to see it in kubectl
kubectl get --raw /version
{
"major": "1",
"minor": "29",
"gitVersion": "v1.29.1",
"gitCommit": "bc401b91f2782410b3fb3f9acf43a995c4de90d2",
"gitTreeState": "clean",
"buildDate": "2024-02-02T01:12:58Z",
"goVersion": "go1.21.6",
"compiler": "gc",
"platform": "linux/amd64"
}
# Which would be the same as the command
kubectl version -o yaml
clientVersion:
buildDate: "2024-01-17T13:49:03Z"
compiler: gc
gitCommit: be3af46a4654bdf05b4838fe94e95ec8c165660c
gitTreeState: clean
gitVersion: v1.28.6
goVersion: go1.20.13
major: "1"
minor: "28"
platform: linux/amd64
kustomizeVersion: v5.0.4-0.20230601165947-6ce0bf390ce3
serverVersion:
buildDate: "2024-02-02T01:12:58Z"
compiler: gc
gitCommit: bc401b91f2782410b3fb3f9acf43a995c4de90d2
gitTreeState: clean
gitVersion: v1.29.1
goVersion: go1.21.6
major: "1"
minor: "29"
platform: linux/amd64
/livez and /readyz
A quick look at livez which is used to check if the server is operational and responding to requests.
The livez endpoint is the sum of OK from all other endpoints below it. If something is wrong it won't be OK.
kubectl get --raw='/livez'
ok
# If you want a more verbose output with everything it executed, like a log
kubectl get --raw='/livez?verbose'
[+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/priority-and-fairness-config-consumer ok
[+]poststarthook/priority-and-fairness-filter ok
[+]poststarthook/storage-object-count-tracker-hook ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/start-service-ip-repair-controllers ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/priority-and-fairness-config-producer ok
[+]poststarthook/start-system-namespaces-controller ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-apiserver-identity-lease-controller ok
[+]poststarthook/start-kube-apiserver-identity-lease-garbage-collector ok
[+]poststarthook/start-legacy-token-tracking-controller ok
[+]poststarthook/aggregator-reload-proxy-client-cert ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
[+]poststarthook/apiservice-openapiv3-controller ok
[+]poststarthook/apiservice-discovery-controller ok
livez check passed
The readyz also serves for monitoring but with the purpose of checking if the Kubernetes server is ready to accept application traffic. The ready endpoint is the sum of OK from all other endpoints below it. If something is wrong it won't be OK.
kubectl get --raw='/readyz'
ok
kubectl get --raw='/readyz?verbose'
[+]ping ok
[+]log ok
[+]etcd ok
[+]etcd-readiness ok
[+]informer-sync ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/priority-and-fairness-config-consumer ok
[+]poststarthook/priority-and-fairness-filter ok
[+]poststarthook/storage-object-count-tracker-hook ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/start-service-ip-repair-controllers ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/priority-and-fairness-config-producer ok
[+]poststarthook/start-system-namespaces-controller ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-apiserver-identity-lease-controller ok
[+]poststarthook/start-kube-apiserver-identity-lease-garbage-collector ok
[+]poststarthook/start-legacy-token-tracking-controller ok
[+]poststarthook/aggregator-reload-proxy-client-cert ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
[+]poststarthook/apiservice-openapiv3-controller ok
[+]poststarthook/apiservice-discovery-controller ok
[+]shutdown ok
readyz check passed
/openapi
All endpoints in openapi have a json document that describes the available APIs along with details about paths, parameters, return types and other relevant information about each endpoint.
The main purpose of the /openapi endpoint is to provide developers with a standardized and automated description of the APIs available in the Kubernetes cluster. This is especially useful when building tools, clients, or automations that interact with Kubernetes, as it allows for easier and more robust integration with cluster APIs.
Now let's get to the main content,
/api
This group contains all core functionality, note that v1 has everything to do with the apiVersion we put in manifests, being a subgroup of api
# I removed some of the output using ... and leaving only the names. Only in pods I left for better analysis
kubectl get --raw='/api/v1'
{
"kind": "APIResourceList",
"groupVersion": "v1",
"resources": [
{
"name": "bindings",
...
},
{
"name": "componentstatuses",
...
},
{
"name": "configmaps",
...
"storageVersionHash": "qFsyl6wFWjQ="
},
{
"name": "endpoints",
...
},
{
"name": "events",
...
},
{
"name": "limitranges",
...
},
{
"name": "namespaces",
...
},
{
"name": "namespaces/finalize",
...
},
{
"name": "namespaces/status",
...
},
{
"name": "nodes",
...
},
{
"name": "nodes/proxy",
...
},
{
"name": "nodes/status",
...
},
{
"name": "persistentvolumeclaims",
...
},
{
"name": "persistentvolumeclaims/status",
...
},
{
"name": "persistentvolumes",
...
},
{
"name": "persistentvolumes/status",
...
},
{
"name": "pods",
"singularName": "pod",
"namespaced": true, #<<< Whether this resource is at namespace level. True = namespaced ; False = Cluster
"kind": "Pod",
"verbs": [
"create",
"delete",
"deletecollection",
"get",
"list",
"patch",
"update",
"watch"
],
"shortNames": [
"po"
],
"categories": [
"all"
],
"storageVersionHash": "xPOwRZ+Yhw8="
},
{
"name": "pods/attach",
...
},
{
"name": "pods/binding",
...
},
{
"name": "pods/ephemeralcontainers",
...
},
{
"name": "pods/eviction",
...
},
{
"name": "pods/exec",
...
},
{
"name": "pods/log",
...
},
{
"name": "pods/portforward",
...
},
{
"name": "pods/proxy",
...
},
{
"name": "pods/status",
"singularName": "",
"namespaced": true,
"kind": "Pod",
"verbs": [
"get",
"patch",
"update"
]
},
{
"name": "podtemplates",
...
},
{
"name": "replicationcontrollers",
...
},
{
"name": "replicationcontrollers/scale",
...
},
{
"name": "replicationcontrollers/status",
...
},
{
"name": "resourcequotas",
...
},
{
"name": "resourcequotas/status",
...
},
{
"name": "secrets",
...
},
{
"name": "serviceaccounts",
...
},
{
"name": "serviceaccounts/token",
...
},
{
"name": "services",
...
},
{
"name": "services/proxy",
...
},
{
"name": "services/status",
...
}
]
}
These resources are the main core of kubernetes. We've already seen many of them here.
Making a more summarized list we have and whether their scope is at namespace or cluster level.
- bindings : Namespace
- componentstatuses : Cluster
- configmaps : Namespace
- endpoints : Namespace
- events : Namespace
- limitranges : Namespace
- namespaces : Cluster
- nodes : Cluster
- persistentvolumeclaims : Namespace
- persistentvolumes : Cluster
- pods : Namespace
- podtemplates : Namespace
- replicationcontrollers : Namespace
- resourcequotas : Namespace
- secrets : Namespace
- serviceaccounts : Namespace
- services : Namespace
Looking at pods we can see that we have verbs (actions) that we can execute on resources. The verbs are different depending on the resource.
The possible verbs are those listed in the main resource like in pods.
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
In pod/status we don't have some verbs.
The same applies to services and service/* or persistentvolumeclaim and persistentvolumeclaim/*.
Note that these verbs are widely used in the kubectl command itself.
To see the possible apigroups we have the command.
kubectl get --raw='/?-k'
# or
curl http://127.0.0.1:6443 -k
/apis
In apis the groups are more organized and will aggregate the newer resources available for Kubernetes. At the first level we only find more groups.
kubectl get --raw='/apis' | jq
{
"kind": "APIGroupList",
"apiVersion": "v1",
# Each group needs to be named with the available versions and the preferred version which would be the default
"groups": [
{
"name": "apiregistration.k8s.io",
"versions": [
{
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
}
},
## I left this group complete to observe
{
"name": "apps",
"versions": [
{
"groupVersion": "apps/v1", #We've used this before
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "apps/v1",
"version": "v1"
}
},
{
"name": "events.k8s.io",
...
},
{
"name": "authentication.k8s.io",
...
},
{
"name": "authorization.k8s.io",
...
},
# A case with more than one version and showing that there is a default version
# In this case it's used to support backward compatibility until it's deprecated
{
"name": "autoscaling",
"versions": [
{
"groupVersion": "autoscaling/v2",
"version": "v2"
},
{
"groupVersion": "autoscaling/v1",
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "autoscaling/v2",
"version": "v2"
}
},
{
"name": "batch",
...
},
{
"name": "certificates.k8s.io",
...
},
{
"name": "networking.k8s.io",
...
},
{
"name": "policy",
...
},
{
"name": "rbac.authorization.k8s.io",
...
},
{
"name": "storage.k8s.io",
...
},
{
"name": "admissionregistration.k8s.io",
...
},
{
"name": "apiextensions.k8s.io",
...
},
{
"name": "scheduling.k8s.io",
},
{
"name": "coordination.k8s.io",
...
},
{
"name": "node.k8s.io",
...
},
{
"name": "discovery.k8s.io",
...
},
{
"name": "flowcontrol.apiserver.k8s.io",
...
}
]
}
Making a summary we have the subgroups below and within each of them we have more kubernetes resources.
- apps : Namespace
- events.k8s.io : Namespace
- authentication.k8s.io : Cluster
- authorization.k8s.io : Cluster and Namespace
- autoscaling : Namespace
- batch : Namespace
- certificates.k8s.io : Cluster
- networking.k8s.io : Namespace
- policy : Namespace
- rbac.authorization.k8s.io : Namespace
- storage.k8s.io : Namespace
- admissionregistration.k8s.io : Namespace
- apiextensions.k8s.io : Namespace
- scheduling.k8s.io : Namespace
- coordination.k8s.io : Namespace
- node.k8s.io : Namespace
- discovery.k8s.io : Namespace
- flowcontrol.apiserver.k8s.io : Namespace
Let's analyze apps, but what I'm going to do would apply to each of the groups above. Similarly I'll reduce the output to make it easier to read. Likewise we have the verbs.
kubectl get --raw='/apis/apps/v1' | jq
{
# Here what is expected to have in each of the resources
"kind": "APIResourceList",
"apiVersion": "v1",
"groupVersion": "apps/v1",
"resources": [
{
"name": "controllerrevisions",
"singularName": "controllerrevision",
"namespaced": true,
"kind": "ControllerRevision",
"verbs": [
"create",
"delete",
"deletecollection",
"get",
"list",
"patch",
"update",
"watch"
],
"storageVersionHash": "85nkx63pcBU="
},
{
"name": "daemonsets",
...
{
"name": "daemonsets/status",
...
{
"name": "deployments",
"singularName": "deployment",
"namespaced": true,
"kind": "Deployment",
"verbs": [
"create",
"delete",
"deletecollection",
"get",
"list",
"patch",
"update",
"watch"
],
"shortNames": [
"deploy"
],
"categories": [
"all"
],
"storageVersionHash": "8aSe+NMegvE="
},
{
"name": "deployments/scale",
...
{
"name": "deployments/status",
...
{
"name": "replicasets",
...
{
"name": "replicasets/scale",
...
{
"name": "replicasets/status",
...
{
"name": "statefulsets",
...
{
"name": "statefulsets/scale",
...
{
"name": "statefulsets/status",
...
}
}
If we were to summarize we would find in apps.
- apps
- v1
- daemonsets
- deployments
- replicasets
- statefulset
- v1
Let's fill in the groups and what we would find inside them. Remember that it's not complete, only the main resource. I'll emphasize showing what scope it has to better understand some concepts later.
- apps
- v1
- daemonsets : Namespace
- deployments : Namespace
- replicasets : Namespace
- statefulset : Namespace
- v1
- events.k8s.io
- v1
- events : Namespace
- v1
- authentication.k8s.io
- v1
- selfsubjectreviews : Cluster
- tokenreviews : : Cluster
- v1
- authorization.k8s.io
- v1
- localsubjectaccessreviews : Namespace
- selfsubjectaccessreviews : Cluster
- selfsubjectrulesreviews : Cluster
- subjectaccessreviews : Cluster
- v1
- autoscaling
- v1
- horizontalpodautoscalers : Namespace
- v2
- horizontalpodautoscalers : Namespace
- v1
- batch
- v1
- cronjobs : Namespace
- jobs : Namespace
- v1
- certificates.k8s.io
- v1
- certificatesigningrequests: Cluster
- v1
- networking.k8s.io
- v1
- ingresses : Namespace
- ingressclasses : Cluster
- networkpolicies : : Namespace
- v1
- policy
- v1
- poddisruptionbudgets : Namespace
- v1
- rbac.authorization.k8s.io
- v1
- clusterroles : Cluster
- clusterrolebindings : Cluster
- roles : Namespace
- rolebindings : Namespace
- v1
- storage.k8s.io
- v1
- storageclasses : Cluster
- volumeattachments : Cluster
- csidrivers : Cluster
- csinodes : Cluster
- csistoragecapacities : Namespace
- v1
- admissionregistration.k8s.io
- v1
- mutatingwebhookconfigurations : Cluster
- validatingwebhookconfigurations : Cluster
- v1
- apiextensions.k8s.io
- v1
- customresourcedefinitions : Cluster
- v1
- scheduling.k8s.io
- v1
- priorityclasses : Cluster
- v1
- coordination.k8s.io
- v1
- leases : Namespace
- v1
- node.k8s.io
- v1
- runtimeclasses : Cluster
- v1
- discovery.k8s.io
- v1
- endpointslices : Namespace
- v1
- flowcontrol.apiserver.k8s.io
- v1
- flowschemas : Cluster
- prioritylevelconfigurations : Cluster
- v1beta3
- flowschemas : Cluster
- prioritylevelconfigurations : Cluster
- v1
What to take from all this?
All kubernetes resources are grouped into different apigroups. At the top level we have /api with the kubernetes core and /apis with named groups. Within each group we have different resources and the associated verbs which are a set of possible actions that will be used to allow or deny a user from doing something and whether a resource is cluster or namespace level.

The command kubectl api-resources will bring all kubernetes resources.
# Cluster level resources
kubectl api-resources --namespaced=false -o name
# Namespace level resources
kubectl api-resources --namespaced=true -o name