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:
- You can add YAML files to source control to track changes.
- 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.
--dry-run
- If true, only print the object that would be sent, without sending it.-o yaml
- Sets the output format to YAML.
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
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
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
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
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
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
.