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