Kubernetes API Resources and kubectl explain with Examples

Use kubectl api-resources, api-versions, and explain to discover supported resource types, API versions, and valid YAML fields on any Kubernetes cluster.

Published

Updated

Read time 11 min read

Reviewed byDeepak Prasad

kubectl api-resources and kubectl explain discovering Kubernetes API fields
Tested on Rocky Linux 10.2 (Red Quartz) workstation
Package kubectl 1.36.3
Applies to Any Linux host with kubectl configured; any Kubernetes cluster
Cert prep CKAD · CKA · CKS
Lab environment Multi-node kubeadm cluster with containerd — install Kubernetes with kubeadm
Privilege Normal user (no sudo required on the workstation)
Scope kubectl api-resources, api-versions, and explain for API discovery; resource names, kinds, short names, and API groups; building a Pod manifest from discovered fields. Does not cover REST API auth, RBAC YAML, CRD authoring, full YAML anatomy, or API deprecation migration.
Related guides Install kubectl and configure kubeconfig

When you write Kubernetes YAML, you need the correct resource name, apiVersion, and field paths. kubectl api-resources, kubectl api-versions, and kubectl explain query the connected API server so you work from what the cluster actually supports instead of a static cheat sheet.

kubectl api-resources vs api-versions vs explain

Command Main purpose Example
kubectl api-resources List resource types the cluster supports kubectl api-resources -o wide
kubectl api-versions List served API group/version pairs kubectl api-versions
kubectl explain Inspect resource fields and schema documentation kubectl explain pod.spec.containers --recursive
kubectl get List actual objects of a resource type kubectl get pods

api-resources answers what types exist. kubectl get pods answers which Pod objects exist right now.


What Are Kubernetes API Resources?

Kubernetes manages state through API resources. Pods, Deployments, Services, and ConfigMaps are resource types. Each type has a REST endpoint on the API server.

The API server exposes only the resources your cluster supports. Installing an Operator or CustomResourceDefinition can add new rows to kubectl api-resources. The command discovers resources from the connected cluster; it does not read a fixed list bundled with kubectl.

A resource is the API type and endpoint, such as pods. An object is one instance of that resource, such as a Pod named nginx in the default namespace. For complete object structure and YAML anatomy, see kubectl commands and YAML examples.

Usage Example
Resource name in kubectl pods
Singular resource name pod
Kind in YAML Pod
Short name po

Resource names are lowercase and usually plural in commands. kind values use the capitalization defined by the API.


Understand kubectl api-resources Output

The default columns describe how kubectl addresses each resource type:

Column Meaning Example
NAME Canonical plural resource name for kubectl commands pods, deployments, services
SHORTNAMES Optional abbreviations; not every resource defines one po, deploy, svc, ns
APIVERSION API group and version for manifests v1, apps/v1, networking.k8s.io/v1
NAMESPACED true for namespace-scoped types; false for cluster-scoped types Pods are namespaced; Nodes are not
KIND Value for the kind field in YAML Pod, Deployment, Service

When no short name exists, use the NAME column. For namespace workflows, see Kubernetes namespaces.


List and Filter Kubernetes API Resources

Query resource types from the connected API server. Output always reflects the cluster and context in your current kubeconfig.

Task Command
List preferred API resources kubectl api-resources
Show verbs and categories kubectl api-resources -o wide
Print compact resource names for piping kubectl api-resources -o name
Sort by resource name kubectl api-resources --sort-by=name
List namespaced resources only kubectl api-resources --namespaced=true
List cluster-scoped resources only kubectl api-resources --namespaced=false
Filter by API group kubectl api-resources --api-group=apps
Filter by supported verb kubectl api-resources --verbs=list
Filter by category kubectl api-resources --categories=all

Do not expect output to match another cluster byte for byte. Results vary with Kubernetes version, enabled API groups, and installed extensions such as Calico CRDs on the lab cluster.

List the preferred API resources returned through server discovery:

bash
kubectl api-resources

The command uses the server's preferred-resource discovery results, rather than enumerating every served version of every resource. kubectl api-versions shows all served group/version pairs.

Do not treat this output as a complete RBAC subresource inventory. Subresources such as pods/log or pods/exec may not appear in kubectl api-resources.

Sample output (representative rows only):

