Run/curl simple Java application deployed and exposed to Kubernetes cluster hosted on AWS

11/18/2019

I am newbie to Kubernetes and had a long time configuring my application to be hosted on Kubernetes cluster hosted on AWS EKS.

Status-quo: I am pretty sure that the service of type LoadBalancer is up and running. It has its pod and all the stuff running. The application is simple Java application with input. You can try accessing it by pulling an image from Docker Hub via:

docker run -i ardulat/mckinsey

Question: how can I run the Java application (not Spring, not REST) that is being hosted on Kubernetes cluster?

Already tried:

  • curl -v <EXTERNAL-IP>:<PORT> that outputs:
*   Trying 3.134.148.191...
* TCP_NODELAY set
* Connected to a8154210d09da11ea9c3806983848f2f-1085657314.us-east-2.elb.amazonaws.com (3.134.148.191) port 8080 (#0)
> GET / HTTP/1.1
> Host: a8154210d09da11ea9c3806983848f2f-1085657314.us-east-2.elb.amazonaws.com:8080
> User-Agent: curl/7.63.0
> Accept: */*
>
* Empty reply from server
* Connection #0 to host a8154210d09da11ea9c3806983848f2f-1085657314.us-east-2.elb.amazonaws.com left intact
curl: (52) Empty reply from server
  • nc -v <EXTERNAL-IP> <PORT> that outputs:
found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
    outif en0
    src 172.20.22.42 port 63865
    dst 3.13.128.24 port 8080
    rank info not available
    TCP aux info available

Connection to a8154210d09da11ea9c3806983848f2f-1085657314.us-east-2.elb.amazonaws.com port 8080 [tcp/http-alt] succeeded!

Therefore, I assume that connection works and the service is up and running except I am trying to connect to the Java (.jar) application in the wrong way. Do you have any suggestions?

-- Anuar Maratkhan
amazon-web-services
curl
java
kubernetes

1 Answer

11/20/2019

You should change your dockerfile and change CMD to ENTRYPOINT which is nicely explained here. I would also recommend reading Define a Command and Arguments for a Container.

  • CMD sets default command and/or parameters, which can be overwritten from command line when docker container runs.
  • ENTRYPOINT configures a container that will run as an executable.

Your dockerfile might look like this:

FROM java:8
WORKDIR /
ADD Anuar.jar Anuar.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","Anuar.jar"]

Your service might look like this:

apiVersion: v1
kind: Service
metadata:
  name: javaservice
  labels:
    app: javaservice
spec:
  type: LoadBalancer
  selector:
    app: javaservice
  ports:
  - protocol: TCP
    port: 8080
    name: http

Also it's important which LoadBalancer you want to use as on AWS there is Classic Load Balancer which is default and Network Load Balancer. You can read more about it on Internal load balancer and check the AWS documentation for Load Balancing.

Amazon EKS supports the Network Load Balancer and the Classic Load Balancer through the Kubernetes service of type LoadBalancer. The configuration of your load balancer is controlled by annotations that are added to the manifest for your service.

By default, Classic Load Balancers are used for LoadBalancer type services. To use the Network Load Balancer instead, apply the following annotation to your service:

service.beta.kubernetes.io/aws-load-balancer-type: nlb

For more information about using Network Load Balancer with Kubernetes, see Network Load Balancer support on AWS in the Kubernetes documentation.

By default, services of type LoadBalancer create public-facing load balancers. To use an internal load balancer, apply the following annotation to your service:

service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0

For internal load balancers, your Amazon EKS cluster must be configured to use at least one private subnet in your VPC. Kubernetes examines the route table for your subnets to identify whether they are public or private. Public subnets have a route directly to the internet using an internet gateway, but private subnets do not.

-- Crou
Source: StackOverflow