Enable rest communication for pods running java images

12/15/2018

So, this is the setup:

  • each pod will run one container (java application)
  • each pod provides its own UI
  • for each java app there is a mysql DB which it needs to access
  • for each java app its necessary to retrieve and provide information using rest calls

It is some kind of the classic containerized microservice architecture.

The requirement is to enable the applications to request and provide information for other application running on different pods. But as I need to set these calls up before I push them to the cluster I have, to be honest, no idea how it should work.

E.g. I got an application which is using another rest interface to request data:

public List<Article> getArticles() {
        String url = http://ip:port/article/getAllArticles/;
        HttpEntity entity = prepareHttpEntity();
        ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.GET, entity, List.class);
        return response.getBody();
    }

How I can make sure to it is connecting to the right service (pod)?

Same for the DB setup. I need to tell the application the datasource, which is unknown yet.

Is there some kind of best practice to deal with these issues?

-- elp
docker
java
kubernetes
microservices

1 Answer

12/15/2018

Each Pod when created will have its own cluster-private IP, but you never depend on it, as pods are ephemeral. If you want to talk to a Pod, you create a Service that routes traffic to the pod.

restCall --> Service --> Pod

Let's say you have the following Pod definition

apiVersion: v1
kind: Pod
metadata:
  name: appAPod
  labels:
    app: appA
spec:
  containers:
  - name: aNameForApp1Container
    image: yourRepository/imageName:tag
    ports:
    - containerPort: 8080
  ...

Then, you make it accessible by creating a Service Definition:

kind: Service
apiVersion: v1
metadata:
  name: serviceA
spec:
  selector:
    app: appA
  ports:
  - name: serviceAPort
    protocol: TCP
    port: 80
    targetPort: 8080 

So the way you connect a Pod and a Service is via labels and selector. Now, you can hit your pod with the following url :

http://serviceA:80

In your second app, you will have the following Pod Definition:

apiVersion: v1
kind: Pod
metadata:
  name: appBPod
  labels:
    app: appB
spec:
  containers:
  - name: aNameForApp2Container
    image: yourRepository/imageName2:tag
    ports:
    - containerPort: 8080
    env:
    - name: "APP_A_ADDRESS"
      value: serviceA
    - name: "APP_A_PORT"
      value: 80

Since you're using RestTemplate, I assume you are using Spring. So in your application.properties :

..
..
appA.baseUrl=http://${APP_A_ADDRESS}:${APP_A_PORT}

And in your code:

@Value("${appA.baseUrl}")
String appABaseUrl;

public List<Article> getArticles() {
        String url = appABaseUrl + "/article/getAllArticles/";
        HttpEntity entity = prepareHttpEntity();
        ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.GET, entity, List.class);
        return response.getBody();
}

You should consider Deplyments, instead of a Pod, as it offers you more flexibility and control over your containers.

If you are going to containerize your DB, then you might want to check out Persistent Volume

-- Elgarni
Source: StackOverflow