Profile picture of Liam Moat

Liam Moat

Premier Field Engineer.

Using kubectl to generate Kubernetes YAML

By Liam Moat. . 7 minutes read.

When you get started with Kubernetes, the first thing you will probably do is create a Deployment using the kubectl command-line interface. When you create an object in Kubernetes, including a Deployment, you must provide the object spec that describes its desired state, as well as some basic information about the object (such as a name). Most often, you provide this information using a YAML file. This post will explore how to use kubectl, and commands that you may already be familiar with, to generate this YAML.

First, by way of example, to create a Pod using kubectl you could run the following command:

$ kubectl run my-nginx --image nginx --restart Never

Alternatively, you could write the following YAML in pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
spec:
  containers:
  - image: nginx
    name: my-nginx

And, then run:

$ kubectl apply -f pod.yaml

Both of these approaches are valid and generate exactly the same result in Kubernetes. While kubectl has a certain simplicity about it, using YAML has two key advantages over running commands manually:

  1. You can add YAML files to source control to track changes.
  2. You can create more complex structures with YAML than you can with the command line.

Generate YAML

Can you get the best of both worlds? Yes. You can use --dry-run -o yaml to instruct kubectl to output the equivalent YAML without actually sending the object to Kubernetes.

These two options can be added to many commands in kubectl, including kubectl run and kubectl create.

Generate YAML for a Kubernetes Pod

$ kubectl run my-nginx --image nginx --restart Never --dry-run -o yaml
output

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: my-nginx
  name: my-nginx
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: my-nginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}

Generate YAML for a Kubernetes Deployment

$ kubectl create deployment my-deploy --image nginx --dry-run -o yaml
output

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: my-deploy
  name: my-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-deploy
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-deploy
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

Generate YAML for a Kubernetes Service

$ kubectl expose deployment my-deploy --port 80 --dry-run -o yaml
output

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: my-deploy
  name: my-deploy
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: my-deploy
  type: LoadBalancer
status:
  loadBalancer: {}

Write YAML to a file

Using --dry-run -o yaml you can instruct kubectl to output YAML. You can then use > to redirect the output of the command to a file, in this case, called deployment.yaml.

$ kubectl create deployment my-deploy --image nginx --dry-run -o yaml > deployment.yaml
deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: my-deploy
  name: my-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-deploy
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-deploy
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

Append an object to an existing file

A Kubernetes YAML file can include the definition of multiple objects - each separated by ---. You can use >> to redirect the output of a command to a file, appending the output to the existing contents of the file. For example, you could append a Service to expose my-deploy in deployment.yaml

Note: You will need to run kubectl apply -f deployment.yaml first, else Kubernetes won’t be able to find my-deploy.

$ echo '---' >> deployment.yaml
$ kubectl expose deployment my-deploy --port 80 --dry-run -o yaml >> deployment.yaml
deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: my-deploy
  name: my-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-deploy
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-deploy
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}
---
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: my-deploy
  name: my-deploy
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: my-deploy
status:
  loadBalancer: {}

Summary

Writing Kubernetes objects in YAML can often be a daunting task. Hopefully, with these simple tips and tricks, you will be able to bootstrap more consistent YAML files with ease. The key thing to take away is --dry-run -o yaml.

Do you have any kubectl tips and tricks? If you do, please share them in the comments below!

Recent Posts