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 NeverAlternatively, you could write the following YAML in pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: my-nginx
spec:
containers:
- image: nginx
name: my-nginxAnd, then run:
$ kubectl apply -f pod.yamlBoth 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 yamloutput
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 yamloutput
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 yamloutput
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.yamldeployment.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.yamldeployment.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.