1. Overview

When dealing with containerized applications, we might want to know what roles Docker Compose and Kubernetes play in this context.

In this tutorial, we’ll discuss some of the most common use cases to see the difference between the two.

2. Docker Compose

Docker Compose is a command-line tool to run multiple Docker containers with a YAML template definition. We can build containers from existing images or a specific context.

We can add a version of the compose file format and at least one service. Optionally, we can add volumes and networks. Also, we can define dependencies and environment variables.

2.1. Docker Compose Template

Let’s create a docker-compose.yml file for an API connecting to a PostgreSQL database:

version: '3.8'
services:
  db:
    image: postgres:latest
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - '5432:5432'
    volumes: 
      - db:/var/lib/postgresql/data
    networks:
      - mynet

  api:
    container_name: my-api
    build:
      context: ./
    image: my-api
    depends_on:
      - db
    networks:
      - mynet
    ports:
      - 8080:8080
    environment:
      DB_HOST: db
      DB_PORT: 5432
      DB_USER: postgres
      DB_PASSWORD: postgres
      DB_NAME: postgres

networks:
  mynet:
    driver: bridge

volumes:
  db:
    driver: local

Finally, we can start working locally or in production by running:

docker-compose up

2.2. Docker Compose Common Use Cases

We commonly use Docker Compose to create a microservice infrastructure environment that links different services over a network.

In addition, Docker Compose is widely used to create and destroy isolated testing environments for our test suites.

Moreover, if we are interested in scalability, we can look at Docker Swarm — a project created by Docker to work at the orchestration level like Kubernetes.

However, compared to Kubernetes, Docker Swarm has limited offerings.

3. Kubernetes

With Kubernetes (also referred to as K8s), we automate the deployment and management of applications in a containerized and clustered environment. Google’s initial work on K8s went from open-source to a donation to the Linux Foundation and eventually as a seed technology to start the Cloud Native Computing Foundation (CNCF).

In the container era, Kubernetes got significant attention to such an extent that it’s now the most popular distributed system orchestrator.

A complete API is available to describe the specifications and status of Kubernetes’ Objects. It also allows integration with third-party software.

In Kubernetes, different components are part of a cluster that consists of a set of worker machines called Nodes. The Nodes are running our containerized applications inside Pods.

Kubernetes is all about managing artifacts deployed in Pods on virtual machines or Nodes. The Nodes and the containers they run are all grouped as a cluster, and each container has endpoints, DNS, storage, and scalability.

Pods are nonpermanent resources. For example, a Deployment can create and destroy them dynamically. Usually, we can expose applications as Services to always be available at the same endpoint.

3.1. Kubernetes Template

Kubernetes provides a declarative or imperative approach, so we can use templates to create, update, delete or even scale Objects. As an example, let’s define a template for a Deployment:

-- Postgres Database
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgresql
  namespace: Database
spec:
  selector:
    matchLabels:
      app: postgresql
  replicas: 1
  template:
    metadata:
      labels:
        app: postgresql
    spec:
      containers:
        - name: postgresql
          image: postgresql:latest
          ports:
            - name: tcp
              containerPort: 5432
          env:
            - name: POSTGRES_USER
              value: postgres
            - name: POSTGRES_PASSWORD
              value: postgres
            - name: POSTGRES_DB
              value: postgres
          volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: postgredb
      volumes:
        - name: postgredb
          persistentVolumeClaim:
            claimName: postgres-data

-- My Api
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-api
  namespace: Api
spec:
  selector:
    matchLabels:
      app: my-api
  replicas: 1
  template:
    metadata:
      labels:
        app: my-api
    spec:
      containers:
        - name: my-api
          image: my-api:latest
          ports:
            - containerPort: 8080
              name: "http"
          volumeMounts:
            - mountPath: "/app"
              name: my-app-storage
          env:
            - name: POSTGRES_DB
              value: postgres
            - name: POSTGRES_USER
              value: postgres
            - name: POSTGRES_PASSWORD
              value: password
          resources:
            limits:
              memory: 2Gi
              cpu: "1"
      volumes:
        - name: my-app-storage
          persistentVolumeClaim:
            claimName: my-app-data

We can then use objects over the network with the kubectl command line.

3.2. Kubernetes and Cloud Providers

Kubernetes is not Infrastructure-as-Code (IaC) itself. However, it integrates with cloud providers’ container services — for example, ECS or EKS by Amazon, GKE by Google, and OpenShift by RedHat.

Or we can use it, for instance, with tools like Helm.

We do commonly see Kubernetes in public cloud infrastructures. However, we can set up Minikube or a local Kubeadm cluster.

Also approved by CNCF, we can checkout K3s, a lightweight version of K8s.

4. Differences Between Kubernetes and Docker Compose

While Docker Compose is about creating and starting one or multiple containers, Kubernetes serves more as a platform to create a network where we can orchestrate containers.

Kubernetes has been able to facilitate many crucial problems in applications management:

  • Resource optimization
  • Self-healing of containers
  • Downtimes during applications redeployment
  • Auto-scaling

Finally, Kubernetes takes multiple isolated containers to a stage where resources are always available with the potential optimal distribution.

However, when it comes to development, Docker Compose can configure all the application’s service dependencies to get started with, for example, our automated tests. So, it’s a powerful tool for local development.

5. Conclusion

In this article, we’ve seen the difference between Docker Compose and Kubernetes. Docker Compose can help when we need to define and run multi-container Docker applications.

Kubernetes is a powerful yet complex framework for managing containerized applications in a clustered environment.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.