kubernetescloud

How to host a simple REST service as a Kubernetes pod


I have been working in Kubernetes. I am well aware of all the components like pod, deployment, service etc.

But I am not able to get the whole picture and hence need your help.

Suppose I want to create a new pod only for this small Java program:

package com.test;
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
 
@Path("/hello")
public class HelloWorldRestService {
 
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getMessage(){
        return "Hello World";
    }
}

In that case what all do I need to launch this pod in the Kubernetes cluster? REST clients outside the cluster should be able to access this URL.

So I need:

  1. The image and the image should be hosted in some registry
  2. The pod yaml file
  3. The deployment yaml file
  4. Route table
  5. Service
  6. Gateway
  7. Load balancer

But what should be the configuration in each of them and how they will be related to each other?

I have followed many tutorials etc, but everyone is just explaining the concepts, not sharing the yaml code. How can I achieve the same through coding?

Please share your expertise.

Thanks


Solution

  • Here are the rough steps (code snippets are untested, but hopefully give you the basic idea):

    1. Build your app. First, you need to build your app into some sort of deployable artifact. In the Java world, the most common way to do this is to create a .jar file. One option is to do this manually (this assumes your Java code is in the src folder):

      javac -d ./build src/*.java
      jar cvf app.jar ./build/*
      

      That said, a more realistic option would be to use a build system such as Gradle or Maven to manage your build and dependencies.

    2. Package your app as a Docker image. Next, you need to package your app artifact (the .jar file) as a Docker image.

      # Use OpenJDK 17 as base image
      FROM openjdk:17-jdk-slim
      
      # Set working directory
      WORKDIR /app
      
      # Copy source code
      COPY src/ ./src/
      
      # Create directory for compiled classes
      RUN mkdir -p build
      
      # Create jar file. If you use Gradle or Maven, run those here instead.
      RUN javac -d ./build src/*.java
      RUN jar cvf app.jar ./build/*
      
      # Set default command to run the JAR file
      CMD ["java", "-jar", "app.jar"]
      

      To build the Docker image:

      docker build -t my-app:v1 .
      
    3. Push to a Docker registry. You now have a Docker image, but it's only on your own computer. Your Kubernetes cluster won't be able to access it there, so you need to push the image to a registry that is accessible to the cluster. For example, you might use Docker Hub as a registry. You can use the web UI in Docker Hub to create a user for yourself named username and a new repository under that user named my-app. You can then login to Docker hub:

      docker login
      

      This will allow you to login via your web browser. Once authenticated, tag your Docker image with your Docker Hub username and repo name, and push the image:

      docker tag my-app:v1 username/my-app:v1
      docker push username/my-app:v1
      
    4. Create a Deployment. There are many ways to deploy apps in Kubernetes. One option is to create a Deployment, which is a declarative way to manage an application in Kubernetes. The Deployment allows you to declare which Docker images to run, how many copies of them to run (replicas), a variety of settings for those images (e.g., CPU, memory, port numbers, environment variables), and so on, and the Deployment will then work to ensure that the requirements you declared are always met. Here's the YAML for a basic Deployment:

      apiVersion: apps/v1
      kind: Deployment                  
      metadata:                         
        name: sample-app-deployment
      spec:
        replicas: 2                    
        template:                       
          metadata:                     
            labels:
              app: sample-app-pods
          spec:
            containers:                 
              - name: sample-app  
                # Specify the Docker image to deploy from your Docker registry      
                image: username/my-app:v1    
                ports:
                  # Specify the port your app listens on for HTTP requests
                  - containerPort: 8080 
        selector:                       
          matchLabels:
            app: sample-app-pods   
      

      Note that if your app is in a private Docker registry, you'll have to give your Kubernetes cluster a way to authenticate to that registry.

      You can use kubectl to create this Deployment. First, you need to authenticate to your Kubernetes cluster. How you do this depends on the cluster. For example, if you're using the local Kubernetes cluster built into Docker Desktop, you can authenticate to it as follows:

      kubectl config use-context docker-desktop
      

      If the YAML for the Deployment is in a file called deployment.yml, you can create it as follows:

      kubectl apply -f deployment.yml
      
    5. Create a Service. A Deployment will get your app running in the cluster, but it won't make it available to other services over the network. To expose your app to the outside world, you can create a Service:

      apiVersion: v1
      kind: Service                    
      metadata:                        
        name: sample-app-loadbalancer
      spec:
        type: LoadBalancer             
        selector:
          app: sample-app-pods         
        ports:
          - protocol: TCP
            port: 80                   
            targetPort: 8080           
      

      If the YAML for this Service is in service.yml, you can create it as follows:

      kubectl apply -f service.yml
      
    6. Test. It'll take a minute or two for everything to deploy. To see the status of your Deployment:

      kubectl describe deployment sample-app-deployment
      

      To see the status of your Service:

      kubectl describe service sample-app-loadbalancer
      

      If everything is working, that last command should output a LoadBalancer Ingress field, which shows you the URL to use for the load balancer. You can then test that URL:

      curl http://<<URL>
      

      If everything is working, you should see "Hello, World."

    This is a minimal deployment just for learning. I've glossed over many details. For a lot more info, including working & tested code examples, check out the Container Orchestration section of How to manage your apps using orchestration tools (an article I wrote).