Spring Boot Istio Traffic Management Sinhala | Service Mesh Tutorial

Spring Boot Istio Traffic Management Sinhala | Service Mesh Tutorial

Spring Boot සමඟ Istio: Traffic Management | Sinhala Guide

Microservices වල ලෝකයේ අපි හැමෝම දන්නවා, applications පොඩි පොඩි කෑලි වලට කඩලා වැඩ කරන එක කොච්චර වටිනවද කියලා. මේකෙන් අපිට scalable, maintain කරන්න පහසු applications හදන්න පුළුවන්. හැබැයි මේ පොඩි කෑලි (services) ගොඩක් තිබ්බම ඒවා manage කරන එක, traffic යවන එක, security බලාගන්න එක එච්චර ලේසි නෑ, නේද? සමහර වෙලාවට ඔලුව අවුල් වෙනවා. 🤯

මෙතනට තමයි Service Mesh වගේ concepts එන්නේ. Service Mesh එකක් කියන්නේ, ඔබේ microservices අතර තියෙන communication manage කරන්න, control කරන්න සහ monitor කරන්න උදව් කරන infrastructure layer එකක්. ඒ වගේම Istio කියන්නේ මේ Service Mesh implementations අතරින් ගොඩක්ම ජනප්‍රිය, powerful එකක්. මේක Kubernetes environments වලදී තමයි ගොඩක්ම පාවිච්චි කරන්නේ.

අද අපි මේ tutorial එකෙන් බලමු, Spring Boot application එකක් Istio Service Mesh එකක් එක්ක කොහොමද traffic management කරන්න පුළුවන් කියලා. විශේෂයෙන්ම, අපි බලමු Istio use කරලා traffic routing, canary deployments වගේ දේවල් කොහොමද කරන්නේ කියලා. Microservices develop කරන ඔයාලට මේක ගොඩක් වැදගත් වෙයි කියලා මට විශ්වාසයි! එහෙනම් වැඩේට බහිමු.

Service Mesh සහ Istio කියන්නේ මොකක්ද? 🤔

සරලවම කිව්වොත්, Service Mesh එකක් කියන්නේ ඔබේ application logic එකෙන් communication logic එක වෙන් කරන ක්‍රමයක්. ඒ කියන්නේ, retry logic, timeouts, circuit breakers, load balancing, traffic routing, security (mTLS) වගේ දේවල් ඔබේ application code එකට ලියනවා වෙනුවට, Service Mesh එකට බාර දෙනවා. මේක කරන්නේ Sidecar Proxy pattern එකෙන්. ඔබේ microservice එක deploy කරනකොටම, ඒකත් එක්ක පොඩි proxy එකක් (Envoy proxy වගේ) deploy වෙනවා. මේ proxy එක හරහා තමයි ඔබේ service එකේ හැම communication එකක්ම යන්නේ. මේ Sidecar proxies ටික තමයි Data Plane එක හදන්නේ.

මේ proxies ටික control කරන්නේ Control Plane එකකින්. Istio වල මේ Control Plane එක හදලා තියෙන්නේ Pilot, Citadel, Galley වගේ components වලින්. මේ Control Plane එකෙන් තමයි අපි දෙන configuration rules (traffic rules, security rules) Data Plane එකට යවන්නේ.

Istio වල ප්‍රධාන වාසි:

  • Traffic Management: Requests යවන විදිය control කරන්න පුළුවන් (load balancing, canary deployments, A/B testing).
  • Observability: Services අතර යන එන requests ගැන detailed metrics, logs, traces ලබා දෙනවා.
  • Security: Service-to-service communication encrypt කරන්න (mTLS), access policies enforce කරන්න පුළුවන්.

අද අපි focus කරන්නේ Traffic Management පැත්තට.

Spring Boot Application එකක් Istio සමඟ සකසමු 🚀

