Spring Boot Kubernetes Helm Charts Sinhala Tutorial | Advanced Deployment Guide

Spring Boot Kubernetes Helm Charts Sinhala Tutorial | Advanced Deployment Guide

ආයුබෝවන් යාළුවෝ! 🙋‍♂️ අද අපි කතා කරන්න යන්නේ නූතන Software Engineering ලෝකයේ ප්‍රබලම සංකල්ප දෙකක් වන Spring Boot සහ Kubernetes එකට පාවිච්චි කරලා, අපේ applications තවත් advanced විදියට deploy කරන්නේ කොහොමද කියලා. ඔයාලා දැනටමත් Spring Boot එක්ක වැඩ කරලා ඇති, Kubernetes ගැනත් යම් අවබෝධයක් ඇති. හැබැයි මේ දෙක එකට ගලපලා production-ready solution එකක් හදන එක ටිකක් අභියෝගාත්මකයි. ඒ අභියෝගය ජයගන්න අපිට උදව් වෙන Tools දෙකක් තමයි Helm Charts සහ Kubernetes Operators.

මේ Guide එකෙන් අපි බලමු Helm Charts කියන්නේ මොනවද, ඒවා අපේ Spring Boot applications Kubernetes වලට deploy කරන්න කොහොමද පාවිච්චි කරන්නේ කියලා. ඒ වගේම Kubernetes Operators ගැනත් පොඩි හැඳින්වීමක් කරනවා. එහෙනම්, අපි පටන් ගමු!

Kubernetes සහ Spring Boot: ඇයි මේ ගැටලුව?

අපේ Spring Boot application එකක් Kubernetes cluster එකක දාන්න (deploy කරන්න) ඕන වුණාම, නිකම්ම java -jar කියලා run කරන්න බැහැනේ. අපිට Kubernetes වලට තේරෙන විදියට YAML files ගොඩක් ලියන්න වෙනවා:

  • Deployment එකක්, අපේ application එකේ instances (pods) manage කරන්න.
  • Service එකක්, ඒ pods වලට traffic යොමු කරන්න.
  • ConfigMap එකක්, application එකේ configuration එක (e.g., database URLs, external service endpoints) manage කරන්න.
  • Secret එකක්, sensitive data (passwords, API keys) ආරක්ෂිතව තියාගන්න.
  • සමහරවිට Ingress එකක්, external access දෙන්න.

මේ හැම දේටම separate YAML files ලියන එක හරි වෙහෙසකර වැඩක්. Application එක update කරන්න, version කරන්න, නැත්නම් වෙන environment එකක deploy කරන්න ගියාම, මේ හැම YAML file එකක්ම manually edit කරන්න වෙනවා. හිතන්න, Microservices ගොඩක් තියෙන project එකක් ගැන! 🤯 ඒක තමයි මේ ගැටලුව.

Helm කියන්නේ මොකක්ද?

මේ වගේ අවුලක් නැති කරගන්න තමයි Helm කියන Tool එක ආවේ. සරලවම කිව්වොත්, Helm කියන්නේ Kubernetes සඳහා වන 'package manager' එකක්. හරියට Windows වලට Chocolatey, macOS වලට Homebrew, Linux වලට apt/yum වගේ.

Helm පාවිච්චි කරලා අපි අපේ applications (ඒවට අදාළ Kubernetes resources ටිකත් එක්ක) 'Helm Chart' කියන එකක් විදියට package කරනවා. මේ Chart එක ඇතුළේ තියෙනවා:

  • Templates: Kubernetes resources (Deployment, Service, ConfigMap, etc.) සඳහා වන YAML files. මේවා plain YAML නෙවෙයි, Go template syntax පාවිච්චි කරලා variables දාන්න පුළුවන්.
  • Values: මේ templates වලට අවශ්‍ය වෙන configuration values (e.g., image name, port, replicas) තියාගන්න වෙනම YAML file එකක් (values.yaml).
  • Chart.yaml: Chart එක ගැන විස්තර (name, version, description) තියෙන file එක.

Helm පාවිච්චි කිරීමේ වාසි:

  • සරල Deployment: එක command එකකින් application එකේ හැම component එකක්ම deploy කරන්න පුළුවන්.
  • Versioning: Chart versions පාවිච්චි කරලා application එකේ different releases manage කරන්න පුළුවන්.
  • Rollback: අලුත් version එකක ප්‍රශ්නයක් ආවොත්, කලින් හොඳින් වැඩ කරපු version එකකට ක්ෂණිකව ආපහු යන්න පුළුවන්.
  • Reusability: එක Chart එකක්, වෙනස් values.yaml files පාවිච්චි කරලා, different environments (dev, staging, prod) වල deploy කරන්න පුළුවන්.

