Day: May 23, 2023

How to Create a Docker Image for Kubernetes to Deploy


1. What Is a Docker Image?

A Docker image is a read-only, portable template that contains everything required to run your application:

  • Application code
  • Dependencies and libraries
  • Operating system base layer
  • Runtime (Node, Python, Go, etc.)
  • Startup command

Kubernetes uses these images to create containers inside Pods. Therefore, creating a clean, reliable Docker image is the foundation of a successful deployment.


2. Creating a Dockerfile

The first step is writing a Dockerfile. This defines how your application is built. Below is a simple example for a Node.js web application:

# Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install --omit=dev

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

Explanation:

  • FROM node:18-alpine chooses a lightweight base image.
  • WORKDIR /app sets the working directory.
  • COPY and npm install install dependencies.
  • EXPOSE 3000 informs Kubernetes which port the app listens on.
  • CMD runs the application.

3. Building a Docker Image

Once your Dockerfile is ready, build the image:

docker build -t my-app:1.0.0 .

This creates an image called my-app with the version 1.0.0. It is good practice to use semantic versioning or Git commit hashes as tags.


4. Tagging the Image for Your Registry

To deploy to Kubernetes, your image must be stored in a registry such as:

  • Docker Hub
  • GitHub Container Registry
  • Amazon ECR
  • Google Artifact Registry
  • Azure Container Registry

Tag the image with your registry path:

docker tag my-app:1.0.0 myregistry/my-app:1.0.0

5. Pushing the Image to the Registry

Push the image so Kubernetes can pull it:

docker push myregistry/my-app:1.0.0

At this point, your container image is globally accessible to your Kubernetes cluster.


6. Creating a Kubernetes Deployment

Once the image is in the registry, create a Kubernetes Deployment manifest to run the image. Below is a production-ready example:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: production
  labels:
    app: my-app
spec:
  replicas: 3
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
      containers:
        - name: my-app
          image: myregistry/my-app:1.0.0
          ports:
            - containerPort: 3000
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "300m"
              memory: "256Mi"
          readinessProbe:
            httpGet:
              path: /
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 20
          securityContext:
            readOnlyRootFilesystem: true
            allowPrivilegeEscalation: false

7. Applying the Deployment

To deploy your application:

kubectl apply -f deployment.yaml

Kubernetes will:

  • Pull the image from the registry
  • Create Pods
  • Perform a rolling update if an older version exists
  • Attach readiness and liveness probes
  • Maintain the desired replica count

8. Verifying the Deployment

kubectl get deploy my-app -n production
kubectl get pods -n production -o wide
kubectl describe deploy my-app -n production

These commands will confirm that Kubernetes successfully rolled out your new Docker image.

0