output
NAME              SHORTNAMES   APIVERSION             NAMESPACED   KIND
nodes             no           v1                     false        Node
pods              po           v1                     true         Pod
services          svc          v1                     true         Service
deployments       deploy       apps/v1                true         Deployment
networkpolicies   netpol       networking.k8s.io/v1   true         NetworkPolicy

Add API group, supported verbs, and categories with wide output:

bash
kubectl api-resources -o wide

Sample output (trimmed):

output
NAME         SHORTNAMES   APIVERSION   NAMESPACED   KIND        VERBS                                                        CATEGORIES
configmaps   cm           v1           true         ConfigMap   create,delete,deletecollection,get,list,patch,update,watch   
pods         po           v1           true         Pod         create,delete,deletecollection,get,list,patch,update,watch   all

VERBS lists API capabilities for that resource type. CATEGORIES groups resources for shortcuts such as kubectl get all. A listed verb does not mean your user account may perform it. Use kubectl auth can-i and Kubernetes RBAC for permission checks.

Filter by API group when you know the group from YAML but not the plural resource name:

bash
kubectl api-resources --api-group=apps

Sample output:

output
NAME                  SHORTNAMES   APIVERSION   NAMESPACED   KIND
controllerrevisions                apps/v1      true         ControllerRevision
daemonsets            ds           apps/v1      true         DaemonSet
deployments           deploy       apps/v1      true         Deployment
replicasets           rs           apps/v1      true         ReplicaSet
statefulsets          sts          apps/v1      true         StatefulSet

Sorting by name helps when you know the Kind from YAML but not the plural resource name. Use -o name when you need compact resource names suitable for piping into other commands. Filtering with --verbs=list or --categories=all narrows the list by API capability or convenience grouping, not by your RBAC permissions.

kubectl get all omits many resource types because all is a category, not a wildcard. To list existing objects across namespaced types that support list, pipe compact resource names into kubectl get:

bash
kubectl api-resources --verbs=list --namespaced=true -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n default

The first command produces namespaced resource types that support list. xargs then queries existing objects of each type in the default namespace. This lists objects, whereas kubectl api-resources alone lists resource types.


Understand Kubernetes API Groups and Versions

Core resources use an apiVersion without a group prefix. In manifests you write apiVersion: v1, not core/v1. Pod, Service, ConfigMap, Secret, and Namespace are core types.

Named API groups use a group prefix:

Resource API version
Deployment apps/v1
Job batch/v1
NetworkPolicy networking.k8s.io/v1
Role rbac.authorization.k8s.io/v1

Print every served group/version pair:

bash
kubectl api-versions

Sample output (trimmed):

output
admissionregistration.k8s.io/v1
apiextensions.k8s.io/v1
apps/v1
batch/v1
networking.k8s.io/v1
rbac.authorization.k8s.io/v1
v1

Each line is one API version the server accepts. Core resources appear as bare v1.

Use kubectl api-resources as the primary way to find the preferred version for a resource type. The APIVERSION column shows the version returned through API discovery for normal kubectl use. Deployments list as apps/v1 and Pods as v1.

A served version is accepted by the current API server. An older version may be deprecated before removal. A manifest that works on one Kubernetes release can fail after an API version is removed. For migration steps and removed versions, see API deprecations and manifest migration. This article stops at discovery; it does not walk through every deprecation timeline.


Use Resource Names, Kinds, and Short Names

kubectl accepts singular and plural forms for many built-in types:

bash
kubectl get pod
kubectl get pods

Documentation and scripts usually use the plural canonical name from the NAME column. Short names such as po, deploy, svc, and ns speed up interactive typing:

bash
kubectl get po
kubectl get deploy

Prefer full resource names in scripts and shared documentation so readers see the exact API type.

When two API groups expose similar names, qualify the resource with the API group suffix from the APIVERSION column:

bash
kubectl get deployments.apps
kubectl get networkpolicies.networking.k8s.io
kubectl get roles.rbac.authorization.k8s.io

For an unfamiliar resource:

  1. Run kubectl api-resources.
  2. Search or filter the output (--api-group, --namespaced, or scroll).
  3. Note the resource name, Kind, and API version.
  4. Run kubectl explain <resource> to inspect valid fields.

Use kubectl explain

kubectl explain prints schema documentation for resources the connected API server supports. Use it when you write YAML without opening external docs, when you need the correct nested field path, or when you want to confirm a field type.

