API Groups
Como ya hemos mencionado varias veces, cualquier interacción con el servidor se realiza a través de una API que es administrada por el kube-apiserver.
Para facilitar el estudio y no tener que estar pasando certificados directamente cada vez que hacemos una petición directa al kube-apiserver usando REST, vamos a crear un proxy.
El comando inicia un servidor proxy local en el puerto 6443 que permite acceder al API Server de Kubernetes. Podría ser cualquier puerto, usé el mismo 6443 solo para saber que es el puerto del servidor. De esta forma podemos ver todo desde el navegador.
kubectl proxy --port=6443 &
[1] 1735417
➜ files git:(main) ✗ Starting to serve on 127.0.0.1:6443
# Si no quieres especificar el puerto, simplemente ejecuta el comando a continuación y se establecerá en el puerto 8001
kubectl proxy
kubectl proxy no es lo mismo que kube-proxy. Kube-proxy es un componente de Kubernetes que administra los servicios. En este caso es solo un comando que facilita la vida.

Vamos a observar lo que tenemos aquí.
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"
]
}
Analizando el primer nivel tenemos un conjunto.
- /api : Core groups
- /apis : Named groups
- /healthz (deprecated) : Lo mismo que livez. Está obsoleto, está aquí por una cuestión de retrocompatibilidad por ahora.
- /livez : Usado para monitorear la salud del cluster
- /logs : Usado para integrar con aplicaciones de extracción de logs de terceros
- /metrics : Usado para monitorear la salud del cluster
- /openapi : Documentación
- La especificación OpenAPI define una interfaz legible por máquinas para APIs RESTful, permitiendo que los desarrolladores entiendan fácilmente la estructura y funcionalidad de las APIs disponibles.
- /openid : Documentación
- /readyz : Usado para monitorear la salud del cluster
- /version : Usado para identificar información sobre la versión del cluster
livez y readyz solo retornan ok que es un código 200 para cada uno de estos paths. Tienen propósitos diferentes.
Comenzando por lo más simple, el 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"
}
## Y si quisiera verlo en 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"
}
# Que sería lo mismo que el comando
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 y /readyz
Una rápida revisión del livez que sirve para verificar si el servidor está operacional y respondiendo a las solicitudes.
El endpoint livez es la suma del OK de todos los otros endpoints debajo de él. Si algo está mal no estará OK.
kubectl get --raw='/livez'
ok
# Si quieres una salida más detallada con todo lo que ejecutó, como si fuera el 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
El readyz también sirve para monitoreo pero con el propósito de verificar si el servidor de Kubernetes está listo para aceptar tráfico de aplicaciones. El endpoint ready es la suma del OK de todos los otros endpoints debajo de él. Si algo está mal no estará 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
Todos los endpoints en openapi poseen un documento json que describe las apis disponibles junto con los detalles sobre los paths, parámetros, tipos de retorno y otra información relevante sobre cada endpoint.
El objetivo principal del endpoint /openapi es proporcionar a los desarrolladores una descripción estandarizada y automatizada de las APIs disponibles en el cluster de Kubernetes. Esto es especialmente útil al construir herramientas, clientes o automatizaciones que interactúan con Kubernetes, ya que permite una integración más fácil y robusta con las APIs del cluster.
Ahora vamos al contenido principal,
/api
Este grupo contiene todas las funcionalidades centrales, observa que v1 tiene todo que ver con el apiVersion que colocamos en los manifiestos, siendo un subgrupo de api
# Eliminé un poco de la salida colocando ... y dejando solo los nombres. Solo en pods lo dejé para un mejor análisis
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, #<<< Si este recurso está a nivel de namespace. 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",
...
}
]
}
Estos recursos son los principales del core de kubernetes. Muchos de ellos ya los vimos aquí.
Haciendo una lista más resumida tenemos y si su alcance está a nivel de namespace o cluster.
- 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
Observando en pods podemos ver que tenemos verbos (acciones) que podemos ejecutar en los recursos. Los verbos son diferentes dependiendo del recurso.
Los posibles verbos son los listados en el recurso principal como en pods.
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
Ya en pod/status no tenemos algunos verbos.
Lo mismo vale para services y service/* o persistentvolumeclain y persistentvolumeclain/*.
Observa que estos verbos son muy usados en el propio comando kubectl.
Para ver los posibles apigroups tenemos el comando.
kubectl get --raw='/?-k'
# o
curl http://127.0.0.1:6443 -k
/apis
Ya en apis los grupos están más organizados y van a agregar los recursos más nuevos disponibles para Kubernetes. En el primer nivel solo encontramos más grupos.
kubectl get --raw='/apis' | jq
{
"kind": "APIGroupList",
"apiVersion": "v1",
# Cada grupo necesita ser nombrado con el nombre, las versiones disponibles y la versión preferida que sería la default
"groups": [
{
"name": "apiregistration.k8s.io",
"versions": [
{
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
}
},
## Dejé este grupo completo para observar
{
"name": "apps",
"versions": [
{
"groupVersion": "apps/v1", #Ya usamos esto antes
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "apps/v1",
"version": "v1"
}
},
{
"name": "events.k8s.io",
...
},
{
"name": "authentication.k8s.io",
...
},
{
"name": "authorization.k8s.io",
...
},
# Un caso con más de una versión y mostrando que existe una versión default
# En este caso se usa para soportar retrocompatibilidad hasta que sea deprecado
{
"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",
...
}
]
}
Haciendo un resumen tenemos los subgrupos abajo y dentro de cada uno de ellos tenemos más recursos de kubernetes.
- apps : Namespace
- events.k8s.io : Namespace
- authentication.k8s.io : Cluster
- authorization.k8s.io : Cluster y 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
Vamos a analizar apps, pero lo que voy a hacer valdría para cada uno de los grupos anteriores. De la misma manera voy a reducir la salida para que sea más fácil de leer. Igualmente tenemos los verbos.
kubectl get --raw='/apis/apps/v1' | jq
{
# Aquí lo que se espera que tenga en cada uno de los recursos
"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",
...
}
}
Si fuéramos a resumir encontraríamos en apps.
- apps
- v1
- daemonsets
- deployments
- replicasets
- statefulset
- v1
Vamos a completar entonces las cosas los grupos y lo que encontraríamos dentro de ellos. Recordando que no está completo, solo el recurso principal. Voy a dar énfasis en mostrar qué alcance posee para entender mejor algunos conceptos después.
- 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
¿Qué sacar de todo esto?
Todos los recursos de kubernetes están agrupados en diferentes apigroups. En el top level tenemos /api con el core de kubernetes y /apis con los grupos nombrados. Dentro de cada grupo tenemos diferentes recursos y los verbos asociados que son un conjunto de acciones posibles que serán usadas para permitir o negar que un usuario haga algo y si un recurso es de nivel cluster o namespace.

El comando kubectl api-resources traerá todos los recursos de kubernetes.
# Recursos a nivel de cluster
kubectl api-resources --namespaced=false -o name
# Recursos a nivel de namespace
kubectl api-resources --namespaced=true -o name