I have configured Kubernetes service (of type LoadBalancer
) hosted on AWS EKS. The service's pods run in interactive mode (which is needed to run the container in the pod). The container in there is running a simple Java .jar application that receives input and produces output based on that.
The question: how can I pass input to Java application inside the Kubernetes container?
Here is the part of yaml configuration of the pod that ensures it runs in an interactive mode:
spec:
containers:
- image: ardulat/mckinsey
imagePullPolicy: Always
name: anuar-mckinsey
ports:
- containerPort: 8080
name: http
protocol: TCP
stdin: true
tty: true
The pod is up and running. As you see from the configuration, it receives TCP connections.
Here is the service of the pod:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
anuar-mckinsey LoadBalancer 10.100.239.207 a8154210d09da11ea9c3806983848f2f-1085657314.us-east-2.elb.amazonaws.com 8080:32516/TCP
I can ensure that the pod and service are configured correctly by looking at the logs of the pod that output a print message from Java application in the container.
Already tried:
* Trying 18.190.142.22...
* TCP_NODELAY set
* Connected to a8154210d09da11ea9c3806983848f2f-1085657314.us-east-2.elb.amazonaws.com (18.190.142.22) 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
found 1 connections:
1: flags=82<CONNECTED,PREFERRED>
outif en0
src 172.20.22.204 port 51144
dst 18.190.142.22 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!
Final thoughts: so it seems like the configurations are right and the service runs on the cluster hosted on AWS EKS. The logs produce the right output. However, I can't send the message (through TCP connection?) to the Java application inside the container. Any thoughts on how I can pass the input to it?
If you are using docker for building your kubernetes image, then you can use ENTRYPOINT or CMD attributes in your docker file for passing arguments while launching your application. Please refer below link for more information.
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
You can use environment variables to define the arguments.
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]
And you just defined an argument for your kubernetes pod here.
Besides it would be good to configure your pods to use a configMap or Secrets.
Based on the discussion in comments, the information was that the Java application uses System.in
to receive the input. That is usually equivalent to stdin
.
A way to send input to the application in the container and get output is by attaching to the process in the container in raw terminal mode, which connects the local stdin
and stdout
with the container's:
kubectl -n <namespace> attach <pod-name> -c <container-name> -i -t
On the additional question about how to access the application from the outside without accessing pods directly and by using a Service, I'll suggest:
ServerSocket
to listen and accept connections at a particular port number.System.in
.This here could be a good starting point for the new code. You can use telnet 127.0.0.1 <port>
or curl telnet://127.0.0.1:<port>/
to test the application locally and when not running it in a container.
Exposing an HTTP-based service instead, in my opinion, seems like an overkill for this application.