දැන් අපි බලමු මේක ප්‍රායෝගිකව කරන්නේ කොහොමද කියලා.

Helm Chart එකක් Spring Boot App එකකට හදමු

අපි පොඩි Spring Boot REST API එකක් හදලා, ඒක Dockerize කරලා, ඊට පස්සේ Helm Chart එකකින් deploy කරමු.

පියවර 1: සරල Spring Boot Application එකක්

මුලින්ම, start.spring.io එකෙන් simple Spring Boot project එකක් හදමු. web dependency එක විතරක් ඇති. HelloController.java එකක් හදලා මේ වගේ code එකක් දාමු:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @GetMapping("/")
    public String hello() {
        return "Hello from Spring Boot on Kubernetes! Ayubowan!";
    }
}

application.properties එකට server.port=8080 කියලා දාන්න.

පියවර 2: Application එක Dockerize කරමු

Project root එකේ Dockerfile එකක් හදමු:

FROM openjdk:17-jdk-slim
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

mvn clean package කරලා .jar file එක හදාගන්න. ඊට පස්සේ Docker image එක build කරමු:

docker build -t your-docker-hub-username/my-spring-boot-app:1.0.0 .
docker push your-docker-hub-username/my-spring-boot-app:1.0.0

(ඔබේ your-docker-hub-username එක වෙනස් කරන්න. Docker Hub එකට push කරන්න ඕන public access තියෙනවා නම්.)

පියවර 3: Helm Chart එකක් හදමු

දැන් අපි Helm Chart එක හදමු. Terminal එකේ මේ command එක දෙන්න:

helm create my-spring-app-chart

මේකෙන් my-spring-app-chart කියලා directory එකක් හැදෙනවා. ඒක ඇතුළේ මේ වගේ structure එකක් තියෙනවා:

my-spring-app-chart/
├── Chart.yaml
├── charts/
├── templates/
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   └── tests/
│       └── test-connection.yaml
└── values.yaml

අපිට අවශ්‍ය වෙන modifications ටික කරමු:

my-spring-app-chart/values.yaml

මෙහි image සහ service කොටස් අපේ application එකට ගැලපෙන විදියට වෙනස් කරමු. your-docker-hub-username වෙනස් කරන්න අමතක කරන්න එපා.

# default values.yaml content
replicaCount: 1

image:
  repository: your-docker-hub-username/my-spring-boot-app # Make sure to change this!
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "1.0.0" # Make sure to change this to your image tag!

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""

podAnnotations: {}
podSecurityContext: {}
  # fsGroup: 2000

securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000

service:
  type: ClusterIP
  port: 80 # External port for the service
  targetPort: 8080 # Internal port of the Spring Boot application

ingress:
  enabled: false # We'll keep ingress disabled for now for simplicity
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-secret: chart-example-tls
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}

my-spring-app-chart/templates/deployment.yaml

