Don’t Memorize Kubernetes API Resources. Use These Two Kubectl Commands Instead!
How many times have you forgotten the name of a Kubernetes API resource you intended to create, view, or modify? Maybe you knew the name of the resource but forgot what the proper schema should be? Both of these scenarios happen to me all the time, especially for resources with longer names or for those I may not interact with daily.
For example, let’s pretend that you needed to create a new validating webhook. The ValidatingWebhookConfiguration resource would allow you to register this, but you may not know about this resource or remember its full name. Luckily, using the kubectl api-resources command, you could search through all of the registered API resources to find the right one.
Once you find the right resource, you would need to know the correct YAML schema so its configuration can be applied. Schemas can be lengthy and difficult to memorize. Luckily, you could use the kubectl explain command to find the full schema, which would help you write the declarative YAML without memorizing every detail.
In this post, I’ll explain the workflow I use to create Kubernetes API resources that involves as little memorization as possible. I first use kubectl api-resources to find the name of the resource if I’m unsure of its name. Then, I use kubectl explain to brush up on the resource’s schema so that I can create it.
Let’s first focus on kubectl api-resources.
Discovering API Resources With Kubectl Api-Resources
The kubectl api-resources command prints each registered API resource. Below is a snippet from the output of this command.
➜ ~ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
Scrolling through to the middle of the output shows the ValidatingWebhookConfiguration resource mentioned earlier.
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingadmissionpolicies admissionregistration.k8s.io/v1 false ValidatingAdmissionPolicy
validatingadmissionpolicybindings admissionregistration.k8s.io/v1 false ValidatingAdmissionPolicyBinding
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
While searching through the full contents of this output is one way of interacting with this command, I prefer to pipe this output to grep if I know what I’m looking for to limit the number of results returned. For example, let’s say I’m searching for the ValidatingWebhookConfiguration resource, and I know the resource’s name includes the word “validating” but I don’t remember the rest. I can pipe the kubectl api-resources output to grep using the command kubectl api-resources | grep validating, shown below:
➜ ~ kubectl api-resources | grep validating
validatingadmissionpolicies admissionregistration.k8s.io/v1 false ValidatingAdmissionPolicy
validatingadmissionpolicybindings admissionregistration.k8s.io/v1 false ValidatingAdmissionPolicyBinding
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
Since I grepped this output, I don’t need to search through the entire list of resources to determine the full name.
You can use this trick for any resource. Another good use case is for when you want to recall all of the API resources under a particular API group. For example, let’s say that you have Gatekeeper installed in your cluster. You can reveal each of the API resources required to interact with Gatekeeper by piping the kubectl api-resources output to grep, searching for the word “gatekeeper”:
➜ ~ kubectl api-resources | grep gatekeeper
➜ ~ kubectl api-resources | grep gatekeeper
configs config.gatekeeper.sh/v1alpha1 true Config
connections connection.gatekeeper.sh/v1alpha1 true Connection
expansiontemplate expansion.gatekeeper.sh/v1beta1 false ExpansionTemplate
providers externaldata.gatekeeper.sh/v1beta1 false Provider
assign mutations.gatekeeper.sh/v1 false Assign
assignimage mutations.gatekeeper.sh/v1alpha1 false AssignImage
assignmetadata mutations.gatekeeper.sh/v1 false AssignMetadata
modifyset mutations.gatekeeper.sh/v1 false ModifySet
configpodstatuses status.gatekeeper.sh/v1beta1 true ConfigPodStatus
connectionpodstatuses status.gatekeeper.sh/v1alpha1 true ConnectionPodStatus
constraintpodstatuses status.gatekeeper.sh/v1beta1 true ConstraintPodStatus
constrainttemplatepodstatuses status.gatekeeper.sh/v1beta1 true ConstraintTemplatePodStatus
expansiontemplatepodstatuses status.gatekeeper.sh/v1beta1 true ExpansionTemplatePodStatus
mutatorpodstatuses status.gatekeeper.sh/v1beta1 true MutatorPodStatus
providerpodstatuses status.gatekeeper.sh/v1beta1 true ProviderPodStatus
syncsets syncset.gatekeeper.sh/v1alpha1 false SyncSet
constrainttemplates templates.gatekeeper.sh/v1 false ConstraintTemplate
Given this output, I know the resources I need to use to interact with my Gatekeeper installation.
While finding resources with kubectl api-resources will likely be a useful tool in your toolbox, you must also know their schemas to create them. The kubectl explain command can help with this.
Recalling Resource Schemas With Kubectl Explain
There are many different resources and schemas you must interact with when working in Kubernetes. Luckily, you don’t have to commit these to memory with the kubectl explain command.
Following the example from before, let’s say that after I found the ValidatingWebhookConfiguration resource, I wanted to start writing the YAML for it. I may know part of the YAML and just need a refresher on the remaining bits, or I may be seeing it for the first time. Either way, I can begin discovering the schema by running kubectl explain validatingwebhookconfiguration, shown below:
➜ ~ kubectl explain validatingwebhookconfiguration
GROUP: admissionregistration.k8s.io
KIND: ValidatingWebhookConfiguration
VERSION: v1
DESCRIPTION:
ValidatingWebhookConfiguration describes the configuration of and admission
webhook that accept or reject and object without changing it.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <ObjectMeta>
Standard object metadata; More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
webhooks <[]ValidatingWebhook>
Webhooks is a list of webhooks and the affected resources and operations.
This output displays the top-level fields of the schema. You can see that you need to provide the apiVersion, kind, metadata, and webhooks to configure this resource. To step into each of these fields, you need to pass in the --recursive flag. Below is a snippet of output after using running kubectl explain validatingwebhookconfiguration --recursive.
➜ ~ kubectl explain validatingwebhookconfiguration --recursive
GROUP: admissionregistration.k8s.io
KIND: ValidatingWebhookConfiguration
VERSION: v1
DESCRIPTION:
ValidatingWebhookConfiguration describes the configuration of and admission
webhook that accept or reject and object without changing it.
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>
Using this command, you can see the full schema down to the last child level. Scrolling to the end of this output is the complete “webhooks” field, which configures the webhook in a ValidatingWebhookConfiguration resource.
webhooks <[]ValidatingWebhook>
admissionReviewVersions <[]string> -required-
clientConfig <WebhookClientConfig> -required-
caBundle <string>
service <ServiceReference>
name <string> -required-
namespace <string> -required-
path <string>
port <integer>
url <string>
failurePolicy <string>
enum: Fail, Ignore
matchConditions <[]MatchCondition>
expression <string> -required-
name <string> -required-
matchPolicy <string>
enum: Equivalent, Exact
name <string> -required-
namespaceSelector <LabelSelector>
matchExpressions <[]LabelSelectorRequirement>
key <string> -required-
operator <string> -required-
values <[]string>
matchLabels <map[string]string>
objectSelector <LabelSelector>
matchExpressions <[]LabelSelectorRequirement>
key <string> -required-
operator <string> -required-
values <[]string>
matchLabels <map[string]string>
rules <[]RuleWithOperations>
apiGroups <[]string>
apiVersions <[]string>
operations <[]string>
resources <[]string>
scope <string>
sideEffects <string> -required-
enum: None, NoneOnDryRun, Some, Unknown
timeoutSeconds <integer>
I use this all the time for both simple and complex resources. I can’t always remember the exact schemas, so I use kubectl explain with the --recursive flag to provide a quick reference from the command line.
You probably noticed that the kubectl explain --recursive command does not define each schema field – it simply outputs what the field is and its corresponding type. If you are unsure about how to configure a particular field, you’ll have to look through the Kubernetes documentation to learn more. The good thing, however, is that the schema itself will not be a mystery. You’ll be more familiar with what to look for once you get to the documentation.
Thanks For Reading!
I hope that you found this article to be helpful. I use the kubectl api-resources and kubectl explain commands all the time to recall resources that I haven’t memorized. Using these commands will save you a lot of time configuring your Kubernetes API resources.
Update: 7/31/2020
I previously mentioned that kubectl explain --recursive doesn’t provide any detailed descriptions of the output fields. Well, I recently learned a new trick that might save you a trip to documentation. After inspecting the output of kubectl explain validatingwebhookconfigurations –recursive, let’s say that I wanted to learn more about the webhooks.matchPolicy setting. It turns out I can pass this straight to kubectl explain and get a detailed description of the field in return. Here’s an example below:
➜ ~ kubectl explain validatingwebhookconfiguration.webhooks.matchPolicy
GROUP: admissionregistration.k8s.io
KIND: ValidatingWebhookConfiguration
VERSION: v1
FIELD: matchPolicy <string>
ENUM:
Equivalent
Exact
DESCRIPTION:
matchPolicy defines how the "rules" list is used to match incoming requests.
Allowed values are "Exact" or "Equivalent".
- Exact: match a request only if it exactly matches a specified rule. For
example, if deployments can be modified via apps/v1, apps/v1beta1, and
extensions/v1beta1, but "rules" only included `apiGroups:["apps"],
apiVersions:["v1"], resources: ["deployments"]`, a request to apps/v1beta1
or extensions/v1beta1 would not be sent to the webhook.
- Equivalent: match a request if modifies a resource listed in rules, even
via another API group or version. For example, if deployments can be
modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and "rules" only
included `apiGroups:["apps"], apiVersions:["v1"], resources:
["deployments"]`, a request to apps/v1beta1 or extensions/v1beta1 would be
converted to apps/v1 and sent to the webhook.
Defaults to "Equivalent"
Possible enum values:
- `"Equivalent"` means requests should be sent to the webhook if they
modify a resource listed in rules via another API group or version.
- `"Exact"` means requests should only be sent to the webhook if they
exactly match a given rule.
If you want to learn more about a specific field, just pass it into kubectl explain!