The Nautilus Application development team has finished development of one of the applications and it is ready for deployment. It is a guestbook application that will be used to manage entries for guests/visitors. As per discussion with the DevOps team, they have finalized the infrastructure that will be deployed on Kubernetes cluster. Below you can find more details about it.
BACK-END TIER
Create a deployment named
redis-masterfor Redis master.
a.) Replicas count should be1.
b.) Container name should bemaster-redis-nautilusand it should use imageredis.
c.) Request resources asCPUshould be100mandMemoryshould be100Mi.
d.) Container port should be redis default port i.e6379.Create a service named
redis-masterfor Redis master. Port and targetPort should be Redis default port i.e6379.Create another deployment named
redis-slavefor Redis slave.
a.) Replicas count should be2.
b.) Container name should beslave-redis-nautilusand it should usegcr.io/google_samples/gb-redisslave:v3image.
c.) Requests resources asCPUshould be100mandMemoryshould be100Mi.
d.) Define an environment variable namedGET_HOSTS_FROMand its value should bedns.
e.) Container port should be Redis default port i.e6379.Create another service named
redis-slave. It should use Redis default port i.e6379.Create another service named
redis-follower. Port and targetPort should be Redis default port i.e6379. Its selectorappshould beredis-slave.
FRONT END TIER
Create a deployment named
frontend.
a.) Replicas count should be3.
b.) Container name should bephp-redis-nautilusand it should usegcr.io/google-samples/gb-frontend@sha256:a908df8486ff66f2c4daa0d3d8a2fa09846a1fc8efd65649c0109695c7c5cbffimage.
c.) Request resources asCPUshould be100mandMemoryshould be100Mi.
d.) Define an environment variable named asGET_HOSTS_FROMand its value should bedns.
e.) Container port should be80.Create a service named
frontend. Itstypeshould beNodePort, port should be80and itsnodePortshould be30009.
Finally, you can check the guestbook app by clicking on App button.
You can use any labels as per your choice.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
Day 67: Deploy Guest Book App on Kubernetes – A Complete Guide
Introduction
Welcome to Day 67 of my 100 Days of DevOps journey. Today, we are deploying a complete multi-tier Guest Book application on Kubernetes. This application demonstrates a typical three-tier architecture with a frontend web layer, a Redis master for write operations, and Redis slaves for read operations.
The Guest Book application allows users to leave messages that are stored in Redis. This architecture is common in real-world applications where scalability and high availability are important considerations.
Understanding the Application Architecture
Components Overview
| Tier | Component | Replicas | Purpose |
|---|---|---|---|
| Backend | Redis Master | 1 | Handles write operations |
| Backend | Redis Slave | 2 | Handles read operations |
| Frontend | PHP Frontend | 3 | Web interface for users |
Architecture Diagram
┌─────────────────────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Frontend Tier │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Deployment: frontend (3 replicas) │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ Container: php-redis-nautilus │ │ │ │
│ │ │ │ Image: gcr.io/google-samples/gb-frontend │ │ │ │
│ │ │ │ Port: 80 │ │ │ │
│ │ │ │ Env: GET_HOSTS_FROM=dns │ │ │ │
│ │ │ └────────────────────────────────────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ Service: frontend (NodePort 30009) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Backend Tier │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Redis Master │ │ │
│ │ │ Deployment: redis-master (1 replica) │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ Container: master-redis-nautilus │ │ │ │
│ │ │ │ Image: redis │ │ │ │
│ │ │ │ Port: 6379 │ │ │ │
│ │ │ │ Resources: 100m CPU, 100Mi Memory │ │ │ │
│ │ │ └────────────────────────────────────────────────────────────┘ │ │ │
│ │ │ Service: redis-master (6379) │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Redis Slave │ │ │
│ │ │ Deployment: redis-slave (2 replicas) │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ Container: slave-redis-nautilus │ │ │ │
│ │ │ │ Image: gcr.io/google_samples/gb-redisslave:v3 │ │ │ │
│ │ │ │ Port: 6379 │ │ │ │
│ │ │ │ Env: GET_HOSTS_FROM=dns │ │ │ │
│ │ │ │ Resources: 100m CPU, 100Mi Memory │ │ │ │
│ │ │ └────────────────────────────────────────────────────────────┘ │ │ │
│ │ │ Services: redis-slave (6379), redis-follower (6379) │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Step-by-Step Implementation
Step 1: Create Redis Master Deployment
The Redis Master handles all write operations for the Guest Book application.
cat > redis-master-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-master
labels:
app: redis-master
spec:
replicas: 1
selector:
matchLabels:
app: redis-master
template:
metadata:
labels:
app: redis-master
role: master
spec:
containers:
- name: master-redis-nautilus
image: redis
ports:
- containerPort: 6379
resources:
requests:
cpu: 100m
memory: 100Mi
EOF
Key Configuration Points:
| Element | Value | Purpose |
|---|---|---|
replicas |
1 |
Single master instance |
image |
redis |
Official Redis image |
containerPort |
6379 |
Redis default port |
cpu |
100m |
0.1 CPU request |
memory |
100Mi |
100 MB memory request |
Step 2: Create Redis Master Service
The Redis Master service exposes the master for internal cluster communication.
cat > redis-master-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: redis-master
labels:
app: redis-master
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis-master
role: master
EOF
Step 3: Create Redis Slave Deployment
Redis slaves handle read operations, distributing the load from the frontend.
cat > redis-slave-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-slave
labels:
app: redis-slave
spec:
replicas: 2
selector:
matchLabels:
app: redis-slave
template:
metadata:
labels:
app: redis-slave
role: slave
spec:
containers:
- name: slave-redis-nautilus
image: gcr.io/google_samples/gb-redisslave:v3
ports:
- containerPort: 6379
env:
- name: GET_HOSTS_FROM
value: dns
resources:
requests:
cpu: 100m
memory: 100Mi
EOF
Key Configuration Points:
| Element | Value | Purpose |
|---|---|---|
replicas |
2 |
Two slave instances for high availability |
image |
gcr.io/google_samples/gb-redisslave:v3 |
Redis slave image |
GET_HOSTS_FROM |
dns |
Service discovery using DNS |
cpu |
100m |
0.1 CPU request |
memory |
100Mi |
100 MB memory request |
Step 4: Create Redis Slave Service
cat > redis-slave-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: redis-slave
labels:
app: redis-slave
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis-slave
role: slave
EOF
Step 5: Create Redis Follower Service
The follower service provides an alternative endpoint name for Redis slaves.
cat > redis-follower-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: redis-follower
labels:
app: redis-follower
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis-slave
EOF
Step 6: Create Frontend Deployment
The frontend provides the web interface for users to view and add guest book entries.
cat > frontend-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
labels:
app: frontend
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: php-redis-nautilus
image: gcr.io/google-samples/gb-frontend@sha256:a908df8486ff66f2c4daa0d3d8a2fa09846a1fc8efd65649c0109695c7c5cbff
ports:
- containerPort: 80
env:
- name: GET_HOSTS_FROM
value: dns
resources:
requests:
cpu: 100m
memory: 100Mi
EOF
Key Configuration Points:
| Element | Value | Purpose |
|---|---|---|
replicas |
3 |
Three frontend instances for scalability |
image |
gcr.io/google-samples/gb-frontend@sha256:... |
Frontend image with specific SHA |
containerPort |
80 |
HTTP port |
GET_HOSTS_FROM |
dns |
Service discovery using DNS |
cpu |
100m |
0.1 CPU request |
memory |
100Mi |
100 MB memory request |
Step 7: Create Frontend Service
The frontend service exposes the application to external users.
cat > frontend-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
app: frontend
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30009
selector:
app: frontend
EOF
Step 8: Apply All Configurations
# Apply Backend
kubectl apply -f redis-master-deployment.yaml
kubectl apply -f redis-master-service.yaml
kubectl apply -f redis-slave-deployment.yaml
kubectl apply -f redis-slave-service.yaml
kubectl apply -f redis-follower-service.yaml
# Apply Frontend
kubectl apply -f frontend-deployment.yaml
kubectl apply -f frontend-service.yaml
Output:
deployment.apps/redis-master created
service/redis-master created
deployment.apps/redis-slave created
service/redis-slave created
service/redis-follower created
deployment.apps/frontend created
service/frontend created
Step 9: Verify All Resources
kubectl get deployments
Output:
NAME READY UP-TO-DATE AVAILABLE AGE
frontend 3/3 3 3 30s
redis-master 1/1 1 1 30s
redis-slave 2/2 2 2 30s
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
frontend-94bfbd46c-4895s 1/1 Running 0 30s
frontend-94bfbd46c-dpjmt 1/1 Running 0 30s
frontend-94bfbd46c-k8xqz 1/1 Running 0 30s
redis-master-6f677945d4-89rb4 1/1 Running 0 30s
redis-slave-65bfddc98d-jvc2g 1/1 Running 0 30s
redis-slave-65bfddc98d-l9x99 1/1 Running 0 30s
kubectl get services
Output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend NodePort 10.43.123.118 <none> 80:30009/TCP 30s
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 54m
redis-follower ClusterIP 10.43.191.102 <none> 6379/TCP 30s
redis-master ClusterIP 10.43.101.228 <none> 6379/TCP 30s
redis-slave ClusterIP 10.43.65.228 <none> 6379/TCP 30s
Understanding the Application Flow
1. User Interaction
- A user accesses the Guest Book application via the frontend service
- The frontend connects to Redis services for data operations
2. Data Flow
┌─────────────────────────────────────────────────────────────────────────────┐
│ Data Flow Architecture │
│ │
│ User → Frontend → Redis Slave (Read) │
│ │
│ User → Frontend → Redis Master (Write) │
│ │
│ Redis Master → Redis Slave (Replication) │
└─────────────────────────────────────────────────────────────────────────────┘
3. Service Discovery
The GET_HOSTS_FROM=dns environment variable instructs the application to use Kubernetes DNS for service discovery. This allows the frontend to find Redis services by their DNS names:
redis-master.default.svc.cluster.localredis-slave.default.svc.cluster.local
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>
Service Not Accessible
# Check service status
kubectl get services
# Check endpoints
kubectl get endpoints
# Check service details
kubectl describe service frontend
Image Pull Issues
# Check if image exists
kubectl describe pod <pod-name> | grep -A 5 "Failed"
# Verify image name
kubectl get deployment frontend -o yaml | grep image
Useful Commands Reference
| Command | Purpose |
|---|---|
kubectl get deployments |
List deployments |
kubectl get pods |
List pods |
kubectl get services |
List services |
kubectl describe pod <pod-name> |
Detailed pod information |
kubectl logs <pod-name> |
View pod logs |
kubectl get endpoints |
List service endpoints |
kubectl delete deployment <name> |
Delete deployment |
kubectl apply -f <file> |
Apply configuration |
kubectl port-forward service/frontend 8080:80 |
Port forward for local testing |
Summary
In this challenge, we successfully:
- Deployed a Redis master for write operations
- Deployed Redis slaves for read operations
- Configured services for internal communication
- Deployed the PHP frontend application
- Exposed the application using a NodePort service
This multi-tier application deployment demonstrates key Kubernetes concepts including:
- Managing stateful and stateless components
- Service discovery using DNS
- Resource management with requests
- Horizontal scaling of application tiers
- Multi-container service communication
The Guest Book application architecture is a common pattern used in production environments for applications that require separate read and write capabilities, scalability, and high availability.
Top comments (0)