මෙහි spec.template.spec.containers යටතේ image එක, containerPort එක සහ env variables අපේ Spring Boot application එකට ගැලපෙන්න වෙනස් කරමු. containerPort එක 8080 විය යුතුයි. image එක values.yaml එකේ අපි දීපු image.repository:tag එකෙන් ගන්නවා.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-spring-app-chart.fullname" . }}
  labels:
    {{- include "my-spring-app-chart.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "my-spring-app-chart.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        {{- include "my-spring-app-chart.selectorLabels" . | nindent 8 }}
    spec:
      {{- if .Values.serviceAccount.create }}
      serviceAccountName: {{ include "my-spring-app-chart.serviceAccountName" . }}
      {{- end }}
      securityContext:
        {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 8080 # Spring Boot default port
              protocol: TCP
          # livenessProbe:
          #   httpGet:
          #     path: /actuator/health # If you use Spring Boot Actuator
          #     port: http
          # readinessProbe:
          #   httpGet:
          #     path: /actuator/health
          #     port: http
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}

my-spring-app-chart/templates/service.yaml

මෙහි spec.ports යටතේ targetPort එක http (containerPort: 8080) ලෙසත්, port එක 80 (service එක external traffic වලට expose කරන port එක) ලෙසත් සකසමු.

apiVersion: v1
kind: Service
metadata:
  name: {{ include "my-spring-app-chart.fullname" . }}
  labels:
    {{- include "my-spring-app-chart.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http # This refers to the named port 'http' in the Deployment container (8080)
      protocol: TCP
      name: http
  selector:
    {{- include "my-spring-app-chart.selectorLabels" . | nindent 4 }}

දැන් අපේ Helm Chart එක deploy කරන්න සූදානම්!

Helm Chart එක Deploy කරමු

ඔයාගේ Kubernetes cluster එක (local Minikube එකක් හරි, cloud එකේ cluster එකක් හරි) ready කරගෙන මේ steps follow කරන්න.

1. Deploy කිරීම:

my-spring-app-chart directory එක තියෙන තැනට ගිහින් මේ command එක දෙන්න:

helm install my-spring-boot-release ./my-spring-app-chart

my-spring-boot-release කියන්නේ මේ deployment එකට අපි දෙන නම (release name).

2. Deployment එක Verify කිරීම:

Deployment එක හරිද කියලා බලන්න:

kubectl get pods
kubectl get svc

my-spring-boot-release-my-spring-app-chart වගේ pod එකක් Running තත්වයේ තියෙන්න ඕන. Service එකත් ClusterIP එකක් විදියට හැදිලා ඇති.

3. Application එක Access කිරීම:

kubectl get svc command එකෙන් ලැබෙන CLUSTER-IP එකට curl request එකක් යවලා බලන්න:

curl http://<CLUSTER-IP>

ඔයාට "Hello from Spring Boot on Kubernetes! Ayubowan!" කියලා message එක ලැබෙන්න ඕන. (Minikube නම්, minikube service my-spring-boot-release-my-spring-app-chart --url කියලා command එක දීලා URL එක ගන්න පුළුවන්).

4. Update කිරීම (Optional):

values.yaml එකේ replicaCount එක 3ට වෙනස් කරලා, release එක update කරන්න පුළුවන්:

helm upgrade my-spring-boot-release ./my-spring-app-chart

දැන් kubectl get pods බැලුවොත් pods 3ක් තියෙනවා දකින්න පුළුවන්.

5. Uninstall කිරීම:

Deployment එක සම්පූර්ණයෙන්ම cluster එකෙන් අයින් කරන්න:

helm uninstall my-spring-boot-release

දැන් ඔයාලට තේරෙනවා ඇති Helm කොච්චර ප්‍රයෝජනවත්ද කියලා, නේද? 👍

Kubernetes Operators: කෙටි හැඳින්වීමක්

Helm charts අපිට applications deploy කරන්න උදව් වුණාට, ඒවා run වෙනකොට වෙනත් operational tasks (e.g., database backups, scaling based on metrics, failover management) handle කරන්න Operators කියන concept එක තමයි පාවිච්චි කරන්නේ.

Kubernetes Operator කියන්නේ මොකක්ද?

සරලවම කිව්වොත්, Operator එකක් කියන්නේ, අපිට ඕන විදියට Kubernetes platform එක extend කරන software එකක්. මේවා "human operational knowledge" Kubernetes system එකටම add කරනවා වගේ වැඩක්. සාමාන්‍යයෙන්, Operators හදලා තියෙන්නේ domain-specific applications (e.g., Prometheus Operator, Kafka Operator, PostgreSQL Operator) manage කරන්න.

Helm Charts සහ Operators අතර වෙනස:

  • Helm: Application එකක් deploy කිරීමේ සහ configuration කිරීමේ "packaging tool" එකක්. Static state එකක් deploy කරනවා.
  • Operator: Application එකේ සම්පූර්ණ lifecycle එකම manage කරන "software controller" එකක්. Application එකේ current state එක desired state එකට ගේන්න continuous monitoring සහ actions කරනවා.

Spring Boot applications සඳහාත් Operators (e.g., Spring Cloud Kubernetes, Kube-Spring-Boot project) තියෙනවා. ඒවායින් Spring Boot app එකක lifecycle එක Kubernetes native විදියට manage කරන්න පුළුවන්. හැබැයි මේක Helm වලට වඩා advanced level එකක්, ඒ ගැන වෙනම article එකකින් කතා කරමු!

නිගමනය

අද අපි Spring Boot applications Kubernetes වලට deploy කරන්න Helm Charts පාවිච්චි කරන හැටි විස්තරාත්මකව ඉගෙන ගත්තා. මේකෙන් අපේ Deployment process එක කොච්චර සරල වෙනවද කියලා ඔයාලට තේරෙන්න ඇති. ඒ වගේම Kubernetes Operators ගැනත් පොඩි අදහසක් ලබා ගත්තා.

Helm කියන්නේ production environment වලදී අනිවාර්යයෙන්ම පාවිච්චි කරන්න ඕන Tool එකක්. ඔයාලගේ ඊලඟ Spring Boot project එකේදී මේ Helm Charts අනිවාර්යයෙන්ම deploy කරලා බලන්න. මොනවා හරි ප්‍රශ්න තියෙනවා නම්, පහළින් comment එකක් දාන්න! 💬 මේ වගේ Software Engineering concepts ගැන තව දැනගන්න කැමති නම්, අපිත් එක්ක එකතු වෙලා ඉන්න!