Migrate docker-compose to k8s

Steps to go from a docker-compose file, to build an Image out of the file, upload it to DockerHub, and run it with Kubernetes (minikube).

Set up

Install Kompose

# linux
curl -L https://github.com/kubernetes/kompose/releases/download/v1.22.0/kompose-linux-amd64 -o kompose
chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose

Clone App and Host It into DockerHub

Clone the files, go to the directory where your Dockerfile is and run:

# mariocodes is my DockerHub username
# kubernetes-custom-java-maven-app is the name of the repo I created at DockerHub
docker build -f Dockerfile -t mariocodes/kubernetes-custom-java-maven-app .

Now if you do

docker images

You should see the image that was created. Log-in to DockerHub.

docker login -u mariocodes

Once we have a working Image on DockerHub

Translate Compose services to K8s Objects

We already have kompose installed and a docker-compose.yml file. A docker-compose file, lays out definitions to run services, A service in compose is a running container. We need to convert these services to K8s objects.

Before converting our resources, we may need to modify our existing files. First, we need the image to point to our DockerHub uploaded image instead of a local one, if this was the case. Edit the docker-compose.yaml file:

# old, local version.
image: my-java-app:0.0.1

# changed for remote DockerHub uploaded image. 
image: mariocodes/kubernetes-custom-java-maven-app 
# append at the same level than image.
restart: always 

# also remove 'volumes' list and 'command' instruction.

Run this command at the same carpet docker-compose.yaml is hosted. It will convert compose file into a kubernetes one.

kompose convert

(If this didn’t work, it may be needed to remove the build: section, if present, from *docker-compose.yaml, before running kompose convert)*.

Now, for this case, this is web service app, kompose created a service, but this service includes an internal ClusterIP, we need a NodePort to be able to communicate with the app from outside the cluster to do a curl. Modify the service file and add this:

spec:
  # add this line
  type: NodePort
  ports:
  - name: "4001"
    port: 4001
	targetPort: 8080
	# add this too
	nodePort: 31500

Now run:

# only if it wasn't started yet as multinode - this avoids work on master
minikube start --nodes 2 -p multinode-demo

# see status
minikube status -p multinode-demo

kubectl apply -f <created_output_files>,<created_output_files>

# annotate the PORT. It should be 31500 (or the one we set before).
kubectl get svc
# annotate the INTERNAL-IP (in the range 192.168.x.x)
kubectl get nodes -o wide

# execute a CURL for the previous notes IP:Port/endpoint
curl http://192.168.49.2:31500/my-java-app/hello-world

Reference(s)

https://www.digitalocean.com/community/tutorials/how-to-migrate-a-docker-compose-workflow-to-kubernetes
https://minikube.sigs.k8s.io/docs/tutorials/multi_node/
https://hub.docker.com/repository/docker/mariocodes/kubernetes-custom-java-maven-app