k8s Build and test application using Maven

Category : Kubernetes | Sub Category : Kubernetes With Java | By Prasad Bonam Last updated: 2023-11-21 08:33:48 Viewed : 215


Kubernetes (K8s) is a powerful container orchestration platform, and Maven is a widely used build tool for Java projects. Here is a general guide on how you can build and test a Java application using Maven and then deploy it to Kubernetes.

Prerequisites:

  1. Make sure you have Maven and Kubernetes installed on your system.
  2. Have a Kubernetes cluster running, either locally (e.g., using Minikube) or on a cloud provider.

Steps:

  1. Create a Java Project: Start by creating a simple Java project using Maven. You can use the following command to generate a basic project structure:

    bash
    mvn archetype:generate -DgroupId=com.example -DartifactId=my-java-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

    This will create a my-java-app directory with a basic Maven project structure.

    The mvn archetype:generate command is part of Apache Maven, and it is used to generate a new Maven project based on a specific project template or archetype. Archetypes are project templates that define the structure and initial configuration of a Maven project. The command you provided generates a new Maven project using the maven-archetype-quickstart archetype with specific parameters.

    Here is a breakdown of the command:

    • mvn archetype:generate: This is the Maven command to generate a new project from an archetype.

    • -DgroupId=com.example: This sets the groupId property for the generated Maven project. The groupId is typically used to identify the project`s group or organization.

    • -DartifactId=my-java-app: This sets the artifactId property for the generated Maven project. The artifactId is the name of the generated JAR file without the version.

    • -DarchetypeArtifactId=maven-archetype-quickstart: This specifies the archetype to be used for project generation. In this case, it is using the maven-archetype-quickstart archetype, which is a simple archetype for creating a basic Java project with a standard directory structure.

    • -DinteractiveMode=false: This parameter disables interactive mode during project generation. In interactive mode, Maven prompts the user for input to customize the project properties. Setting it to false means that Maven will use the default values specified by the command, and it won`t prompt for user input.

    When you run this command, Maven will download the specified archetype from the Maven Central Repository, create a new directory for your project, and generate the necessary project files based on the archetype. The generated project will have a standard Maven project structure, including source code directories, a pom.xml file, and a simple Java class for you to get started with.

    Here Is an example of what the generated project structure might look like:

    lua
    my-java-app |-- src | |-- main | |-- java | |-- com | |-- example | |-- App.java |-- pom.xml

    The App.java file in the src/main/java/com/example/ directory is a simple Java class that you can use as a starting point for your application. The pom.xml file contains the project configuration and dependencies managed by Maven.

  2. Write Code and Tests: Write your Java application code in the src/main/java directory and corresponding tests in the src/test/java directory.

  3. Build the Application: Use Maven to build your application:

    bash
    cd my-java-app mvn clean install

    This will compile your code, run tests, and package your application into a JAR file.

    After running the mvn archetype:generate command with the specified parameters, you would have created a new Maven project named "my-java-app" using the "maven-archetype-quickstart" archetype. The cd my-java-app command is used to change the current directory to the newly created project directory. Once you are inside the project directory, you can use Maven commands to build and manage the project.

    Here is a breakdown of the commands:

    1. cd my-java-app: This command changes the current working directory to the "my-java-app" directory. After running this command, you will be inside the project directory where the generated project files are located.

    2. mvn clean install:

      • mvn: This is the Maven command-line tool.
      • clean: This is a Maven lifecycle phase that removes the target directory, which contains the compiled bytecode and other generated files from previous builds. It ensures a clean state before building the project again.
      • install: This is also a Maven lifecycle phase. In the context of the install phase, Maven will compile the source code, run tests, package the application into a JAR (or other applicable format), and then copy the packaged JAR to the local Maven repository. The local Maven repository is typically located in the users home directory (~/.m2/repository).

    So, when you run mvn clean install inside the "my-java-app" directory, Maven will perform the following actions:

    • Clean the project by removing the target directory.
    • Compile the Java source code located in the "src/main/java" directory.
    • Run any tests located in the "src/test/java" directory.
    • Package the application into a JAR file.
    • Copy the JAR file to the local Maven repository.

    After running these commands, you should see output indicating the build process, and if everything is successful, you will find the compiled JAR file in the "target" directory. The JAR file will have a name like "my-java-app-1.0-SNAPSHOT.jar" (the version number may vary depending on your project configuration).

  4. Create Docker Image: To run your application in Kubernetes, you need to containerize it. Create a Dockerfile in the project root directory:

    Dockerfile
    FROM openjdk:11-jre-slim COPY target/my-java-app-1.0-SNAPSHOT.jar /app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]

    The provided code is a Dockerfile, which is a set of instructions used to build a Docker image. Docker images are portable, self-sufficient containers that can run applications and their dependencies. Lets break down each line of the Dockerfile:

    1. FROM openjdk:11-jre-slim:

      • This line specifies the base image for the Docker image being built. In this case, it is using the official OpenJDK 11 image with the JRE (Java Runtime Environment) on a slim Debian-based Linux distribution. This base image provides a minimal environment for running Java applications.
    2. COPY target/my-java-app-1.0-SNAPSHOT.jar /app.jar:

      • This line copies the JAR file generated by Maven during the build process into the Docker image. The source file is assumed to be located in the "target" directory of the build context (the directory where the Dockerfile is located). The destination in the image is set to "/app.jar". Adjust the source and destination paths accordingly based on your project structure.
    3. ENTRYPOINT ["java", "-jar", "/app.jar"]:

      • This line sets the default command to run when a container based on this image is started. It specifies that the Java application should be executed using the java -jar command, and the JAR file to be executed is "/app.jar". The ENTRYPOINT instruction allows you to configure a container that will run as an executable.

    In summary, this Dockerfile is creating a lightweight container for running a Java application. It starts with a base image containing OpenJDK 11 with the JRE, copies the JAR file into the image, and sets up the entry point to run the Java application when the container starts. This is a common pattern for packaging and deploying Java applications using Docker, especially in microservices architectures.

    Build the Docker image:

    bash
    docker build -t my-java-app:1.0 .
  5. The docker build command is used to build a Docker image from a specified Dockerfile. Lets break down the provided command:

    1. docker build: This is the command to build a Docker image.

    2. -t my-java-app:1.0: This option is used to tag the resulting Docker image. The -t flag allows you to specify a name and optionally a tag for the image. In this case:

      • my-java-app is the name of the image.
      • 1.0 is the tag associated with the image. The tag is often used to version the image.
    3. .: This specifies the build context. The build context is the set of files located in the current directory (.) and its subdirectories. It includes the Dockerfile and any files specified in the Dockerfile with commands like COPY or ADD.

    Putting it all together, the command docker build -t my-java-app:1.0 . is telling Docker to build an image based on the Dockerfile found in the current directory (.). The resulting image will be tagged as my-java-app with the version 1.0.

    During the build process, Docker will execute the instructions in the Dockerfile, which includes pulling the base image (in this case, OpenJDK 11 with the JRE), copying the JAR file into the image, and setting up the entry point. The final output is a Docker image that encapsulates your Java application along with its dependencies and runtime environment.

    After the build is complete, you can use the docker images command to verify that the image has been created with the specified tag:

    bash
    docker images

    You should see an entry for my-java-app with the 1.0 tag in the list of Docker images.

    Push Docker Image: If you are using a container registry (like Docker Hub), push the Docker image:

    bash
    docker tag my-java-app:1.0 username/my-java-app:1.0 docker push username/my-java-app:1.0
  6. The docker tag and docker push commands are used to tag and push a Docker image to a container registry. Lets break down each command:

    1. docker tag my-java-app:1.0 username/my-java-app:1.0:

      • docker tag: This command is used to create a new tag for an existing Docker image.

      • my-java-app:1.0: This is the source image and tag that you want to tag.

      • username/my-java-app:1.0: This is the new tag you are assigning to the image. It includes the username (or organization name) associated with the container registry. This is typically used when you want to push the image to a remote registry, such as Docker Hub or another private registry.

      So, this command is creating a new tag (username/my-java-app:1.0) for the existing Docker image (my-java-app:1.0).

    2. docker push username/my-java-app:1.0:

      • docker push: This command is used to push a Docker image or a repository to a container registry.

      • username/my-java-app:1.0: This specifies the image and tag that you want to push. It includes the username (or organization name) associated with the container registry.

      After running this command, Docker will push the image with the specified tag to the container registry. This assumes that you are authenticated to the registry (logged in) using docker login with the appropriate credentials.

      Note: Before pushing to a container registry, it is a common practice to log in to the registry using docker login. This command prompts you for your registry credentials (username and password or token).

    In summary, the two commands together (docker tag and docker push) are used to tag a Docker image with a new name and push it to a container registry, making it available for use by others or for deployment to a Kubernetes cluster or other container orchestration platforms.

    Deploy to Kubernetes: Create Kubernetes deployment and service YAML files. For example:

    yaml
    # deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-java-app spec: replicas: 3 selector: matchLabels: app: my-java-app template: metadata: labels: app: my-java-app spec: containers: - name: my-java-app image: username/my-java-app:1.0 ports: - containerPort: 8080
    yaml
    # service.yaml apiVersion: v1 kind: Service metadata: name: my-java-app spec: selector: app: my-java-app ports: - protocol: TCP port: 80 targetPort: 8080 type: LoadBalancer

    Apply the configuration to your Kubernetes cluster:

    bash
    kubectl apply -f deployment.yaml kubectl apply -f service.yaml
  7. Test the Application:

    Once deployed, test your application:

    bash
    kubectl get services # Note the external IP of the service curl http://<external-ip>

    Alternatively, you can port-forward to one of the pods:

    bash
    kubectl port-forward <pod-name> 8080:8080

    Then access your app at http://localhost:8080.

Thats it! You have built, tested, containerized, and deployed a Java application to Kubernetes using Maven.

Search
Related Articles

Leave a Comment: