Migrate a Docker Compose to Kubernetes

Tiempo de lectura: 5 minutos

Today, we’re going to learn, with an example, how to migrate a Docker Compose (https://www.docker.com/) setup to Kubernetes (https://kubernetes.io/).

First, let me explain what the two mentioned technologies are:

Docker Compose:

Docker Compose is a tool that allows you to define and run multi-container Docker applications. With Docker Compose, you can describe the entire configuration of your services, networks, and volumes in a YAML file (docker-compose.yaml). This file can contain information about container images, exposed ports, environment variables, shared volumes, and more. By using docker-compose up, you can easily start and deploy a multi-container application in your local environment.

An example docker-compose.yaml for a web application and a MySQL database might look like this:

version: '3'
services:
  webapp:
    image: your-webapp-image:latest
    ports:
      - "8080:80"
  database:
    image: your-mysql-image:latest
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: mydatabase
      MYSQL_USER: user
      MYSQL_PASSWORD: password

Kubernetes:

Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and operation of containerized applications. It enables the management and orchestration of containers in clusters, facilitating the deployment and management of distributed and scalable applications.

In Kubernetes, you define application resources such as Pods (container instances), Deployments (sets of Pods), Services (entry points to the application), ConfigMaps (configurations), and more, using YAML or JSON configuration files.

Differences and Joint Use:

  • Docker Compose is for local development: Docker Compose is excellent for local development environments, where you can easily define and test your multi-container applications. You can use it to create consistent environments among developers and quickly deploy applications on a single host.
  • Kubernetes is for production orchestration: Kubernetes is ideal for production environments and scenarios where you need to manage applications in server clusters. It provides advanced features such as automatic scaling, self-healing, zero-downtime version deployment, and resource management.
  • Joint Use: Docker Compose is often used to develop and test applications locally, and then migrated to Kubernetes for deployment in production environments. Tools like kompose can assist in converting Docker Compose files to Kubernetes configurations, facilitating the transition between development and production environments.

Now let’s provide an example to see how we can transition our Docker Compose to Kubernetes configuration:

Assume you have an application composed of two services in your Docker Compose: a web service named “webapp” and a database named “database.” Here is the original Docker Compose:

version: '3'
services:
  webapp:
    image: your-webapp-image:latest
    ports:
      - "8080:80"
  database:
    image: your-database-image:latest
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: mydatabase
      MYSQL_USER: user
      MYSQL_PASSWORD: password

*Yes, it’s the code from the first example.

Step 1: Preparation

Before you start, make sure you have Kubernetes installed in your local environment. You can use tools like Minikube or Docker Desktop with Kubernetes support (https://devcodelight.com/install-docker-and-docker-compose-on-oracle-linux/). You will also need kubectl, the Kubernetes command-line tool.

Step 2: Convert Docker Compose to Kubernetes

html
Copy code
2.1 Convert docker-compose.yaml to Kubernetes Resources

Split your docker-compose.yaml file into several Kubernetes configuration files: one for each service. You can create separate files for Deployment and Service.

Remember, for it to be usable in Kubernetes, your Docker image should be built and hosted or use an already hosted one (https://devcodelight.com/deploy-a-docker-image-server-in-a-docker-compose-docker-registry/).

For example, for a service named “webapp”:

webapp-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: your-webapp-image:latest
        ports:
        - containerPort: 80

webapp-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  selector:
    app: webapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

database-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: database
spec:
  replicas: 1
  selector:
    matchLabels:
      app: database
  template:
    metadata:
      labels:
        app: database
    spec:
      containers:
      - name: database
        image: your-database-image:latest
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpass
        - name: MYSQL_DATABASE
          value: mydatabase
        - name: MYSQL_USER
          value: user
        - name: MYSQL_PASSWORD
          value: password

database-service.yaml

docker-compose.yaml to Kubernetes Resources

Split your docker-compose.yaml file into several Kubernetes configuration files: one for each service. You can create separate files for Deployment and Service. Remember, for it to be usable in Kubernetes, your Docker image should be built and hosted or use an already hosted one (

https://devcodelight.com/deploy-a-docker-image-server-in-a-docker-compose-docker-registry/

). For example, for a service named "webapp":

webapp-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: your-webapp-image:latest
        ports:
        - containerPort: 80

webapp-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  selector:
    app: webapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

database-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: database
spec:
  replicas: 1
  selector:
    matchLabels:
      app: database
  template:
    metadata:
      labels:
        app: database
    spec:
      containers:
      - name: database
        image: your-database-image:latest
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpass
        - name: MYSQL_DATABASE
          value: mydatabase
        - name: MYSQL_USER
          value: user
        - name: MYSQL_PASSWORD
          value: password

database-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: database
spec:
  selector:
    app: database
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

Now apply these files to the Kubernetes cluster:

kubectl apply -f webapp-deployment.yaml
kubectl apply -f webapp-service.yaml
kubectl apply -f database-deployment.yaml
kubectl apply -f database-service.yaml

2.2 Convert Environment Variables

If your Docker Compose uses environment variables, make sure to convert them to equivalent configurations in Kubernetes. In the above example, the environment variables for the database service were converted like this:

database-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: database
spec:
  replicas: 1
  selector:
    matchLabels:
      app: database
  template:
    metadata:
      labels:
        app: database
    spec:
      containers:
      - name: database
        image: your-database-image:latest
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpass
        - name: MYSQL_DATABASE
          value: mydatabase
        - name: MYSQL_USER
          value: user
        - name: MYSQL_PASSWORD
          value: password

Step 3: Apply Configurations in Kubernetes

Apply the converted configurations to your Kubernetes cluster using kubectl:

kubectl apply -f webapp-deployment.yaml
kubectl apply -f webapp-service.yaml
kubectl apply -f database-deployment.yaml
kubectl apply -f database-service.yaml

Step 4: Verify the Status

Use the following commands to verify that your resources have been deployed successfully:

kubectl get pods
kubectl get services
kubectl get deployments

Done!

You have successfully migrated your Docker Compose system to Kubernetes! You can access your application through the IP address or service name provided by Kubernetes for the “webapp” service. Remember to adjust these steps according to the specific needs of your application.

Note: How to stop the created pods.

To stop (or more precisely, delete) pods in Kubernetes, you can use the kubectl delete pod command. Here are some ways to do it:

Stop a Single Pod:</html Copy code

kubectl delete pod POD_NAME

Replace POD_NAME with the name of the pod you want to stop.

Stop All Pods in a Specific Namespace:

kubectl delete pods --all -n NAMESPACE_NAME

Replace NAMESPACE_NAME with the name of the namespace where you want to stop all pods.

Stop All Pods in All Namespaces:

kubectl delete pods --all --all-namespaces

This command will delete all pods in all namespaces.

Keep in mind that when you delete a pod, Kubernetes will attempt to create a new pod to maintain the desired state. If you want to stop a pod and prevent it from being replaced, you can scale the number of replicas of the deployment or replica set to zero, but be careful when doing this in production environments.

Scale Replicas to Zero to Stop a Deployment:

kubectl scale deployment DEPLOYMENT_NAME --replicas=0 -n NAMESPACE_NAME

Replace DEPLOYMENT_NAME and NAMESPACE_NAME with the appropriate names.

Note that these operations will delete the pods, and if you have a replication controller configured, new pods will be created to maintain the desired number. If you want to completely stop an application, you may need to unmount or delete related resources such as services and deployments.

Another option is to modify the number of replicas within the pod and set them to 0:

metadata:
  name: webapp
spec:
  replicas: 0

And then apply it:

kubectl apply -f webapp-deployment.yaml

Leave a Comment