මුලින්ම අපි සරල Spring Boot REST API එකක් හදාගමු. මේකෙන් අපි `v1` සහ `v2` වගේ versions පෙන්නන්න පුදලු පුළුවන් වෙන විදියට හදමු, මොකද අපිට traffic management කරන්න versions දෙකක් ඕනේ වෙනවා.

1. Spring Boot Project එක හදමු

අපි මේක hello-service කියලා හඳුන්වමු. pom.xml එකට spring-boot-starter-web dependency එක add කරන්න.

HelloController.java:

package com.example.istio.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        // APP_VERSION environment variable එකෙන් service version එක ගන්නවා
        String version = System.getenv().getOrDefault("APP_VERSION", "v1");
        return "Hello from Spring Boot Service " + version + "!";
    }
}

මේ application එක build කරන්න (mvn clean package) සහ Docker image එකක් හදන්න. Dockerfile එකක් මෙහෙම ලියන්න පුළුවන්:

Dockerfile:

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

Image එක build කරලා ඔබේ Docker registry එකට push කරන්න. (උදා: docker build -t your-docker-repo/hello-service:v1 ., docker push your-docker-repo/hello-service:v1)

2. Kubernetes වල deploy කරමු (Istio Injection සමඟ)

ඔබේ Kubernetes cluster එකේ Istio install කරලා තියෙන්න ඕනේ. (ඒ ගැන අද අපි කතා කරන්නේ නෑ, නමුත් Istio documentation එක බලන්න).

අපිට Istio Sidecar එක automate deploy වෙන්න නම්, අපි deploy කරන namespace එකට Istio injection enable කරන්න ඕනේ. මේක කරන්නේ මේ විදියට:

kubectl label namespace default istio-injection=enabled

(මෙහි default වෙනුවට ඔබගේ namespace එක දෙන්න.)

දැන් අපි v1 version එක deploy කරමු. hello-service-v1.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-service-v1
  labels:
    app: hello-service
    version: v1 # Istio Traffic Management වලට මේ 'version' label එක ගොඩක් වැදගත්
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-service
  template:
    metadata:
      labels:
        app: hello-service
        version: v1
    spec:
      containers:
      - name: hello-service
        image: your-docker-repo/hello-service:v1 # ඔබේ image නාමය මෙහි දෙන්න
        ports:
        - containerPort: 8080
        env:
        - name: APP_VERSION
          value: v1
---
apiVersion: v1
kind: Service
metadata:
  name: hello-service
  labels:
    app: hello-service
spec:
  ports:
  - port: 80
    targetPort: 8080
    name: http
  selector:
    app: hello-service

මේක deploy කරන්න:

kubectl apply -f hello-service-v1.yaml

දැන් ඔබේ hello-service-v1 deployment එකත් එක්ක Envoy proxy එකක් deploy වෙලා ඇති (kubectl get pods බැලුවම container දෙකක් පෙනෙයි). hello-service කියන Kubernetes Service එක හරහා අපිට මේකට access කරන්න පුළුවන්.

Istio Traffic Management: ප්‍රධාන Concepts 🚦

Istio වලින් traffic management කරන්න අපි ප්‍රධාන Kubernetes Custom Resources තුනක් පාවිච්චි කරනවා:

DestinationRule: VirtualService එකෙන් traffic යවන්න ඕන service එක මොකක්ද කියලා කිව්වට, ඒ service එකේ මොන version එකටද යවන්නේ කියලා කියන්නේ DestinationRule එකෙන්. මේකෙන් service එකේ subsets (versions) define කරන්න පුළුවන්. ඒ වගේම load balancing policy, connection pool settings වගේ දේවලුත් define කරන්න පුළුවන්.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: hello-service # VirtualService එකේ destination.host එකට ගැලපෙන්න ඕනේ
spec:
  host: hello-service
  subsets:
  - name: v1
    labels:
      version: v1 # මේක අපේ Deployment එකේ version label එකට ගැලපෙන්න ඕනේ
  - name: v2
    labels:
      version: v2 # V2 deployment එකට පස්සේ add කරනවා

