I have a little java project that needs to be deployed with kubernetes. After studying kubernetes for a little while, I have two questions.
Since the projects needs beside the java app, rabbitmq and redis, clearly those three thing need to have three docker images.
1.) Can I put the java app, rabbitmq and redis containers/images into a single pod or should they be in separete pods (I was advised to put them on the same pod)?
Since this is a java app (with a build .jar file) is has a foobar.conf file that has the configurations for the app, like the redis/rabbitmq hostnames and ports and other stuff in it.
rabbitmq{
host="$RABBITMQ_HOSTNAME"
username="rabbitmq"
password="rabbitmq"
status-queue-name="foobar-status"
audit-queue-name="foobar-audit"
event-queue-name="foobar-events"
incoming-messages-queue-name="foobar-incoming-messages"
acknowledge-queue-name="foobar-acknowledge"
}
So, how do I expose the redis and rabbitmq containers ports and hostnames (when they spin up) to the foobar.conf files for the app?
Tnx, Tom
Yes, you will need three docker images one for each of the components of your application stack - application, redis and rabbitmq. Also, it is a good idea to put all of those components in a single pod. Microservices usually will need sidecars to fully function and Kubernetes pods exist just to address that need.
But please note that docker containers are stateless in nature. So, if kubernetes decides to move your pod to a different node, then the containers running your service will be destroyed and will be recreated on a different node. All the data that is written to the local filesystem inside the container by any of the three components is lost in the process. If you are aware of that and you have designed your app to be stateless then you should be alright. If not, please explore persistent volumes in kubernetes to preserve the state of your pods when they are moved around. You can find more information on configuring your pod to use persistent volumes here
To answer your second question, there is bunch of ways you can configure your app to communicate with rabbitmq and redis services. Since all the containers in a pod have the same IP and share the same port namespace, you can literally configure the other two services to talk on localhost and standard ports for those two services. However, if you decide to expose those two services to other service with in the cluster network you can still do so by using the pod ip and the ports that you start those two services on.
If you want to expose those two services outside your cluster network, you have to do so via kubernetes services of type NodePort.
Hope that helps.
If you should place all three services within one Pod or not depends on how you would scale the application.
For example, if you would like to run a second instance of the Java application, would each app instance use it's "private" RabbitMQ and Redis (an all-in-one Pod is fine), or would the instances share RabbitMQ and/or Redis?
As soon as one component is shared between several instances, it should run in an own Pod and be exposed (within the namespace) via a Service.
Finally: if you don't know whether the application needs scaling in the future, plan for scaling at day 0 (it's easier than to redo things later).