Building a Multi-Language Microservice Project with Kubernetes, ArgoCD, and DevSecOps

Introduction
This blog post walks through my implementation of a multi-language microservice project (Java, Python, Go) deployed on Kubernetes, automated with ArgoCD (GitOps), and secured via DevSecOps practices (Trivy scanning, GitHub Actions CI/CD).
π Project Repository
GitHub - multi-lang-devops-project
πDemo Endpoints
Java Service (Spring Boot)
Python Service (Flask)
Go Service (Native HTTP)
Technical Implementation
1. Microservices in Three Languages
β Java Service (Spring Boot)
REST API with Spring Web
Actuator for health checks (
/health
)Maven build system
Multi-stage Docker build for optimized image
π Python Service (Flask)
Lightweight Flask REST API
Pytest for unit testing
requirements.txt
dependency managementAlpine-based Docker image for minimal footprint
π Go Service (Native HTTP)
Standard library HTTP server
Minimal dependencies (
go.mod
)Single-binary deployment
Scratch-based Docker image (~5MB)
2. Kubernetes Deployment
All services are deployed using Kubernetes manifests with:
Deployments (replicas, resource limits)
Services (ClusterIP for internal communication)
Health checks (liveness & readiness probes)
Example Deployment (Java Service)
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-service
spec:
replicas: 2
template:
spec:
containers:
- name: java-service
image: lookatravi/java-service:latest
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /api/java/health
port: 8080
Manifest Structure
k8s-manifest-all/
βββ all-services.yaml # Combined manifests
βββ java-deployment.yaml
βββ python-service.yaml
βββ go-service.yaml
3. Local Development Access with Port-Forwarding
For easy local testing, I use a Bash script to automate kubectl port-forward
:
port-forward.sh
#!/bin/bash
# Stop all port-forwards on script exit
trap "echo 'Stopping port-forwarding...'; kill 0" SIGINT SIGTERM EXIT
# Forward Java service (8080 β 80)
nohup kubectl port-forward svc/java-service 8080:80 > java.log 2>&1 &
echo "Java: http://localhost:8080"
# Forward Python service (5001 β 80)
nohup kubectl port-forward svc/python-service 5001:80 > python.log 2>&1 &
echo "Python: http://localhost:5001"
# Forward Go service (5002 β 80)
nohup kubectl port-forward svc/go-service 5002:80 > go.log 2>&1 &
echo "Go: http://localhost:5002"
wait # Keep running until Ctrl+C
Features
β
Graceful shutdown (kills all forwards on exit)
β
Log separation (per-service logs in java.log
, python.log
, go.log
)
β
Consistent ports (matches production endpoints)
Usage
chmod +x port-forward.sh
./port-forward.sh
# Access:
# - Java: localhost:8080
# - Python: localhost:5001
# - Go: localhost:5002
4. ArgoCD (GitOps Deployment)
Deployed on AWS EC2, ArgoCD syncs Kubernetes manifests automatically:
Installation
helm install argocd argo/argo-cd --namespace argocd
Application Configuration
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: multi-lang-app
spec:
source:
repoURL: https://github.com/lookatravi/multi-lang-devops-project
path: k8s-manifest-all
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated: # Auto-sync on Git changes
prune: true
selfHeal: true
Benefits
β Automated deployments (Git as single source of truth)
β Rollback capability (via Git history)
β Visual UI for monitoring status
5. CI/CD Pipeline (GitHub Actions + DevSecOps)
Pipeline Stages
Build & Test (Java, Python, Go)
Dockerize & Push (to DockerHub)
Security Scan (Trivy for vulnerabilities)
Update K8s Manifests (GitOps trigger)
Key Workflow Features
- name: Trivy Scan (Java)
run: |
trivy image --severity CRITICAL,HIGH \
--exit-code 1 \
${{ env.DOCKER_USERNAME }}/java-service:${{ github.run_id }}
- name: Update K8s Manifests
run: |
sed -i "s|image: lookatravi/java-service:.*|image: lookatravi/java-service:${{ github.run_id }}|" k8s-manifest-all/all-services.yaml
git commit -am "CI: Update image tags"
git push
Security Checks
π Trivy scans for CVEs in containers
π GitHub CodeQL integration for SARIF reports
π Fail pipeline on critical vulnerabilities
SARIF reports Sample
π Architecture Overview
π Lessons Learned
β
Consistency is key β Standardizing APIs (/health
, /api
) across languages improves maintainability.
β
Go containers are tiny β Scratch images are ~5MB vs Java (~200MB).
β
Trivy + ArgoCD = Strong Security β Catching vulnerabilities before deployment is crucial.
β
Port-forwarding script saves time β No more manual kubectl
commands!
Kubernetes Pods Running
kubectl get deployments
kubectl get svc
kubectl get pods
ArgoCD UI Sync Status
GitHub Actions Pipeline Passed
Live Endpoints Working
API: http://IP/localhost:8080/api/java
Health: http://IP/localhost:8080/api/java/health
API: http://IP/localhost:5001/api/python
Health: http://IP/localhost:5001/api/python/health
API: http://IP/localhost:5002/api/go
Health: http://IP/localhost:5002/api/go/health
π Conclusion
This project demonstrates how to manage polyglot microservices with:
β Kubernetes (unified deployment)
β ArgoCD (GitOps automation)
β DevSecOps (Trivy, GitHub Actions)
β Bash automation (port-forwarding, logging)
Check out the full code:
π GitHub - multi-lang-devops-project
Questions? Let me know in the comments! π
Subscribe to my newsletter
Read articles from Ravichandran Sundaramurthy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
