The Nautilus application development team observed some performance issues with one of the application that is deployed in Kubernetes cluster. After looking into number of factors, the team has suggested to use some in-memory caching utility for DB service. After number of discussions, they have decided to use Redis. Initially they would like to deploy Redis on kubernetes cluster for testing and later they will move it to production. Please find below more details about the task:
Create a redis deployment with following parameters:
Create a
config mapcalledmy-redis-confighavingmaxmemory 2mbinredis-config.Name of the
deploymentshould beredis-deployment, it should use
redis:alpineimage and container name should beredis-container. Also make sure it has only1replica.The container should request for
1CPU.Mount
2volumes:
a. An Empty directory volume calleddataat path/redis-master-data.
b. A configmap volume calledredis-configat path/redis-master.
c. The container should expose the port6379.Finally,
redis-deploymentshould be up and running.
Understanding Redis
What is Redis?
Redis (REmote DIctionary Server) is an open-source, in-memory data structure store. It supports various data structures including strings, hashes, lists, sets, and sorted sets. Redis is commonly used for:
- Caching: Reducing database load by storing frequently accessed data
- Session Management: Storing user session data
- Real-time Analytics: Counting, ranking, and aggregation
- Message Queuing: Pub/Sub messaging patterns
- Rate Limiting: API request throttling
Why Use Redis on Kubernetes?
Deploying Redis on Kubernetes provides:
- Scalability: Easy to scale horizontally with replicas
- Resilience: Self-healing through Kubernetes pod management
- Configuration Management: Using ConfigMaps for Redis configuration
- Storage Management: Persistent volumes for data persistence
- Service Discovery: Built-in service discovery through Kubernetes services
What We Will Build
Task Overview
| Component | Specification |
|---|---|
| ConfigMap |
my-redis-config with maxmemory 2mb
|
| Deployment Name | redis-deployment |
| Image | redis:alpine |
| Container Name | redis-container |
| Replicas | 1 |
| CPU Request | 1 |
| Volume 1 | EmptyDir data at /redis-master-data
|
| Volume 2 | ConfigMap redis-config at /redis-master
|
| Port | 6379 |
Architecture Diagram
┌─────────────────────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ ConfigMap: my-redis-config │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ redis-config: | │ │ │
│ │ │ maxmemory 2mb │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Deployment: redis-deployment │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Pod: redis-deployment-xxxxxxxxxx-xxxxx │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ Container: redis-container │ │ │ │
│ │ │ │ Image: redis:alpine │ │ │ │
│ │ │ │ Port: 6379 │ │ │ │
│ │ │ │ CPU Request: 1 │ │ │ │
│ │ │ │ VolumeMounts: │ │ │ │
│ │ │ │ - data → /redis-master-data │ │ │ │
│ │ │ │ - redis-config → /redis-master │ │ │ │
│ │ │ └────────────────────────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ▼ │ │
│ │ │ Volumes: │ │
│ │ │ - data: emptyDir │ │
│ │ │ - redis-config: ConfigMap (my-redis-config) │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Redis Service (Optional) │
│ Port: 6379 │
└─────────────────────────────────────────────────────────────────────────────┘
Step-by-Step Implementation
Step 1: Create the ConfigMap
ConfigMaps store configuration data that can be consumed by pods. For Redis, we can store the maxmemory configuration.
cat > redis-configmap.yaml << 'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: my-redis-config
data:
redis-config: |
maxmemory 2mb
EOF
Explanation:
-
apiVersion: v1– ConfigMap API version -
kind: ConfigMap– Resource type -
metadata.name: my-redis-config– ConfigMap name -
data.redis-config– Configuration content for Redis
Step 2: Create the Deployment
The deployment defines the Redis pod specification, including volumes, volume mounts, and container configuration.
cat > redis-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis-container
image: redis:alpine
ports:
- containerPort: 6379
resources:
requests:
cpu: 1
volumeMounts:
- name: data
mountPath: /redis-master-data
- name: redis-config
mountPath: /redis-master
volumes:
- name: data
emptyDir: {}
- name: redis-config
configMap:
name: my-redis-config
EOF
YAML Breakdown
Deployment Metadata:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
Pod Template:
template:
metadata:
labels:
app: redis
spec:
Container Specification:
containers:
- name: redis-container
image: redis:alpine
ports:
- containerPort: 6379
resources:
requests:
cpu: 1
Volume Mounts:
volumeMounts:
- name: data
mountPath: /redis-master-data
- name: redis-config
mountPath: /redis-master
Volumes:
volumes:
- name: data
emptyDir: {}
- name: redis-config
configMap:
name: my-redis-config
Step 3: Apply the Configurations
kubectl apply -f redis-configmap.yaml
kubectl apply -f redis-deployment.yaml
Output:
configmap/my-redis-config created
deployment.apps/redis-deployment created
Step 4: Verify the Deployment
kubectl get deployments
Output:
NAME READY UP-TO-DATE AVAILABLE AGE
redis-deployment 1/1 1 1 10s
Step 5: Verify the Pod
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
redis-deployment-c795495f4-vjfpl 1/1 Running 0 10s
Step 6: Verify the ConfigMap
kubectl describe configmap my-redis-config
Output:
Name: my-redis-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
redis-config:
----
maxmemory 2mb
Step 7: Verify Volume Mounts
kubectl describe pod redis-deployment-c795495f4-vjfpl
Key Output:
Containers:
redis-container:
Mounts:
/redis-master from redis-config (rw)
/redis-master-data from data (rw)
Volumes:
data:
Type: EmptyDir
redis-config:
Type: ConfigMap
Name: my-redis-config
Step 8: Check Redis Configuration
kubectl exec -it redis-deployment-c795495f4-vjfpl -- redis-cli CONFIG GET maxmemory
Output:
1) "maxmemory"
2) "0"
Note: The ConfigMap is mounted as a file, but Redis does not automatically load the configuration from the mounted path. To load the configuration, Redis would need to be started with redis-server /redis-master/redis-config.
Step 9: Check Redis Memory Info
kubectl exec -it redis-deployment-c795495f4-vjfpl -- redis-cli INFO memory
Output:
# Memory
used_memory:1419296
used_memory_human:1.35M
maxmemory:0
maxmemory_human:0B
Step 10: Check Mounted Config File
kubectl exec -it redis-deployment-c795495f4-vjfpl -- cat /redis-master/redis-config
Output:
maxmemory 2mb
Redis Configuration Options
Common Redis Configuration Parameters
| Parameter | Description | Example |
|---|---|---|
maxmemory |
Maximum memory limit | maxmemory 256mb |
maxmemory-policy |
Eviction policy when memory limit is reached | maxmemory-policy allkeys-lru |
save |
Snapshotting intervals | save 900 1 |
appendonly |
Enable AOF persistence | appendonly yes |
requirepass |
Password authentication | requirepass mypassword |
Redis Memory Policies
| Policy | Description |
|---|---|
noeviction |
Return error when memory limit is reached |
allkeys-lru |
Evict least recently used keys |
volatile-lru |
Evict least recently used keys with expiration |
allkeys-random |
Evict random keys |
volatile-random |
Evict random keys with expiration |
volatile-ttl |
Evict keys with shortest time to live |
Advanced Configuration
Loading ConfigMap Configuration in Redis
To load the ConfigMap configuration into Redis, you can modify the container command:
containers:
- name: redis-container
image: redis:alpine
command: ["redis-server"]
args: ["/redis-master/redis-config"]
Adding Environment Variables
containers:
- name: redis-container
image: redis:alpine
env:
- name: REDIS_PASSWORD
value: "my-secure-password"
Adding a Service for Redis
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
Troubleshooting
Pod Not Starting
# Check pod status
kubectl get pods
# Check pod details
kubectl describe pod <pod-name>
# Check pod logs
kubectl logs <pod-name>
ConfigMap Not Found
# Check ConfigMap exists
kubectl get configmaps
# Check ConfigMap details
kubectl describe configmap my-redis-config
Volumes Not Mounted
# Check volume mounts
kubectl describe pod <pod-name> | grep -A 10 "Mounts:"
# Check volumes
kubectl describe pod <pod-name> | grep -A 10 "Volumes:"
Redis Not Accessible
# Check if Redis is running
kubectl exec -it <pod-name> -- redis-cli PING
# Should return: PONG
Best Practices
1. Resource Management
Set appropriate resource requests and limits:
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "1"
2. Persistent Storage
Use PersistentVolumeClaims for data persistence:
volumes:
- name: redis-data
persistentVolumeClaim:
claimName: redis-pvc
3. Configuration Management
Use ConfigMaps for Redis configuration:
volumes:
- name: redis-config
configMap:
name: redis-config
4. Security
Enable Redis authentication:
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: password
Useful Commands Reference
| Command | Purpose |
|---|---|
kubectl get deployments |
List deployments |
kubectl get pods |
List pods |
kubectl get configmaps |
List ConfigMaps |
kubectl describe configmap my-redis-config |
ConfigMap details |
kubectl exec -it <pod> -- redis-cli CONFIG GET maxmemory |
Check Redis max memory |
kubectl exec -it <pod> -- redis-cli INFO memory |
Check Redis memory info |
kubectl exec -it <pod> -- redis-cli PING |
Check Redis connectivity |
kubectl exec -it <pod> -- cat /redis-master/redis-config |
View mounted config file |
kubectl logs <pod> |
View pod logs |
Summary
In this challenge, we successfully:
- Created a ConfigMap to store Redis configuration (
maxmemory 2mb) - Deployed Redis on Kubernetes using the
redis:alpineimage - Configured resource requests for the Redis container
- Mounted an EmptyDir volume for data storage
- Mounted a ConfigMap volume for configuration
- Verified the deployment, pod, and configuration
Redis is a powerful in-memory data store commonly used in microservices architectures. Deploying Redis on Kubernetes provides a scalable, resilient, and manageable solution for caching and data storage needs. The patterns demonstrated here can be extended to support more complex Redis configurations, persistent storage, and high-availability setups.
Top comments (0)