Inspect the top-level Pod schema:

bash
kubectl explain pod

Sample output (trimmed):

output
KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Pod is a collection of containers that can run on a host. This resource is
    created by clients and scheduled onto hosts.
    
FIELDS:
  apiVersion	<string>
  kind	<string>
  metadata	<ObjectMeta>
  spec	<PodSpec>
  status	<PodStatus>

KIND supplies the manifest kind. For core resources, VERSION is also the apiVersion, such as v1. For named API groups, combine GROUP and VERSION, such as apps/v1. FIELDS lists the next level to drill into.

kubectl explain annotates field types in angle brackets. Use the markers to decide whether YAML needs a scalar, list, object, or map:

Output Meaning
<string> Single string value
<[]Container> List of Container objects
<map[string]string> String key/value map
-required- Required at that schema level

Drill into nested fields with a dot-separated path. Each additional segment narrows the schema:

bash
kubectl explain pod.spec
kubectl explain pod.spec.containers
kubectl explain pod.spec.containers.resources

Sample output from pod.spec.containers (trimmed):

output
FIELD: containers <[]Container>

FIELDS:
  args	<[]string>
  command	<[]string>
  image	<string>
  name	<string> -required-
  ports	<[]ContainerPort>
  resources	<ResourceRequirements>

Expand the next level of fields in one view with --recursive. In Kubernetes v1.36, kubectl explain --recursive documents one level of expansion at a time, not the entire deeply nested schema:

bash
kubectl explain pod --recursive

Sample output (trimmed):

output
KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Pod is a collection of containers that can run on a host. This resource is
    created by clients and scheduled onto hosts.
    
FIELDS:
  apiVersion	<string>
  kind	<string>
  metadata	<ObjectMeta>
    annotations	<map[string]string>
    creationTimestamp	<string>
    deletionGracePeriodSeconds	<integer>
    deletionTimestamp	<string>
    finalizers	<[]string>
    generateName	<string>
    generation	<integer>
    labels	<map[string]string>
    managedFields	<[]ManagedFieldsEntry>
      apiVersion	<string>
      fieldsType	<string>
      fieldsV1	<FieldsV1>
      manager	<string>
      operation	<string>
      subresource	<string>
      time	<string>
    name	<string>
    namespace	<string>

metadata shows its immediate child fields; managedFields expands one level under that entry. Deeper paths such as spec.containers still need a separate kubectl explain pod.spec.containers call. Explaining one field at a time usually gives richer descriptions than --recursive.

Pin the schema to a specific API version when you compare schemas, follow older documentation, or inspect a custom resource with multiple served versions:

bash
kubectl explain deployment --api-version=apps/v1

Sample output (trimmed):

output
GROUP:      apps
KIND:       Deployment
VERSION:    v1

Build a Kubernetes YAML Manifest with kubectl explain

The following exercise builds one Pod manifest using fields discovered from the API server.

Confirm Pod metadata from discovery:

bash
kubectl api-resources | grep -w pods

Sample output:

output
pods              po           v1           true         Pod

The manifest header is apiVersion: v1 and kind: Pod.

Inspect metadata and specification fields before you write YAML:

bash
kubectl explain pod.metadata
kubectl explain pod.spec
kubectl explain pod.spec.containers

Sample output from pod.metadata (trimmed):

output
FIELD: metadata <ObjectMeta>

FIELDS:
  annotations	<map[string]string>
  labels	<map[string]string>
  name	<string>
  namespace	<string>

Use name and namespace for identity. Add labels when a controller or Service will select the Pod. The containers field is required for a runnable Pod. Relevant keys for a minimal Pod include name, image, command, args, and ports.

Save this manifest as explain-demo.yaml:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: explain-demo
  namespace: default
  labels:
    app: explain-demo
spec:
  containers:
  - name: nginx
    image: nginx:1.27
    ports:
    - containerPort: 80

Every key came from kubectl explain paths: top-level apiVersion/kind, metadata.*, and spec.containers with name, image, and ports.

Ask the API server to validate the object without creating it:

bash
kubectl apply --dry-run=server -f explain-demo.yaml

Sample output:

output
pod/explain-demo created (server dry run)

