Deploying Containerized Applications to Kubernetes

Kubernetes is an open-source system designed for automating the deployment, scaling, and management of containerized applications. This blog will delve into the technical aspects of deploying containerized applications to Kubernetes, focusing on key concepts, configurations, and practical examples.

Kubernetes Architecture

Kubernetes operates on a cluster model, consisting of a master node and multiple worker nodes. The master node is responsible for managing the cluster's state and orchestrating operations such as scheduling containers, scaling applications, and handling failovers. Worker nodes run the containers and communicate with the master node for instructions and updates.

Master Node

The master node includes several key components:

  • API Server: Handles incoming API requests.

  • Controller Manager: Runs and manages control plane components.

  • Scheduler: Assigns pods to nodes.

  • etcd: Distributed key-value store for cluster data.

Worker Nodes

Worker nodes run the application workloads and are managed by the master node. Each worker node includes:

  • Kubelet: Ensures that containers are running in a pod.

  • Kube-proxy: Handles network traffic and load balancing.

  • Container Runtime: Executes containers (e.g., Docker).

Pods

A pod is the smallest deployable unit in Kubernetes. It represents one or more containers that are tightly coupled and share the same resources such as network and storage.

Example Pod Configuration

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx:latest

This YAML configuration defines a pod named my-pod with a single container named my-container running the latest version of the Nginx web server image.

ReplicaSets and Deployments

ReplicaSets ensure a specified number of replicas (identical pods) are running at any given time. Deployments manage ReplicaSets and provide features like rolling updates and rollbacks.

Example ReplicaSet Configuration

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest

This configuration defines a ReplicaSet named my-replicaset with three replicas of a pod labeled my-app.

Example Deployment Configuration

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest

This deployment configuration ensures that three replicas of the pod are running and provides the ability to perform rolling updates and rollbacks.

Rolling Back Deployments

Kubernetes allows rolling back to a previous version of a deployment if issues occur. This can be done using the kubectl command:

kubectl rollout undo deployment/my-deployment

This command rolls back the deployment named my-deployment to the previous stable version.

Service Discovery and Load Balancing

Kubernetes provides service discovery and load balancing capabilities. Services can be exposed using DNS names or IP addresses, and Kubernetes can distribute network traffic to ensure deployment stability.

Example Service Configuration

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - name: http
    port: 80
    targetPort: 80
  type: LoadBalancer

This configuration defines a service named my-service that selects pods labeled my-app and exposes port 80.

Storage Orchestration

Kubernetes allows automatic mounting of storage systems, including local storage, public cloud providers, and network storage systems like iSCSI or NFS.

Example Persistent Volume Claim (PVC) Configuration

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

This configuration defines a PVC named my-pvc requesting 5GB of storage.

Automated Rollouts and Rollbacks

Kubernetes can progressively roll out changes to your application or its configuration while monitoring application health. If issues occur, Kubernetes can roll back the changes.

Example Deployment with Rollout Strategy

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1

This configuration defines a deployment with a rolling update strategy, allowing for controlled rollouts and rollbacks.

Platform Engineering Considerations

When deploying containerized applications to Kubernetes, platform engineering teams must ensure that the infrastructure is properly configured and managed. This includes setting up the cluster, managing node resources, and implementing continuous integration and continuous delivery (CI/CD) pipelines.

CI/CD Pipelines

CI/CD pipelines are crucial for automating the build, test, and deployment of containerized applications. Tools like Jenkins, GitLab CI/CD, or GitHub Actions can be integrated with Kubernetes to automate these processes.

Example CI/CD Pipeline Using Jenkins

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'docker build -t my-app .'
            }
        }
        stage('Push') {
            steps {
                sh 'docker tag my-app:latest <your-docker-registry>/my-app:latest'
                sh 'docker push <your-docker-registry>/my-app:latest'
            }
        }
        stage('Deploy') {
            steps {
                sh 'kubectl apply -f deployment.yaml'
            }
        }
    }
}

This Jenkinsfile defines a CI/CD pipeline that builds a Docker image, pushes it to a registry, and deploys it to Kubernetes using a deployment YAML file.

Automated Testing

Automated testing is essential for ensuring the reliability and performance of containerized applications. Tools like K6 and Locust can be used to simulate user traffic and measure system performance under load.

Example K6 Test Script

import http from 'k6/http';
import { sleep, check } from 'k6';

export let options = {
  stages: [
    { duration: '30s', target: 20 },
    { duration: '1m', target: 20 },
    { duration: '30s', target: 0 },
  ],
};

export default function () {
  let res = http.get('https://my-app.example.com');
  check(res, { 'status was 200': (r) => r.status === 200 });
  sleep(1);
}

This K6 test script simulates a load test scenario, checking the status code of the response and ensuring it is 200.

Conclusion

Deploying containerized applications to Kubernetes involves understanding the architecture, configuring pods, ReplicaSets, and deployments, and implementing automated rollouts, rollbacks, and testing. By leveraging these features, platform engineering teams can ensure efficient, scalable, and reliable deployments of their applications.