Skip to content

Latest commit

 

History

History
320 lines (298 loc) · 9.67 KB

File metadata and controls

320 lines (298 loc) · 9.67 KB

Learning Kubernetes

Spring Boot App with Kubernetes Deployment

kubernetes

Overview

This project implements JUnit for unit testing (automated tests), swagger for api documentation, docker and kubernetes for deployment.

Kubernetes

Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications. Containers are a good way to bundle and run your applications. In a production environment, you need to manage the containers that run the applications and ensure that there is no downtime. Kubernetes provides you with a framework to run distributed systems resiliently. It takes care of scaling and failover for your application, provides deployment patterns, and more. Kubernetes also provides several features that make deployment easier, including;

  • Automated rollouts and rollbacks
  • Storage orchestration
  • Secret and configuration management
  • Service discovery and load balancing
  • Self-healing
  • Designed for extensibility

Docker

Docker is a software platform that allows you to build, test, and deploy applications quickly. Docker enables an entirely isolated application to be deployed to multiple servers. We need to install Docker Desktop, follow this link to Install Docker Desktop. Why do we need Docker Desktop? Docker Desktop is the easiest way to run Kubernetes on local machine, it gives you a fully certified Kubernetes cluster and manages all the components for you. Kubernetes can be enabled from the Kubernetes settings panel as shown below.

docker desktop

Go to Settings, checking the Enable Kubernetes box and then pressing Apply & Restart triggers the installation of a single-node Kubernetes cluster. To check the kubernetes cluster already installed on your computer, open terminal and run this command:

kubectl cluster-info
kubectl get nodes

Deploy the App with Kubernetes Cluster

Deploy PostgreSQL with Kubernetes

Create postgres-config.yaml (config for PostgreSQL)

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
  labels:
    app: customer-management-db
data:
  POSTGRES_DB: postgres
  POSTGRES_USER: postgresqldb
  POSTGRES_PASSWORD: postgre123

Apply the configuration

kubectl apply -f postgres-config.yaml

result

configmap/postgres-config created

Confirm the configmap

kubectl get configmap

result

NAME               DATA   AGE
kube-root-ca.crt   1      5m7s
postgres-config    3      53s

Create postgres-pvc-pv.yaml (for persistent storage volume and persistent volume claim)

kind: PersistentVolume
apiVersion: v1
metadata:
  name: postgres-pv-volume  # Sets persistent volume's name
  labels:
    type: local  # Sets persistent volume's type to local
    app: postgres
spec:
  storageClassName: manual
  capacity:
    storage: 5Gi # Sets persistent volume
  accessModes:
    - ReadWriteMany
  hostPath:
    path: "/mnt/data"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: postgres-pv-claim  # Sets name of persistent volume
  labels:
    app: customer-management-db
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteMany  # Sets read and write access
  resources:
    requests:
      storage: 5Gi  # Sets volume size

Create and apply persistent storage volume and persistent volume claim

kubectl apply -f postgres-pvc-pv.yaml

result

persistentvolume/postgres-pv-volume created
persistentvolumeclaim/postgres-pv-claim created

Check the pvc is bound

kubectl get pvc

result

NAME                STATUS   VOLUME               CAPACITY   ACCESS MODES   STORAGECLASS   AGE
postgres-pv-claim   Bound    postgres-pv-volume   5Gi        RWX            manual         71s

Create postgres-deployment.yaml (for deployment)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: customer-management-db  # Sets Deployment name
spec:
  replicas: 1
  selector:
    matchLabels:
      app: customer-management-db
  template:
    metadata:
      labels:
        app: customer-management-db
    spec:
      containers:
        - name: customer-management-db
          image: postgres:10.1 # Sets Image
          imagePullPolicy: "IfNotPresent"
          ports:
            - containerPort: 5432  # Exposes container port
          envFrom:
            - configMapRef:
                name: postgres-config
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgres
      volumes:
        - name: postgres
          persistentVolumeClaim:
            claimName: postgres-pv-claim

Check if your deployments and the children objects, such as pods, are created successfully

kubectl apply -f postgres-deployment.yaml

result

deployment.apps/customer-management-db created

Create postgres-service.yaml (for expose ports in various ways)

apiVersion: v1
kind: Service
metadata:
  name: customer-management-db # Sets service name
  labels:
    app: customer-management-db # Labels and Selectors
spec:
  type: NodePort # Sets service type
  ports:
    - port: 5432 # Sets port to run the postgres application
  selector:
    app: customer-management-db

Create and apply ports

kubectl apply -f postgres-service.yaml

result

service/customer-management-db created

Connect to database, modify database (create schema, tabel, insert data)

kubectl exec -it [pod-name] --  psql -h localhost -U admin --password -p 5432 postgresdb

Database Configuration of This Project

Create a new role

database name = postgres
username = postgresqldb
password = postgre123

Run the DDL command to create a new table

CREATE TABLE customer(
nik varchar(20) primary key,
full_name varchar(50),
address varchar(150),
phone_number varchar(12),
account_number varchar(12),
balance numeric,
status varchar(10)
);

Deploy Spring Boot App with Kubernetes

Show list of deployment services, cluster ip and external ip

kubectl get services customer-management-db

result

NAME                     TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
customer-management-db   NodePort   10.107.130.243   <none>        5432:31104/TCP   93s

Change spring.datasource.url into cluster ip of the database on application.properties app-properties

Build .jar file of the project

mvn clean install

Build docker images. We need docker images to deploy with kubernetes cluster.

docker build --tag=customer-management-service:latest .

Create springboot-deploy.yaml (all configuration, images and port to expose)

apiVersion: v1 # Kubernetes API version
kind: Service # Kubernetes resource kind we are creating
metadata: # Metadata of the resource kind we are creating
  name: customer-management-service
spec:
  selector:
    app: customer-management-service
  ports:
    - protocol: "TCP"
      port: 8081 # The port that the service is running on in the cluster
      targetPort: 8081 # The port exposed by the service
  type: LoadBalancer # type of the service. LoadBalancer indicates that our service will be external.
---
apiVersion: apps/v1
kind: Deployment # Kubernetes resource kind we are creating
metadata:
  name: customer-management-service
spec:
  selector:
    matchLabels:
      app: customer-management-service
  replicas: 2 # Number of replicas that will be created for this deployment
  template:
    metadata:
      labels:
        app: customer-management-service
    spec:
      containers:
        - name: customer-management-service
          image: customer-management-service # Image that will be used to containers in the cluster
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8081 # The port that the container is running on in the cluster

Create and apply configuration, deploy the service

kubectl apply -f springboot-deploy.yaml

result

service/customer-management-service created
deployment.apps/customer-management-service created

Show port and pod

kubectl get pod -o wide

result

NAME                                           READY   STATUS              RESTARTS   AGE   IP           NODE             NOMINATED NODE   READINESS GATES
customer-management-db-5bf7fcd76-hgwj7         1/1     Running             0          6m    10.1.0.110   docker-desktop   <none>           <none>
customer-management-service-57cc8d9d59-hr8l7   0/1     ContainerCreating   0          21s   <none>       docker-desktop   <none>           <none>
customer-management-service-57cc8d9d59-xxw7t   0/1     ContainerCreating   0          21s   <none>       docker-desktop   <none>           <none>

Show logs

kubectl logs -f [pod-name]

Rollout deployment and restart

kubectl rollout restart deployment [service-name] -n default

Path URL

http://localhost:8081/

Testing api using Postman hello

API Documentation

http://localhost:8081/swagger-ui.html#/customer-web-controller

screenswagger.png


References :