Server dry run confirms the schema and admission checks accept the manifest. For imperative versus declarative kubectl workflows and fuller YAML anatomy, see kubectl commands and YAML examples.


Discover Custom Resources and CRDs

Installing Calico on the lab cluster adds rows such as networkpolicies under crd.projectcalico.org/v1 alongside the built-in networking.k8s.io/v1 NetworkPolicy. New Operator or CRD installs can change kubectl api-resources output immediately.

List resources from a CRD API group reported in discovery. On the lab cluster, Calico registers types under crd.projectcalico.org:

bash
kubectl api-resources --api-group=crd.projectcalico.org

Sample output (trimmed):

output
NAME                    SHORTNAMES   APIVERSION                 NAMESPACED   KIND
globalnetworkpolicies                crd.projectcalico.org/v1   false        GlobalNetworkPolicy
ippools                              crd.projectcalico.org/v1   false        IPPool
networkpolicies                      crd.projectcalico.org/v1   true         NetworkPolicy

These rows are custom resources added by Calico CRDs. They are separate from the built-in networking.k8s.io/v1 NetworkPolicy in the core Kubernetes API. Replace the group with the value from your installed CRD when you troubleshoot other extensions.

Read APIVERSION and KIND from kubectl api-resources, then confirm the group appears in kubectl api-versions. kubectl explain reads schema information published by the API server. Select a specific group and version with --api-version:

bash
kubectl explain networkpolicy --api-version=crd.projectcalico.org/v1

Sample output (trimmed):

output
GROUP:      crd.projectcalico.org
KIND:       NetworkPolicy
VERSION:    v1

DESCRIPTION:
    <empty>
FIELDS:
  apiVersion	<string>
  kind	<string>
  metadata	<ObjectMeta>
  spec	<Object>

Field detail depends on the schema the CRD author published. Calico may show <empty> descriptions when the CRD does not ship rich OpenAPI documentation.

The CustomResourceDefinition defines the type. Custom resources are instances you create from that definition. For end-user CRD concepts, see CRDs and custom resources. This article does not cover CRD schema authoring or controller code.


Troubleshoot Kubernetes API Resource Errors

Symptom Likely cause Fix
the server doesn't have a resource type, short name failure, or wrong resource on kubectl get Typo, wrong singular/plural, missing short name, CRD not installed, or wrong context kubectl api-resources; use NAME or a fully qualified name such as deployments.apps; confirm kubectl config current-context
kubectl explain cannot find a resource Resource missing from discovery, wrong context, typo, or extension not installed kubectl api-resources; confirm active context and spelling
kubectl explain cannot find a field Typo in dot-separated path, wrong --api-version, or field removed in your Kubernetes version Re-run explain one segment at a time; pin --api-version to match the manifest
Discovery output looks outdated Wrong context, API server was unavailable, or new CRD not ready kubectl config current-context; reconnect; wait for CRD establishment before expecting new rows
Explain shows empty CRD descriptions CRD lacks rich OpenAPI schema detail Read CRD spec.versions[].schema or operator documentation

What's Next


References


Summary

Use kubectl api-resources and kubectl api-versions to discover what your cluster supports, then kubectl explain to walk field paths while you write YAML. Match resource names, kinds, and API versions from discovery output rather than from memory. kubectl get lists objects; discovery commands list types and schemas.


Frequently Asked Questions

1. Is apiVersion in a manifest the same as the Kubernetes cluster version?

No. The cluster version is the Kubernetes release on the control plane, such as v1.36.3. The manifest apiVersion selects the API group and schema version for one resource type, such as apps/v1 for a Deployment or v1 for a Pod.

2. What is the difference between a resource name and a Kind?

Kind is the singular CamelCase type in YAML, such as Deployment. The resource name is the lowercase plural REST collection kubectl uses, such as deployments. kubectl accepts the plural, singular, or short name on the command line, but manifests must use Kind.

3. Does kubectl get all list every API resource in the cluster?

No. all is a resource category, not a wildcard. kubectl get all shows common workload types in that category. Secrets, ConfigMaps, Roles, and many custom resources are omitted unless you query them directly or use kubectl api-resources.

4. Can kubectl explain show fields for custom resources?

Yes, when the CustomResourceDefinition publishes a usable OpenAPI schema. If explain returns little detail, inspect the CRD schema or operator documentation. Built-in resources always expose schema through the API server.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)