15
Complete Application Deployment using Kubernetes
In this post, we will be deploying a complete end to end application using Kubernetes. We will see and discuss how the different components of Kubernetes compliment each other and make the application deployment process smooth.
We will be using minikube to deploy our application on our local system. You can refer this link to read more about minikube : https://minikube.sigs.k8s.io/docs/start/
Once you are done with this post, you would be familiar with the below concepts in Kubernetes:
- Creating Deployment using YAML file.
- What is Pod and How to define the pod in YAML config file.
- How to to create internal service and make the pod accessible to other component in the cluster.
- How to create external service and make the pod accessible outside the cluster.
Sample application which we will be deploying on the Kubernetes cluster will be as below. We will deploy mongodb and mongo-express docker image and will access the mongo-express from the browser.
To deploy the above application on Kubernetes we will be following the below steps:
1.First we will create mongodb secret
which will contain the sensitive information such as the mongodb username
and password
in encrypted format.
- Then create
mongodb deployment and service
which will be responsible to create the mongdb pod and exposing the mongodb to the other internal components. - Now we will create
mongodb configmap
to save themongodb url
and other configuration. - Once config map is created and deployed we will create the
mongo-express deployment
file to create the mongo-express pod. - Accessing the application from the browser.
Before implementing the above steps to deploy the mongodb application on Kubernetes, lets revise the few Kubernetes components which will be used in deploying the application in brief.
Pods: Pods are the smallest, most basic deployable
objects in Kubernetes. A Pod represents a single instance of a running process in your cluster. Pods contain one or more containers
, such as Docker containers.
Secrets: Secrets let you store and manage sensitive information
, such as passwords, OAuth tokens, and ssh keys. Storing confidential information in a Secret is safer and more flexible than putting it verbatim in a Pod definition or in a container image
ConfigMap: A ConfigMap is an API object used to store non-confidential data in key-value pairs
. Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume.A ConfigMap allows you to decouple environment-specific configuration from your container images, so that your applications are easily portable.
Deployment: Deployment is a resource object in Kubernetes that provides declarative updates
to applications. A deployment allows you to describe an application’s life cycle, such as which images to use for the app, the number of pods there should be, and the way in which they should be updated.
Services : Service is a logical abstraction
for a deployed group of pods in a cluster (which all perform the same function). Since pods are ephemeral, a service enables a group of pods, which provide specific functions (web services, image processing, etc.) to be assigned a name and unique IP address (clusterIP).
Note: ConfigMap does not provide secrecy or encryption. If the data you want to store are confidential, use a Secret rather than a ConfigMap, or use additional (third party) tools to keep your data private.
Now let’s deploy the complete mongodb application by following the steps discussed above. Architecture of our application with different components will be as below :
As our mongodb application require username and password to access, as username and password are confidential information, so will be creating the secrets to save them. We have username as “username” and password as “password“. We are saving them by encoding in base64.
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
mongo-root-username: dXNlcm5hbWU=
mongo-root-password: cGFzc3dvcmQ=
apiVersion : this is the version of the API used by the cluster.
kind: kind define whether it’s a deployment, secret or configMap.
metadata: here we can define data about the object we are about to create. In this example, we only provide the name of the pod. But you can provide other details like the namespace.
type: type Opaque means that from kubernetes’s point of view the contents of this Secret is unstructured, it can contain arbitrary key-value pairs.
data : data contains the data, you want to save as secrets.
Deploy the secret config file via kubectl apply -f mongo-secret.yaml
.
Now we will create the mongo deployment to create the mongodb pod, mongo db deployment will be fetching the mongodb username and password from the mongo secrets created in Step1.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
labels:
app: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
---
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
spec:
selector:
app: mongodb
ports:
- protocol: TCP
port: 27017
targetPort: 27017
In the above yaml file we have defined two things :
1.Deployment – responsible to create the pod and replicaset of the pod.(here we are creating only one replica).
2.Service – to expose the pod to the internal component.
Now Let’s see the each field in deployment in the more details:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
labels:
app: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
apiVersion : this is the version of the API used by the cluster.
kind: kind define whether it’s a deployment, secret or configMap.
metadata: here we can define data about the object we are about to create. In this example, we only provide the name of the pod. But you can provide other details like the namespace.
spec: in the deployment kind file, we have spectification which is responsible for defining the replica, selector and container template.
replicas : define the number of pod to be created for this container.
selector: inside selector we define the matching Label.
template: template is the actual blue print of the container and pod that will be created.
template.metadata : contains the information about pod like label etc.
template.spec: blueprint for the container that needs to be created.
containers : define the different pod to be created.
name: name of container.
image: docker image that will be pulled from docker hub.
ports: on which this container will be accessible.
env : container the environment variables like mongodb username and password in our case.
Note: Secrets needs to be created first before the applying the deployment as they are being used in the deployment as environment variable.
Let’s see the service in more detail now:
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
spec:
selector:
app: mongodb
ports:
- protocol: TCP
port: 27017
targetPort: 27017
Service yaml has the similar fields as in the deployment, only targetPort field is different, targetPort
is the port on which other component can access this pod.
Now we will create the configMap which will contain the mongodb url.
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-configmap
data:
database_url: mongodb-service
ConfigMap file is almost similar to the other yaml file.
Step 4: Create the mongo-express deployment and external service to create the mongo-express pod and expose it to the outside of cluster.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-express
labels:
app: mongo-express
spec:
replicas: 1
selector:
matchLabels:
app: mongo-express
template:
metadata:
labels:
app: mongo-express
spec:
containers:
- name: mongo-express
image: mongo-express
ports:
- containerPort: 8081
env:
- name: ME_CONFIG_MONGODB_ADMINUSERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: ME_CONFIG_MONGODB_ADMINPASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
- name: ME_CONFIG_MONGODB_SERVER
valueFrom:
configMapKeyRef:
name: mongodb-configmap
key: database_url
---
apiVersion: v1
kind: Service
metadata:
name: mongo-express-service
spec:
selector:
app: mongo-express
type: LoadBalancer
ports:
- protocol: TCP
port: 8081
targetPort: 8081
nodePort: 30000
mongo-express deployment config is similar to the mongodb deployment config so we will not discuss that here.
We will discuss few of the extra field that we have in the mongo-express external service below:
apiVersion: v1
kind: Service
metadata:
name: mongo-express-service
spec:
selector:
app: mongo-express
type: LoadBalancer
ports:
- protocol: TCP
port: 8081
targetPort: 8081
nodePort: 30000
This service file contains 2 fields extra (type, nodePort )as compared to the service file of mongodb.
type: LoadBalancer : makes the service external by assigning the service external ip address.
nodePort: port on which this pod can be accessed outside the cluster.
To access the mongo-express from the browser, we would need to find the IP ADDRESS of the service assigned by the kubernetes.
We will first verify if the service is created and will fetch the service name by the following command
kubectl get service
As we can see our external service with the name mongo-express-service and internal service mongodb-service both have been created.
Now we will run our external service to get the url created for the service to be accessible by using below command.
minikube service mongo-express-service
Now copy paste the url in browser and check whether application is accessible.
We can see that we are able to access the application in our browser on port 30000 as given in the external service yaml file.
So in this way we deployed a complete end to end mongo db application on kubernetes and access it through our browser. We created a mongodb pod and made it accessible to the other component by internal service. We also created one pod for mongo-express to make changes to mongodb and created an external service to make it accessible outside the cluster or external source.
This is all from this Post, if you have any question or find anything wrong, then please comment below.
This post was first published on my personal blog. If you find this blog content relevant, you can visit my blog for similar kind of content: https://ishantgaurav.in/
15