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.