How to Migrate a Java Project to Kubernetes: Step‑by‑Step Guide
This article walks through the complete process of moving a Java application to a Kubernetes platform, covering image creation, pod management, data persistence, service exposure, ingress configuration, and deployment automation with Docker, Maven, and Helm‑like YAML files.
How to migrate a project to a Kubernetes platform is explained step by step.
Build image
Controller manages Pods
Pod data persistence
Expose application
Publish application
Logging and monitoring
1 Build Image
Base image: choose an OS such as CentOS 7.
Middleware image: e.g., Nginx or Tomcat service image.
Project image: layer the built project on top of the service image.
Operations staff usually prepare the images in advance so developers can directly use them, ensuring they match the target deployment environment.
2 Controller Manages Pods
Kubernetes uses controllers to deploy images, the most common being Deployment . Other controllers include:
Deployment – stateless deployment
StatefulSet – stateful deployment
DaemonSet – daemon deployment
Job & CronJob – batch processing
Stateful workloads have fixed identities (network ID, storage) and ordered start/stop, while stateless workloads do not.
3 Pod Data Persistence
Pod data persistence is needed when an application writes files that must survive pod restarts. The data can be categorized as:
Initial configuration data needed at startup.
Temporary data generated during runtime that may need to be shared between containers.
Persistent data that must be retained after the pod stops.
4 Expose Application
A Deployment alone cannot be accessed from outside the cluster because pods have dynamic IPs. A Service provides a stable ClusterIP and load‑balancing, while Ingress offers a layer‑7 entry point that routes traffic to services based on host or path.
Service defines a logical set of Pods and the access policy.
Service enables service discovery and load balancing.
CoreDNS resolves Service names.
5 Publish Application
After exposing the Service, an Ingress controller is used to provide a unified external entry point. The typical CI/CD pipeline includes:
Code stored in a Git repository.
Jenkins pulls, builds, and packages the code into a WAR.
The WAR is baked into a Docker image.
The image is pushed to a private Harbor registry.
Kubernetes pulls the image, creates a Deployment, Service, and Ingress.
yum -y install java-1.8.0-openjdk.x86_64 maven
java -version
# openjdk version "1.8.0_222"
# OpenJDK Runtime Environment (build 1.8.0_222-b10)
# OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)Place the Dockerfile and source code in the same directory:
FROM lizhenliang/tomcat
LABEL maintainer zhaochengcheng
RUN rm -rf /usr/local/tomcat/webapps/*
ADD target/*.war /usr/local/tomcat/webapps/ROOT.warConfigure Maven to use a fast mirror:
<mirror>
<id>central</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>Build the project and create the Docker image:
mvn clean package -D maven.test.skip=true
docker build -t 192.168.30.24/library/java-demo:latest .Configure Docker to trust the Harbor registry:
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"insecure-registries": ["192.168.30.24"]
}Create a namespace for the project:
apiVersion: v1
kind: Namespace
metadata:
name: testCreate a secret for registry authentication:
apiVersion: v1
kind: Secret
metadata:
name: registry-pull-secret
namespace: test
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{"auths":{"192.168.30.24":{"username":"admin","password":"Harbor12345","email":"[email protected]"}}}Define the Deployment:
apiVersion: apps/v1beta1
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
resources:
requests:
cpu: "0.5"
memory: 1Gi
limits:
cpu: "1"
memory: 2Gi
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 20
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 20Create a Service to expose the pods:
apiVersion: v1
kind: Service
metadata:
name: tomcat-java-demo
namespace: test
spec:
selector:
project: www
app: java-demo
ports:
- name: web
port: 80
targetPort: 8080Define an Ingress to provide external access:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tomcat-java-demo
namespace: test
spec:
rules:
- host: java.maidikebi.com
http:
paths:
- path: /
backend:
serviceName: tomcat-java-demo
servicePort: 80Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
