Introduction
In this Tech Bite we will show you how to deploy services using Kubernetes, a popular tool for the management of containerized applications. For tutorial purposes, two services will be deployed, fe-deploy, and be-deploy (each service is part of one image).
Spinning Pods using Deployment object
The smallest deployable unit in Kubernetes is a Pod, which represents a group of one or more containers. A Pod is usually managed by one more level of abstraction: Deployment, ReplicaSet, StatefulSet, etc. which enable us to scale up/down the desired number of Pods in a cluster (for the purpose of this episode, we will use Deployment Object). Because of the nature of the container, Pods are prone to sudden termination when a service inside of the container encounters an error and unexpectedly stops executing. In that case, Deployment is going to create a new, healthy Pod that replaces an ill, dying one. Below we have defined two Deployment objects, where be-deploy spins and manages three instances while fe-deploy spins and manages only one.
be-deployment.yaml
fe-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: be-deploy
labels:
app: be
spec:
replicas: 3
selector:
matchLabels:
app: be
template:
metadata:
labels:
app: be
spec:
containers:
- name: be
image: be-image
ports:
- containerPort: 8080
apiVersion: apps/v1
kind: Deployment
metadata:
name: fe-deploy
labels:
app: fe
spec:
replicas: 1
selector:
matchLabels:
app: fe
template:
metadata:
labels:
app: fe
spec:
containers:
- name: fe
image: fe-image
ports:
- containerPort: 80
Exposing Pods using Service
Containers can communicate with other containers in the same Pod like they are on the same node, but by default cannot communicate with containers from another Pod. To allow communication between Pods across nodes of Cluster, a Kubernetes Service object is used. In this case, we will use ClusterIP (there are other options too) which make Pods reachable only from inside of the cluster.
be-service.yaml
fe-service.yaml
apiVersion: v1
kind: Service
metadata:
name: be-service
spec:
selector:
app: be
ports:
- protocol: TCP
port: 8080
targetPort: 8080
apiVersion: v1
kind: Service
metadata:
name: fe-service
spec:
selector:
app: fe
ports:
- protocol: TCP
port: 80
targetPort: 80
Accessing our application
After we have started our services and enabled them to communicate with each other, we have to expose our frontend outside of the cluster. For that purpose we can use an Ingress object, which routes incoming HTTP(S) requests to desired service (simple proxy). In order to use the HTTPS protocol, we need a certificate and private key so a secure connection between the user and Ingress can be established. To store sensitive information inside the Kubernetes cluster, we use Secret objects which can encode data using a base64 code scheme or can completely hide it.
fe-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
annotations:
kubernetes.io/ingress.allow-http: false
spec:
tls:
- hosts:
- atlantbh.ba
secretName: secret-tls
rules:
- host: atlantbh.ba
http:
paths:
- path: /ui
backend:
serviceName: fe-service
servicePort: 80
- path: /api
backend:
serviceName: be-service
servicePort: 8080
ingress-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-tls
type: kubernetes.io/tls
data:
tls.crt: base64-encoded-cert
tls.key: base64-encoded-key
Each of the previously defined services can be created using kubectl create -f object-name.yaml and can be deleted using the kubectl delete -f object-name.yamlcommand.
“Deploying applications using Kubernetes” Tech Bite was brought to you by Dario Pejčinović, Junior Software Engineer at Atlantbh.
Tech Bites are tips, tricks, snippets or explanations about various programming technologies and paradigms, which can help engineers with their everyday job.