Deployment with Kubernetes
How to deploy your application using Kubernetes?
This tutorial will introduce you to the technical details of deploying your application to a Kubernetes cluster. You will learn what YAML definitions are and how to prepare them to have your project up and running in your desired environment.
I made an assumption you are already familiar with all of Kubernetes basic concepts and have a cluster available. Otherwise, you may want to read my previous article which will teach you initial elements and simple setup to begin with:
Let’s get started!
Introduction
Objects in the Kubernetes API are abstractions that represent a state of your system: deployed containerized applications and workloads, their associated network and disk resources, and other information about what your cluster does.
From my recent blogpost, you should know that Kubernetes also contains a number of higher-level abstractions called Controllers built upon the basic objects, and provide additional functionality along with convenience features:
Objects are “records of intent” — once you create them, the Kubernetes will constantly work to ensure that these objects exist. By creating an object, you’re effectively telling the Kubernetes what you want your cluster’s workload to look like; this is your cluster’s desired state.
Installation
To work with Kubernetes objects — either to create, modify, or delete them — you’ll need to use the Kubernetes API. When you use the kubectl
command-line interface, for example, the CLI makes the necessary Kubernetes API calls for you.
Using kubectl
, you can inspect cluster resources — create, delete, and update components — look at your new cluster, and bring up example apps.
You will find the detailed installation here:
YAML
When you create an object in Kubernetes, you must provide the object spec that describes its desired state, as well as some basic information about the object (such as a name).
When you use the Kubernetes API to create an object (either directly or via kubectl
), the API request must include that information as JSON in a request body. Most often, you provide the information in a .yaml
file and kubectl
converts the information to JSON when making the API request.
Required Fields
In the .yaml
file for the Kubernetes object you want to create, you’ll need to set values for the following fields:
apiVersion
- which version of the Kubernetes API you’re using to create this object;kind
- what kind of object you want to create;metadata
- data that helps uniquely identify the object, including aname
string and an optionalnamespace
.
You’ll also need to provide the object spec
field. The precise format of the object spec
is different for every Kubernetes object, and contains nested fields specific to that object. The Kubernetes API Reference can help you find the spec format for all of the objects you can create using Kubernetes.
Deployment
A deployment controller lets you manage a set of identical pods, scale, roll out, and roll back versions of your applications. Everyone who runs applications on Kubernetes cluster uses a deployment. Without it, you’d need to create, update, and delete a bunch of pods manually.
For deployment, you declare a single object in a YAML file:
Firstly, have a look at theapiVersion
value. apps/v1
is the most common API group in Kubernetes, with many core objects. It includes functionality related to running applications on Kubernetes like Deployments.
After that, let’s see the spec
contents that describe your desired state for the object and governs its configuration. As you already know, it’s the characteristics you want the object to have.
When you create the Deployment, you might set its spec
to define how many replicas of the application you want to run. The Kubernetes system updates the status to match your spec. Actually, .spec.replicas
is an optional field that defaults to 1.
The selector
field defines how the Deployment finds which Pods to manage. In our case, you simply select a label that is defined in the Pod template (app: api
). .spec.selector.matchLabels
must match .spec.template.metadata.labels
and specify a label selector for the Pods targeted by this deployment.
The .spec.template
has exactly the same schema as a Pod, except it is nested and does not have an apiVersion
or kind
. Deployment uses a Pod template to create the Pods for which it is responsible. The template
field contains the following sub-fields:
- The Pods are labeled as
app: api
using thelabels
field. - The Pod template’s specification (
.template.spec
field) indicates that the Pods run some container based on the given image. - Container is named
example-container
using thename
field. - Port
4444
will be exposed so that the container can accept traffic.
And that’s basically the entire definition of Deployment in its minimal scope.
envsubst
Last but not least, I’d like to explain the “magic” with environmental variables inside a YAML file. You may wonder how exactly it is supposed to work. Let me answer you briefly and explain what the envsubst
command actually is.
The envsubst
program substitutes the values of environment variables. In the normal operation mode, standard input is copied to standard output, with references to environment variables of the form $VARIABLE
or ${VARIABLE}
being replaced with the corresponding values.
Let’s see this in action:
~/Desktop » echo $USER
squixy~/Desktop » echo 'You username is: $USER'
You username is: $USER~/Desktop » echo 'You username is: $USER' | envsubst
You username is: squixy
This is how it works in the simplest form, reading input from the command line and replacing specific forms with your environmental variables. It’s pretty useful but we actually want to use it with .yaml
files. We can do that as well:
~/Desktop » cat k8s.yml
---
apiVersion: apps/v1
kind: Deployment
spec:
replicas: ${NO_REPLICAS}~/Desktop » echo $NO_REPLICAS~/Desktop » export NO_REPLICAS=3
~/Desktop » echo $NO_REPLICAS
3~/Desktop » envsubst < k8s.yml
---
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 3
As you can see, there’s a variable definition inside the YAML file. We substitute it with what we have defined in our environment by redirecting the file contents to the envsubst
command.
Applying the configuration
To finally apply the Kubernetes configuration, you should pipe YAML file definition into variables substitution and pass the result as a file:
~/Desktop » cat k8s.yml | envsubst | kubectl apply -f -
deployment.apps/example-deployment configured
ingress.extensions/example-ingress unchanged
service/example-api unchanged
As your last concern, you may wonder how to automate this process. What I usually do is to invoke the above script in a CI server where all the necessary environment variables are exported. This way I’m able to delegate the entire workflow and provide continuous delivery of the applications I build.
Subscribe to get the latest content immediately
https://tinyletter.com/KamilLelonek
Summary
Hopefully, this article introduced you to Kubernetes configuration definition, deployment, and automation of the entire process quite well.
With the knowledge you have now, you are able to describe your Kubernetes structure and apply it to a cluster. You can have a YAML file which explains your architecture or infrastructure to anyone else.
You should be also already familiar with the basic concepts and practical strategies so you can finally start deploying your applications. Do not hesitate to try that in your team and don’t be afraid of experimenting with any changes.