This 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.

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.

Leave a Reply