If you use kubectl to build out your Kubernetes cluster, you are either creating or applying a YAML file called a manifest. Just like shipping manifests have all the information to ensure that a package or set of goods made it from point A to point B, Kubernetes YAML manifests contain all the information necessary to convey or carry your k8s services–such as deployments and pods–into a functioning reality.
While remaining humanly readable, YAML manifests must absolutely be machine-readable and syntactically correct. The proper indentation is critical, as are key words and values. Sure, you can write out your YAML manifests by hand once you've gotten the exact requirements and structure needed for each kind or type of entity being generated. But why not have the Kubernetes API do all that heavy lifting for you?
With just a single kubectl flag, you can both quickly verify that an existing manifest will work in your cluster and produce a syntactically correct new manifest.
Turning the Kubernetes API into your debugger using dry-run
Pop quiz! (You never know when one will show up!) Is the following manifest properly written?
- image: nginx
- containerPort: 8080
Buzzzzzz - time's up. And the answer is: Nope! In fact, there are three errors in the manifest. Now, maybe you spotted the problems right away and maybe you still haven't. Either way, it's a lot faster and more accurate to let the Kubernetes API do the work for you.
The key to turning the Kubernetes API into your debugger is to use the dry-run flag in server mode. Let's say I've cleverly named the above manifest test.yaml. Then, I just SSH into my control plan node and run this kubectl command.
kubectl apply -f test.yaml --dry-run=server
The dry-run flag tells kubectl to run the command as you normally would, but only to validate the file and report the results. In this case, the results returned look like this:
error: error validating "test.yaml": error validating data: [ValidationError(Deployment.metadata): unknown field "label" in io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta, ValidationError(Deployment.spec.selector): unknown field "matchLabel" in io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector, ValidationError(Deployment.spec.template.metadata): unknown field "label" in io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta]; if you choose to ignore these errors, turn validation off with --validate=false
Now, we have our three problems pinpointed. First, the field label in the metadata section is not recognized. Then we have a similar problem with the field matchLabel in the spec:selector section. Finally, we have another unrecognized term label in the template:metadata section. Basically, there are three typos. Even though there is only one value for all of them–app:nginx–each of these singular terms (label and matchLabel) should be plural (labels and matchLabels).
If I make those corrections in the file and rerun the command, kubectl apply -f test.yaml --dry-run=server the Kubernetes API will return this response:
deployment.apps/nginx created (server dry run)
Essentially, the dry-run flag tells the Kubernetes API to go through all the steps of actually creating the deployment, but doesn't store the results even if the manifest is valid.
Cluster magic: kubectl commands to generate a new manifest
You can see that setting the dry-run flag to server allows you to validate and debug an existing manifest. But what if you don't have a manifest yet? Changing that value from server to client (and specifying a couple of other options) will allow you to output syntactically correct YAML and even send it directly to a file.
For example, let's say you want to generate a manifest for a new pod that uses the latest Nginx image and applies the web label. Furthermore, you want it to be in YAML and stored in a file named pspod.yaml.
kubectl run pspod --image=nginx:latest --labels type=web --dry-run=client -o yaml > pspod.yaml
Everything in this command line, until the --dry-run=client option, is designed to pass arguments into the manifest. And voilà! Here's the pspod.yaml file created:
- image: nginx:latest
Whether you need a manifest for a deployment, adding a pod, or even a NodePort service that specifies a custom port, rely on the dry-run flag to provide the precise code blocks, copy and paste into a master file and then run the kubectl command–without the flag–to get your custom Kubernetes cluster up and running in no time.
For more information about the Kubernetes API as well as some hands-on experience, check out my course Hands-On with the Kubernetes API.
5 keys to successful organizational design
How do you create an organization that is nimble, flexible and takes a fresh view of team structure? These are the keys to creating and maintaining a successful business that will last the test of time.Read more
8 ways to stand out in your stand-up meetings
Whether you call them stand-ups, scrums, or morning circles, here's some secrets to standing out and helping everyone get the most out of them.Read more
Technology in 2025: Prepare your workforce
The key to surviving this new industrial revolution is leading it. That requires two key elements of agile businesses: awareness of disruptive technology and a plan to develop talent that can make the most of it.Read more