In this RX-M Cloud Native Short Take, Christian Lacsina explores how to migrate a standalone Kubernetes Pod spec to a Kubernetes Deployment. A Pod is the smallest deployable unit in Kubernetes that represents a single instance of a running process in a cluster. However, managing the lifecycle of multiple Pods can be challenging. This is where Controllers come in, and one of the most commonly used Controllers is the Deployment, which maintains a specified number of replicas of a Pod.
Video Transcript
Welcome to the latest RX-M cloud native short take, I’m Christian Lacsina and today we’re going to look at how we would migrate a standalone Kubernetes Pod spec into a Kubernetes Deployment. First we will look at a standalone pod specification. We can see that I have a pod that has a few extra keys to it:
apiVersion: v1
kind: Pod
metadata:
labels:
app: webserver
name: webserver
spec:
containers:
- env:
- name: ROLE
value: webserver
- name: TIER
value: "1"
image: nginx
name: nginx
volumeMounts:
- name: restart-cache
mountPath: /var/www/html
volumes:
- name: restart-cache
emptyDir: {}
If I were to do something such as apply this pod to the cluster–now it’s entirely up to me to ensure that I have enough copies of my pod. So what if I wanted to automate the life cycle management of that pod? I actually have that option as a user to do so using a concept in Kubernetes called a controller. For pods, the controller of choice for me would be the Deployment. Deployments are a type of Kubernetes controller that maintain a number of replicas of a specified pod.
Let’s go ahead and migrate that pod specification that we took a look at into a Deployment specification. First off what i’m going to do is use kubectl to create a Deployment yaml for me. I’m going to output this Deployment spec into yaml and ensure that kubectl returns a yaml spec for me to consume using a client-side dry run (--dry-run=client). Then I will pipe this all into a file called webserver-d.yaml with this command: kubectl create deploy webserver-deploy --image nginx -o yaml --dry-run=client > webserver-d.yaml.
What i’m going to do is take my pod specification from the metadata: onward and I’m going to copy that and place my pod specification inside this Deployment yaml under this key in the Deployment specification called template. My next task will then be to make sure that the pod specification is properly indented under this so i’ll go take a few seconds here and space all these correctly so it looks like this:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: webserver-deploy
name: webserver-deploy
spec:
replicas: 1
selector:
matchLabels:
app: webserver-deploy
strategy: {}
template:
metadata:
labels:
app: webserver
name: webserver
spec:
containers:
- env:
- name: ROLE
value: webserver
- name: TIER
value: "1"
image: nginx
name: nginx
volumeMounts:
- name: restart-cache
mountPath: /var/www/html
volumes:
- name: restart-cache
emptyDir: {}
One thing that I should check: the Deployment selector is what the deployment will use to identify what pods it is meant to manage. In this case the Deployment selector is currently webserver-deploy and my pods only have the label of webserver so I have to make sure that these two values are in alignment:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: webserver-deploy
name: webserver-deploy
spec:
replicas: 1
selector:
matchLabels:
app: webserver-deploy # at least one pod label should match this key/value pair
strategy: {}
template:
metadata:
labels:
app: webserver-deploy # changed to match the selector
name: webserver
spec:
containers:
- env:
- name: ROLE
value: webserver
- name: TIER
value: "1"
image: nginx
name: nginx
volumeMounts:
- name: restart-cache
mountPath: /var/www/html
volumes:
- name: restart-cache
emptyDir: {}
Let’s go ahead and apply this to the cluster!
Once it’s up and running, let’s go ahead and delete that Deployment-based pod. We’ll do kubectl delete pod and then we’ll select the pod by its name. Is my application broken?
No it’s not! The Deployment is responsible for maintaining the desired state and in this case I want my Deployment to maintain at least one copy of my pod.
In addition to maintaining counts of pods, Deployments can also perform low- to zero-downtime updates to those pods by gradually replacing pods with new pods bearing any changes that i might want. So, if i added labels to these pods, which i’ll go ahead and do using kubectl edit. I’m just going to put in a label of label=test and save this spec. What’s going to happen is my Deployment will automatically terminate the old version of the pod and then create a new version of the pod with my changes.
So all in all, Deployments relieve the burden of adding, replacing, or deleting pods from the user so I can focus on other things like defining my pods in a more specific manner or perhaps further developing the application that is running in my pods.
You can learn about creating Deployments and migrating specifications between resources from RX-M by building your own custom Kubernetes course that includes exercises like what I’ve shown here. Go to the custom course builder under the Training menu to get started.
That’s our Cloud Native Short Take on migrating from standalone pod specs to a deployment!