Kubernetes has revolutionized the way we deploy and manage applications in the cloud. By offering automated scaling, service discovery, and container orchestration, Kubernetes provides a highly flexible platform for deploying web applications. In this tutorial, we’ll walk through the step-by-step process of deploying a web application on Kubernetes, focusing on setting up persistent storage using AWS EBS volumes.
Introduction: Understanding the Deployment Process
Deploying web applications on Kubernetes involves several critical steps. This guide covers everything from creating a cluster to setting up persistent storage and configuring secrets. In particular, we will focus on utilizing EBS volumes to ensure your application has persistent storage, which is ideal for database management and other stateful services.
Prerequisites: Creating a Kubernetes Cluster with Kops
Before deploying, you need to have a Kubernetes cluster up and running. We will use Kops, a popular tool for managing Kubernetes clusters on AWS.
- Install Kops and AWS CLI:
- Ensure you have Kops installed locally.
- Install the AWS CLI and configure your AWS credentials.
- Create a Kubernetes Cluster:
- Use Kops to create and manage the cluster. Choose an AWS region where your cluster will be hosted.
kops create cluster –name=yourclustername.k8s.local –zones=us-east-1a –state=s3://your-state-store –node-size=t2.micro –node-count=3
kops update cluster –name yourclustername.k8s.local –yes
kops validate cluster
Storage Setup: Provisioning an EBS Volume for Database Persistence
Persistent storage is essential for stateful applications such as databases. AWS EBS volumes provide block storage that is well-suited for this purpose.
- Create an EBS Volume: Go to the AWS Console and provision an EBS volume in the same availability zone as your cluster nodes. Note the volume ID, as you’ll need it later.
- Attach EBS Volume to Kubernetes Pod: Define a PersistentVolume (PV) and PersistentVolumeClaim (PVC) in your Kubernetes YAML manifest to connect the EBS volume to your Kubernetes pod.
Example:
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
– ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
awsElasticBlockStore:
volumeID: vol-xxxxxxxxxxxxxx
fsType: ext4
Node Labeling: Ensuring Node and Volume Zone Alignment
Ensure your EBS volume and node are in the same availability zone for optimal performance.
- Label Nodes by Availability Zone: Use the following command to label your nodes:
kubectl label nodes <node-name> failure-domain.beta.kubernetes.io/zone=us-east-1a - Modify PVC to Match the Zone: Update your PVC definition to ensure it’s deployed on nodes in the same zone:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
– matchExpressions:
– key: failure-domain.beta.kubernetes.io/zone
operator: In
values:
– us-east-1a
Defining Kubernetes Resources: Cloning the Definition Files Repository
Before deploying, ensure that you have the required Kubernetes YAML definition files. Clone the appropriate repository to your local machine or set up your own.
git clone https://github.com/your-repo/k8s-definitions.git
cd k8s-definitions
Secrets Management: Creating and Managing Application Secrets
Secrets in Kubernetes allow you to store sensitive information like database credentials securely.
- Create Secrets: Use Kubernetes secrets to store sensitive information:
kubectl create secret generic mysql-secret –from-literal=password=yourpassword - Access Secrets in Pods: Modify your deployment YAML to pull in the secret:
env:
– name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
Database Deployment: Configuring and Deploying the MySQL Database
Now, let’s deploy a MySQL database using the EBS volume for persistent storage.
- MySQL Deployment: Define a Kubernetes deployment for MySQL with the EBS volume mounted as persistent storage:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
template:
spec:
containers:
– name: mysql
image: mysql:5.7
envFrom:
– secretRef:
name: mysql-secret
volumeMounts:
– name: mysql-pv-storage
mountPath: /var/lib/mysql
volumes:
– name: mysql-pv-storage
persistentVolumeClaim:
claimName: mysql-pvc
Troubleshooting: Resolving EBS Volume Tagging Errors
Check for tagging errors if your EBS volume isn’t attached to your pod. Ensure that the volume’s availability zone matches that of your Kubernetes nodes. Verify tagging with:
kubectl describe pv my-pv
Applying Deployments: Creating Remaining Kubernetes Resources
After setting up the database, deploy the remaining application components using kubectl apply:
kubectl apply -f web-app-deployment.yaml
This file should define your web application’s deployment and service, exposing the app to the internet.
Load Balancer Access: Testing the Deployed Application
Kubernetes automatically provisions an AWS Elastic Load Balancer (ELB) when you deploy a service of type LoadBalancer. Check the external IP of the service using:
kubectl get svc
Visit the external IP address in a browser to ensure the application is up and running.
Domain Configuration: Setting up Custom Domain for Access
Configure a custom domain with AWS Route 53 to provide a user-friendly URL. Point your domain to the ELB using a CNAME record.
- Create a Hosted Zone in Route 53:
- Add a record pointing to the ELB’s DNS name.
- Verify Domain Setup: Use dig or an online DNS tool to verify that your domain points to the correct ELB.
Cleaning Up Resources: Deleting the Cluster and Associated Resources
Clean your environment once you’ve tested everything and no longer need the resources.
- Delete the Kubernetes Cluster:
kops delete cluster –name yourclustername.k8s.local –yes - Remove EBS Volumes: Ensure that all persistent volumes are deleted to avoid unwanted charges.
Conclusion
Deploying a web application on Kubernetes with persistent storage can seem daunting, but following these steps will quickly give you a robust, scalable setup. With EBS volumes providing persistence for stateful applications, your deployment becomes more reliable and efficient.