VirtualService: මේක තමයි traffic routing rules define කරන්නේ. මේකෙන් අපිට request එකක headers, paths, query parameters වගේ දේවල් බලලා service එකේ මොන version එකටද යවන්න ඕනෙ කියලා කියන්න පුළුවන්. Canary deployments, A/B testing වලට මේක අත්‍යවශ්‍යයි.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: hello-virtualservice
spec:
  hosts:
  - "*" # Gateway එකේ hosts එකට ගැලපෙන්න ඕනේ
  gateways:
  - hello-gateway # අපි කලින් හදපු Gateway එකට attach කරනවා
  http:
  - match:
    - uri:
        prefix: /hello # /hello path එකට එන requests වලට මේ rule එක apply වෙනවා
    route:
    - destination:
        host: hello-service # අපේ Kubernetes Service එකේ නම
        port:
          number: 80 # Service එක expose කරන port එක

Gateway: මේකෙන් කරන්නේ external traffic ඔබේ Service Mesh එකට ඇතුල් වෙන්න දොරටුවක් හදන එක. මේක Istio Ingress Gateway එකට attach වෙනවා.

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: hello-gateway
spec:
  selector:
    istio: ingressgateway # Istio default ingress gateway එක පාවිච්චි කරනවා
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*" # මේකෙන් කියන්නේ ඕනෑම host එකකින් එන traffic භාර ගන්න කියලා. ඔබේ domain එකක් තියෙනවා නම් ඒක මෙතන දෙන්න පුbr>

මුලින්ම Gateway සහ VirtualService (hello-gateway-vs.yaml) deploy කරලා අපේ v1 service එකට external access දෙමු:

kubectl apply -f hello-gateway-vs.yaml

දැන් Istio Ingress Gateway එකේ IP එක හොයාගෙන request එකක් ගහලා බලන්න පුguluwan.

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')

curl -s -H "Host: my.example.com" "http://$INGRESS_HOST:$INGRESS_PORT/hello"

ඔබට Hello from Spring Boot Service v1! කියලා response එකක් එන්න ඕනේ.

Traffic Management: A/B Testing (Canary Deployment) 🧪

දැන් අපි බලමු කොහොමද අපේ service එකේ අලුත් v2 version එකක් එළියට දාලා, ඒකට පොඩි traffic percentage එකක් යවලා test කරන්නේ කියලා. මේකට කියන්නේ Canary Deployment එකක් නැත්නම් A/B Testing එකක් කියලා.

1. V2 Deployment එක හදමු

අපි අලුත් Docker image එකක් build කරලා push කරමු. (your-docker-repo/hello-service:v2)

දැන් v2 deployment එක deploy කරමු. hello-service-v2.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-service-v2
  labels:
    app: hello-service
    version: v2 # මේක V2 බවට වෙනස් කරලා තියෙන්නේ
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-service
  template:
    metadata:
      labels:
        app: hello-service
        version: v2 # මෙතනත් වෙනස් කරලා තියෙනවා
    spec:
      containers:
      - name: hello-service
        image: your-docker-repo/hello-service:v2 # V2 image එක මෙතන දෙන්න
        ports:
        - containerPort: 8080
        env:
        - name: APP_VERSION
          value: v2 # Environment variable එකත් V2

deploy කරන්න:

kubectl apply -f hello-service-v2.yaml

2. DestinationRule එක update කරමු

දැන් අපේ hello-service එකේ v1 සහ v2 subsets දෙකම තියෙනවා කියලා Istio ට කියන්න ඕනේ. ඒකට කලින් අපි හදපු DestinationRule එක update කරමු. (hello-destination-rule.yaml)

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: hello-service
spec:
  host: hello-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

apply කරන්න:

kubectl apply -f hello-destination-rule.yaml

3. VirtualService එක update කරමු (Traffic Splitting)

