Deploying Java and PHP Applications on Kubernetes with ELK and Prometheus Monitoring

Environment Preparation

1.1 Cloning GitLab Repository

mkdir /root/gitlab/
cd /root/gitlab/
git clone http://172.17.17.84:85/java/java.git

1.2 Setting Up Harbor Registry

Login and create a project named demo in Harbor.

docker login reg.ctnrs.com
# Username: admin
# Password: harbor12345
docker tag <source-image> reg.ctnrs.com/demo/java-demon:v1
docker push reg.ctnrs.com/demo/java-demon:v1

1.3 Installing JDK and Maven

yum install java-1.8.0-openjdk maven -y

Configure Maven to use the Aliyun mirror by editing /etc/maven/settings.xml:

<mirror>
  <id>central</id>
  <mirrorOf>central</mirrorOf>
  <name>aliyun maven</name>
  <url>https://maven.aliyun.com/repository/public</url>
</mirror>

1.4 Building the Java Application

cd /root/gitlab/java
mvn clean package -D maven.test.skip=true

Create the Docker image and push to Harbor:

docker build -t reg.ctnrs.com/demo/java-demon:v1 .
docker push reg.ctnrs.com/demo/java-demon:v1

Kubernetes Deployment

2.1 Creating Namespace and Pull Secret

kubectl create ns test
kubectl create secret docker-registry docker-registry-auth --docker-username=admin --docker-password=Harbor12345 --docker-server=reg.ctnrs.com -n test

2.2 Deploying the Java Application

Create deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: 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: "docker-registry-auth"
      containers:
      - image: reg.ctnrs.com/demo/java-demon:v1
        name: java-demo
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        resources:
          requests:
            cpu: 0.5
            memory: 1.8Gi
          limits:
            cpu: 2
            memory: 3Gi
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 20
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 20

Create service.yaml:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: java-demo
  name: java-demo
  namespace: test
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 30018
  selector:
    project: www
    app: java-demo
  type: NodePort

Apply both resources:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

Verify the service:

kubectl get svc -n test
kubectl get ep -n test

Access the application via http://172.17.17.85:30018/.

2.3 Exposing with Ingress

Ensure an Ingress Controller is deployed (e.g., NGINX Ingress).

Create ingress.yaml:

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

Apply it:

kubectl apply -f ingress.yaml

2.4 Setting Up MySQL with Helm

helm install java-demon-db --set persistence.storageClass="managed-nfs-storage" azure/mysql

Copy SQL file into the MySQL pod and initialize the database:

kubectl cp db/tables_ly_tomcat.sql java-demon-db-mysql-dc4bcf7fd-df42g:/
kubectl exec -it java-demon-db-mysql-dc4bcf7fd-df42g bash
mysql -uroot -p$MYSQL_ROOT_PASSWORD
create databases java;
use java;
source /tables_ly_tomcat.sql;
grant all on java.* to 'root'@'%' identified by 'yuPML5qCdK';

If the table srtucture is missing, create it manually:

CREATE TABLE `user` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(100) NOT NULL COMMENT 'name',
  `age` INT(3) NOT NULL COMMENT 'age',
  `sex` CHAR(1) DEFAULT NULL COMMENT 'gender',
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

Udpate src/main/resources/application.yml:

url: jdbc:mysql://java-demon-db-mysql.default:3306/java?characterEncoding=utf-8
username: root
password: yuPML5qCdK

Rebuild the application:

mvn clean package -D maven.test.skip=true
docker build -t reg.ctnrs.com/demo/java-demon:v2 .

Update deployment.yaml to use the new image and reapply.

Deploying PHP Application

3.1 PHP MySQL Database

helm install php-demon-db --set persistence.storageClass="managed-nfs-storage" azure/mysql -n test
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default php-demon-db-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)
echo $MYSQL_ROOT_PASSWORD

Update wp-config.php:

define('DB_NAME', 'wp');
define('DB_USER', 'root');
define('DB_PASSWORD', 'qOaSMpDX4v');  // Use actual password
define('DB_HOST', 'php-demon-db-mysql.default');

Build and push the PHP image:

docker build -t reg.ctnrs.com/demo/php-demo:v1 .
docker push reg.ctnrs.com/demo/php-demo:v1

3.2 Deploying PHP Application

Update deployment.yaml to reference the PHP image and ensure imagePullSecrets is set.

kubectl apply -f deployment.yaml
kubectl get svc -n test

Initialize the database:

kubectl exec -it php-demon-db-mysql-76bd66ff4d-nmglm bash
mysql -uroot -p$MYSQL_ROOT_PASSWORD
create databases wp;

Access the PHP application via the NodePort or Ingress.

Monitoring with ELK and Prometheus

ELK Stack for Log Collection

Deploy the ELK stack (Elasticsearch, Logstash, Kibana) using Helm or manual manifests. Configure Filebeat or Fluentd as a DaemonSet to collect logs from all containers. Send logs to Logstash for parsing and then to Elasticsearch. Use Kibana to visualize logs.

Prometheus for Metrics

Deploy Prometheus with a ServiceMonitor to scrape metrics from Kubernetes components and application endpoints. Use Grafana for dashboards. Configure alerts as needed.

Apply monitoring manifests and verify data in Grafana and Kibana.

Tags: kubernetes java PHP ELK prometheus

Posted on Thu, 04 Jun 2026 19:09:24 +0000 by pplexr