DNA //evolutions

JOpt TourOptimizer on Kubernetes

This document describes best practices and reference architectures for running JOpt TourOptimizer as a containerized Spring-based application in Kubernetes environments. It targets DevOps engineers, platform operators, and solution architects responsible for deploying and operating JOpt in production-grade container platforms.

The guidance is intentionally platform-agnostic and applies equally to managed Kubernetes offerings (such as EKS, AKS, GKE, OpenShift) and self-managed clusters.


Architectural Overview

JOpt TourOptimizer is a stateless Spring application that exposes its functionality via REST APIs. It is therefore well suited for cloud-native, container-based deployments.

At a high level, a typical Kubernetes setup consists of:

  • One or more JOpt application Pods
  • A Service for internal or external access
  • Optional Ingress for HTTP(S) routing
  • ConfigMaps and Secrets for configuration
  • Optional Persistent Volumes for logs or temporary data
  • Horizontal scaling via ReplicaSets / Deployments

The application itself does not require Kubernetes-specific features and follows standard Spring Boot conventions.


Container Image Assumptions

This document assumes that JOpt TourOptimizer is available as a Docker-compatible container image with the following characteristics:

  • Runs as a non-root user
  • Exposes an HTTP port (default: 8080)
  • Uses environment variables and/or configuration files for runtime configuration
  • Terminates gracefully on SIGTERM (Spring Boot default behavior)

Example (conceptual):

  • Image: dna-evolutions/jopt-touroptimizer:<version>
  • Exposed port: 8080

Kubernetes Deployment Model

Deployment

JOpt should be deployed using a Kubernetes Deployment resource to ensure:

  • Declarative lifecycle management
  • Automatic restarts
  • Rolling updates
  • Horizontal scalability

Example (simplified):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jopt-touroptimizer
spec:
  replicas: 2
  selector:
    matchLabels:
      app: jopt
  template:
    metadata:
      labels:
        app: jopt
    spec:
      containers:
        - name: jopt
          image: dna-evolutions/jopt-touroptimizer:latest
          ports:
            - containerPort: 8080
          env:
            - name: SPRING_PROFILES_ACTIVE
              value: kubernetes

Service

Expose the application internally within the cluster using a Service:

apiVersion: v1
kind: Service
metadata:
  name: jopt-service
spec:
  selector:
    app: jopt
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP

For external access, this service is typically combined with an Ingress or LoadBalancer.


Configuration Management

Spring Configuration

JOpt follows standard Spring configuration patterns. Configuration can be supplied via:

  • Environment variables
  • application.yml / application.properties
  • Spring profiles (recommended)

In Kubernetes, configuration should be externalized using:

  • ConfigMaps for non-sensitive values
  • Secrets for credentials and licenses

Example ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: jopt-config
data:
  application.yml: |
    server:
      port: 8080
    jopt:
      solver:
        timeoutSeconds: 60

Mounted into the container or referenced via environment variables.


Secrets

Sensitive data such as license keys, credentials, or API tokens must be stored in Kubernetes Secrets:

apiVersion: v1
kind: Secret
metadata:
  name: jopt-secrets
type: Opaque
stringData:
  JOPT_LICENSE_KEY: "<license-key>"

Referenced in the Deployment:

env:
  - name: JOPT_LICENSE_KEY
    valueFrom:
      secretKeyRef:
        name: jopt-secrets
        key: JOPT_LICENSE_KEY

Resource Management

CPU and Memory

JOpt performs computationally intensive optimization tasks. Explicit resource requests and limits are strongly recommended.

Example:

resources:
  requests:
    cpu: "1"
    memory: "2Gi"
  limits:
    cpu: "2"
    memory: "4Gi"

This ensures predictable scheduling and prevents resource starvation of other workloads.


Horizontal Scaling

JOpt instances are typically stateless and can be scaled horizontally if:

  • Requests are independent
  • External state (if any) is managed outside the Pod

Horizontal Pod Autoscaling (HPA) can be enabled based on CPU or custom metrics.

Note: Scaling does not speed up a single optimization run; it increases throughput.


Networking and Ingress

For production deployments, access to JOpt is commonly provided via:

  • Kubernetes Ingress
  • API Gateway
  • Service Mesh (optional)

Ingress example (simplified):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: jopt-ingress
spec:
  rules:
    - host: jopt.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: jopt-service
                port:
                  number: 80

TLS termination and authentication are typically handled at this layer.


Observability

Logging

JOpt logs to standard output, following container best practices. Logs should be collected by the cluster’s logging solution (e.g. Fluent Bit, Logstash).

Health Checks

Spring Boot Actuator endpoints should be enabled and used for:

  • Liveness probes
  • Readiness probes

Example:

livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  initialDelaySeconds: 30

readinessProbe:
  httpGet:
    path: /actuator/health/readiness
    port: 8080
  initialDelaySeconds: 10

Security Considerations

  • Run containers as non-root
  • Use network policies to restrict access
  • Store licenses and credentials only in Secrets
  • Prefer TLS for all external communication
  • Limit Pod permissions via RBAC and Pod Security Standards

Production Recommendations

  • Use explicit versions for container images
  • Separate environments via namespaces
  • Enable rolling updates with appropriate readiness probes
  • Test resource limits under realistic workloads
  • Monitor memory usage closely for large optimization problems

Summary

JOpt TourOptimizer integrates cleanly into Kubernetes-based platforms due to its stateless, Spring-based architecture. By following standard Kubernetes patterns for configuration, scaling, and observability, the application can be operated reliably in both cloud and on-premise environments.

For advanced deployment scenarios or performance tuning, please consult DNA Evolutions directly.