දැන් තමයි traffic split කරන magic එක. අපි VirtualService එක update කරලා කියමු, 90% ක් v1 එකටත්, 10% ක් v2 එකටත් යවන්න කියලා. (hello-virtual-service-split.yaml)

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: hello-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - hello-gateway
  http:
  - match:
    - uri:
        prefix: /hello
    route:
    - destination:
        host: hello-service
        subset: v1 # v1 subset එකට යවන්න
      weight: 90 # 90% traffic
    - destination:
        host: hello-service
        subset: v2 # v2 subset එකට යවන්න
      weight: 10 # 10% traffic

apply කරන්න:

kubectl apply -f hello-virtual-service-split.yaml

දැන් බලන්න, Istio එකේ බලය! 🎉

4. Traffic Split එක verify කරමු

දැන් අපි කලින් වගේම Ingress Gateway එක හරහා requests කිහිපයක් යවලා බලමු.

for i in $(seq 1 20); do curl -s -H "Host: my.example.com" "http://$INGRESS_HOST:$INGRESS_PORT/hello"; done

ඔබට පෙනෙයි, 20න් requests 18ක් විතර Hello from Spring Boot Service v1! කියලා එනවා, අනිත් 2ක් විතර Hello from Spring Boot Service v2! කියලා එනවා. මේක හරියටම 90/10 ratio එකටම එන්නේ නැති වෙන්න පුළුවන්, මොකද මේක load balancing algorithm එක මත තීරණය වෙනවා. නමුත් විශාල request ප්‍රමාණයකට මේ ratio එක maintain වෙන්න ඕනේ. (වෙනස් වෙන්න පුළුවන්, ඒත් ඒක ආසන්න වශයෙන් 90/10 වෙයි).

මේ විදියට ඔබට පුළුවන් ක්‍රමයෙන් ඔබේ අලුත් service version එක production එකට නිකුත් කරන්න, users ලට බලපාන්නේ නැති විදියට. මොකද අලුත් version එකේ මොනවා හරි ප්‍රශ්නයක් ආවොත්, VirtualService එක update කරලා traffic එක සම්පූර්ණයෙන්ම v1 එකට යවන්න පුළුවන්, කිසිම downtime එකක් නැතුව!

අවසන් වශයෙන් (Conclusion) ✨

අද අපි Spring Boot microservices Istio Service Mesh එකක් සමඟ භාවිත කර traffic management කරන ආකාරය ගැන ඉගෙන ගත්තා. අපි මුලින්ම Service Mesh සහ Istio කියන්නේ මොකක්ද කියලා තේරුම් ගත්තා. ඊට පස්සේ සරල Spring Boot service එකක් Kubernetes වල deploy කරලා, Istio Gateway, VirtualService සහ DestinationRule කියන key resources ගැන ඉගෙන ගත්තා.

අවසානයේදී, මේ concepts ටික පාවිච්චි කරලා කොහොමද A/B Testing (Canary Deployment) වගේ දේවල් implement කරන්නේ කියලා practical example එකකින් බැලුවා. මේකෙන් ඔයාලට පුළුවන්, ඔබේ applications වලට වැඩි control එකක් ගන්න, resilience වැඩි කරන්න, ඒ වගේම progressive delivery (ක්‍රමයෙන් අලුත් features නිකුත් කිරීම) පහසු කරගන්න.

Microservices ලෝකයේදී Istio වගේ Service Mesh එකක් කියන්නේ ගොඩක් වටිනා tool එකක්. මේක ඔයාලගේ projects වලට implement කරලා බලන්න. මොනවා හරි ප්‍රශ්න තිබ්බොත්, නැත්නම් මේ ගැන ඔබේ අත්දැකීම් බෙදාගන්න ඕනේ නම්, පහළ තියෙන comment section එකේ අනිවාර්යයෙන්ම ලියන්න. අපි හැමෝටම ඉගෙන ගන්න පුළුවන්!

Happy Coding! 🇱🇰