Cloud Native 14 min read

How to Migrate a Java Project to Kubernetes: From Image Build to Ingress

This guide walks through migrating a Java application to a Kubernetes platform, covering image creation, pod controllers, data persistence, service exposure, ingress publishing, and a complete step‑by‑step example with Docker, Harbor, and YAML manifests.

Efficient Ops
Efficient Ops
Efficient Ops
How to Migrate a Java Project to Kubernetes: From Image Build to Ingress

1 Build Image in Three Steps

Base image based on an operating system such as CentOS 7.

Middleware image (e.g., nginx or tomcat) that provides the runtime.

Project image that packages the application on top of the middleware.

Operations staff usually prepare the image in advance so developers can directly use it in the target environment.

2 Controllers Manage Pods

Kubernetes uses controllers to schedule pods, including Deployment for stateless workloads, StatefulSet for stateful workloads, DaemonSet for daemon processes, and Job/CronJob for batch processing.

Stateful pods have fixed identities (network ID, storage) and ordered start/stop, while stateless pods do not.

3 Pod Data Persistence

Pod persistence is needed when an application writes data to local files. Three kinds of data are considered:

Initial configuration data required at startup.

Temporary data shared among containers during runtime.

Persistent data that must survive pod restarts.

4 Exposing the Application

Since a Deployment has no stable address, a Service provides a logical set of pods and a stable ClusterIP for load‑balancing and service discovery. CoreDNS resolves Service names.

5 Publishing the Application

Ingress complements Service by offering a Layer‑7 entry point, allowing external users to reach the application via a domain name. CI/CD pipelines build the code, create a Docker image, push it to Harbor, and then deploy it on Kubernetes.

Practical Example: Deploy a Java Tomcat Application

Install OpenJDK and Maven:

<code>yum -y install java-1.8.0-openjdk.x86_64 maven
java -version</code>

Create a Dockerfile that copies the built WAR into a Tomcat base image:

<code>FROM lizhenliang/tomcat
LABEL maintainer zhaochengcheng
RUN rm -rf /usr/local/tomcat/webapps/*
ADD target/*.war /usr/local/tomcat/webapps/ROOT.war</code>

Configure Maven to use a fast mirror, then build the WAR:

<code>mvn clean package -D maven.test.skip=true</code>

Build and push the Docker image to a private Harbor registry:

<code>docker build -t 192.168.30.24/library/java-demo:latest .
# configure insecure‑registry if needed
docker login 192.168.30.24
docker push 192.168.30.24/library/java-demo:latest</code>

Create a namespace and a pull‑secret for the registry:

<code>apiVersion: v1
kind: Namespace
metadata:
  name: test
---
apiVersion: v1
kind: Secret
metadata:
  name: registry-pull-secret
type: kubernetes.io/dockerconfigjson
# data omitted for brevity</code>

Define a Deployment that uses the image:

<code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  replicas: 3
  selector:
    matchLabels:
      project: www
      app: java-demo
  template:
    metadata:
      labels:
        project: www
        app: java-demo
    spec:
      imagePullSecrets:
      - name: registry-pull-secret
      containers:
      - name: tomcat
        image: 192.168.30.24/tomcat-java-demo/java-demo:latest
        ports:
        - containerPort: 8080</code>

Expose the pods with a Service:

<code>apiVersion: v1
kind: Service
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  selector:
    project: www
    app: java-demo
  ports:
  - name: web
    port: 80
    targetPort: 8080</code>

Create an Ingress to route external traffic:

<code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  rules:
  - host: java.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat-java-demo
          servicePort: 80</code>

After applying the manifests, the application is reachable via the Ingress host name (or by curling the Service ClusterIP for testing).

JavaDockerCI/CDdeploymentKubernetesIngressHarbor
Efficient Ops
Written by

Efficient Ops

This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.