How to deploy Docker Compose stacks on Kubernetes with Kompose – CloudSavvy IT

Illustration showing the Docker and Kubernetes logos

Docker Compose allows you to define stacks of containers that you can collectively manage. It’s a relatively straightforward tool that originally focused on local Docker installations.

Kubernetes is a container orchestrator that comes with its own toolchain and manifest files. It is generally considered more complex than a typical Docker workflow, but its capabilities facilitate scalable container deployments in production.

Compose is a tool that allows you to take Docker Compose files and deploy them to Kubernetes clusters. It is developed as part of the Kubernetes project.

Current versions of Kompose are limited to conversions of YAML files. You need to apply the converted Kubernetes resource manifests to your cluster using a tool such as Kubectl. Older versions of Kompose had a up command that could deploy directly to your cluster without an intermediate conversion step. This was eliminated due to increasing technical complexity.

To start

Kompose is available for Windows, macOS, and the most popular Linux distributions. The pre-built binaries are available from its GitHub repository. Download the latest version, set the executable permission bit, and move the binary to a directory that is in your path. Multiple package managers are also supported.

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

Try to run kompose in your terminal. You will see some basic information about the available commands. In progress kompose version checks which version of Kompose you are using.

Now make sure you have a docker-compose.yml file available. Here is a basic example that sets up an Apache web server with a MySQL database:

version: "3"

services:
  apache:
    image: httpd:latest
    ports:
      - 80:80
  mysql:
    image: mysql:latest
    expose:
      - 3306
    volumes:
      - mysql:/var/lib/mysql

volumes:
  mysql:

You also need a Kubernetes cluster to deploy to. Create a new cluster with a public cloud provider or create your own using a project like MicroK8s.

Converting your stack

the kompose convert The command accepts the path to a Docker Compose file and issues equivalent Kubernetes resource manifests. He uses the docker-compose.yml in your working directory when no path is specified. Several files are accepted via the -f flag.

kompose convert -f docker-compose.yml -f docker-compose-dev.yml

You will see a few lines of output as Kompose writes manifest files for each of the resources in your Compose stack. Individual files are created for each component of your docker-compose.yml. They will be placed in your working directory.

Here is the result of the conversion of the docker-compose.yml shown above:

A Kubernetes deployment and service have been created for each of the Compose services. These resources define the Pods to be created as well as their network routing rules.

A PersistentVolumeClaim also exists for the MySQL container. This represents the volume configured in the docker-compose.yml, providing persistent storage for the MySQL database that outlasts any individual pod.

If you inspect the YAML files, you will see that they are only Kubernetes manifests compatible with Kubectl. Here is the convert apache-deployment.yaml file:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kompose.cmd: kompose convert
    kompose.version: 1.23.0 (bc7d9f4f)
  creationTimestamp: null
  labels:
    io.kompose.service: apache
  name: apache
spec:
  replicas: 1
  selector:
    matchLabels:
      io.kompose.service: apache
  strategy: {}
  template:
    metadata:
      annotations:
        kompose.cmd: kompose convert
        kompose.version: 1.23.0 (bc7d9f4f)
      creationTimestamp: null
      labels:
        io.kompose.service: apache
    spec:
      containers:
        - image: httpd:latest
          name: apache
          ports:
            - containerPort: 80
          resources: {}
      restartPolicy: Always
status: {}

The deployment spec is quite similar to the definition of the Apache container in the original docker-compose.yml. In the case of this simple service, it is easily mapped to a Kubernetes object. The rest of the file is mostly about defining metadata, including Kompose-specific annotations that allow you to identify resources created with the tool.

Deployment on your cluster

Deploy the manifest fileset in the usual way with kubectl apply. It is a good idea to store them in a directory separate from your docker-compose.yml, so that kubectl also do not try to choose this incompatible file.

kubectl apply .

The resources will be provisioned inside your cluster. It may take a few minutes for your services to complete. Inspect your deployment with kubectl get deployments. When the AVAILABLE column shows 1, your workload must be accessible.

Now you can update your deployment by modifying the generated manifests and rerunning kubectl apply. If you wanted to scale Apache to three replicas, you would open apache-deployment.yaml, change the replicas field to 3, and apply the modified manifesto.

You can also continue to update your Docker Compose file. Course kompose convert again to get the latest Kubernetes interpretation of its contents, then reapply the output to your cluster. Be aware that this will overwrite any changes you have manually applied since.

Limits

Kompose generally works well with Docker Compose files using the most common features and best practices. It can create containers, expose ports, and provide persistent storage through volumes.

However, not all conversions will be perfect. Some features of Compose do not have a direct equivalent in the Kubernetes world, while others will be mapped in a way that might not meet your needs. The use of deployments and services in this example is an example: if you were deploying directly to Kubernetes, you can use an Ingress rule to expose your service, but it is not created by Kompose. Opinion decisions are resolved by taking the simplest option.

You will also encounter volume-related issues. Docker Compose files can link host mount files and folders in containers. This is not possible with Kubernetes, so you will need an alternative solution. Additionally, although Kompose can create resources for PersistentVolumeClaims, it will not create the actual PersistentVolumes. You must have a volume already available in your cluster before attempting to deploy your manifests.

A complete table of supported features and conversion details is offered as part of the Kompose documentation. It’s worth checking that the Docker Compose features you’re using are supported before you start any conversion effort.

Conclusion

Kompose simplifies the migration from Docker Compose to a Kubernetes cluster. It automates steps that were previously tedious, time-consuming, and error-prone. It is a good functional aid, but it is not a tool that should be used without some degree of supervision.

Kompose conversions are not universally applicable, so they will not be suitable for all environments. It is always worth checking any issued manifests before applying them to your cluster. In some cases, it is better to use Kompose as a reference — convert your docker-compose.yml, see what the result is, then use that as a starting point to create manifests that are fully compatible with your application and cluster.

Leave a Comment