Microservice in Java (Part-2): Docker container for gRPC server
Notes on Microservice implementation in Java. Creating Docker container for gRPC server. Following the recent trend to containerize the microservice server to make deployments easier using tools like Docker and Kubernetes.
gRPC server
This is part-2 for the Java microservice. Recap of first part:
- We have a hello world greeter service implemented in Java using gradle and spring
- The greeter service would listen to gRPC requests
Main method
To execute Java main method via gradle we need to add a new task in our build.gradle
:
// execute main method for HelloMain
task execute(type:JavaExec) {
main = "com.example.HelloMain"
classpath = sourceSets.main.runtimeClasspath
}
Docker
We want to create Docker image for above service. As a common practice for container images, it should:
- have a base image
- have all java the dependencies while building the image
- start the server on the docker run
- have a tag for versioning the release
We already used gradle for building proto and managing dependencies for Java server, we can use gradle in Docker image as well.
Dockerfile
Above gradle task simplifies the Docker image:
- using java:8 base image to get the Java JDK we would need
- installing gradle in the image
gradle build
would install all the java dependencies- execute above gradle task of main method on docker container start
FROM java:8
RUN mkdir -p /grpc-hello
COPY ./ /grpc-hello
WORKDIR /grpc-hello
RUN apt-get -y update && \
apt-get install -y --no-install-recommends wget unzip
RUN wget https://services.gradle.org/distributions/gradle-3.4.1-bin.zip
RUN mkdir /opt/gradle
RUN unzip -d /opt/gradle gradle-3.4.1-bin.zip
ENV PATH="/opt/gradle/gradle-3.4.1/bin:${PATH}"
RUN gradle build
CMD ["gradle", "execute"]
To build docker image from above Dockerfile:
docker build -f ./tools/Dockerfile
This docker image is published to docker hub: yogin16/grpc-hello
So, to start the grpc server to any server running Docker we will just have to do:
docker pull yogin16/grpc-hello
docker run -p 10000:10000 yogin16/grpc-hello
Docker makes deploying services incredibly simple.
k8s
To use container orchestrator platforms like kubernetes to deploy:
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-hello
labels:
app: grpc-hello
spec:
replicas: 1
selector:
matchLabels:
name: grpc-hello
template:
metadata:
labels:
name: grpc-hello
spec:
containers:
- name: grpc-hello
image: yogin16/grpc-hello:latest
imagePullPolicy: Always
ports:
- containerPort: 10000
service.yaml
kind: Service
apiVersion: v1
metadata:
name: grpc-hello
labels:
app: grpc-hello
spec:
selector:
name: grpc-hello
ports:
- protocol: TCP
port: 10000
targetPort: 10000
name: grpc
type: NodePort
To deploy in kubernetes cluster run:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Above config is updated in the git-repo.
References:
- https://www.sumologic.com/blog/devops/kubernetes-vs-docker/
- https://docs.docker.com/engine/reference/commandline/image_build/
- https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
- https://kubernetes.io/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/
- https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
- https://hub.docker.com/_/java/