DEV Community

Janak Shrestha
Janak Shrestha

Posted on

Day 56: Deploy Nginx Web Server on Kubernetes Cluster

Some of the Nautilus team developers are developing a static website and they want to deploy it on Kubernetes cluster. They want it to be highly available and scalable. Therefore, based on the requirements, the DevOps team has decided to create a deployment for it with multiple replicas. Below you can find more details about it:

  1. Create a deployment using nginx image with latest tag only and remember to mention the tag i.e nginx:latest. Name it as nginx-deployment. The container should be named as nginx-container, also make sure replica counts are 3.
  2. Create a NodePort type service named nginx-service. The nodePort should be 30011.

🔧 Step-by-Step Solution

Step 1: Create the Deployment YAML

vi nginx-deployment.yaml
Enter fullscreen mode Exit fullscreen mode

YAML Content:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: nginx-container
        image: nginx:latest
        ports:
        - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Service YAML

vi nginx-service.yaml
Enter fullscreen mode Exit fullscreen mode

YAML Content:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx-app
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30011
Enter fullscreen mode Exit fullscreen mode

Step 3: Apply the Configuration

# Apply the deployment
kubectl apply -f nginx-deployment.yaml

# Apply the service
kubectl apply -f nginx-service.yaml
Enter fullscreen mode Exit fullscreen mode

Step 4: Verify the Deployment

# Check deployments
kubectl get deployments

# Check pods
kubectl get pods

# Check replicas
kubectl get pods -o wide
Enter fullscreen mode Exit fullscreen mode

Step 5: Verify the Service

# Check services
kubectl get services

# Check service details
kubectl describe service nginx-service

# Check endpoints
kubectl get endpoints nginx-service
Enter fullscreen mode Exit fullscreen mode

Step 6: Test the Deployment

# Check if pods are running
kubectl get pods

# Check service NodePort
kubectl get svc nginx-service

# Test the service (if accessible)
curl http://<node-ip>:30011
Enter fullscreen mode Exit fullscreen mode

📊 Expected Output

Creating Deployment:

thor@jump-host ~$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
Enter fullscreen mode Exit fullscreen mode

Creating Service:

thor@jump-host ~$ kubectl apply -f nginx-service.yaml
service/nginx-service created
Enter fullscreen mode Exit fullscreen mode

Verifying Deployment:

thor@jump-host ~$ kubectl get deployments
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment    3/3     3            3           30s

thor@jump-host ~$ kubectl get pods
NAME                                 READY   STATUS    RESTARTS   AGE
nginx-deployment-xxxxxxxxxx-xxxxx   1/1     Running   0          30s
nginx-deployment-xxxxxxxxxx-yyyyy   1/1     Running   0          30s
nginx-deployment-xxxxxxxxxx-zzzzz   1/1     Running   0          30s
Enter fullscreen mode Exit fullscreen mode

Verifying Service:

thor@jump-host ~$ kubectl get services
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP        10d
nginx-service   NodePort    10.96.xxx.xxx   <none>        80:30011/TCP   10s

thor@jump-host ~$ kubectl describe service nginx-service
Name:                     nginx-service
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=nginx-app
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.96.xxx.xxx
IPs:                      10.96.xxx.xxx
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30011/TCP
Endpoints:                10.22.0.x:80,10.22.0.y:80,10.22.0.z:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
Enter fullscreen mode Exit fullscreen mode

📋 YAML Breakdown

Deployment YAML

apiVersion: apps/v1              # Kubernetes API version for Deployments
kind: Deployment                 # Resource type
metadata:
  name: nginx-deployment          # Deployment name
  labels:
    app: nginx-app               # Label for identifying the deployment
spec:
  replicas: 3                     # Number of pod replicas
  selector:
    matchLabels:
      app: nginx-app             # Selector to match pods
  template:                       # Pod template
    metadata:
      labels:
        app: nginx-app           # Pod labels
    spec:
      containers:
      - name: nginx-container    # Container name
        image: nginx:latest      # Image with tag
        ports:
        - containerPort: 80      # Port the container listens on
Enter fullscreen mode Exit fullscreen mode

Service YAML

apiVersion: v1                   # Kubernetes API version for Services
kind: Service                    # Resource type
metadata:
  name: nginx-service            # Service name
spec:
  type: NodePort                 # Service type
  selector:
    app: nginx-app              # Selector to match pods
  ports:
    - port: 80                   # Service port
      targetPort: 80             # Container port
      nodePort: 30011            # Node port (30000-32767 range)
Enter fullscreen mode Exit fullscreen mode

🎯 Key Concepts

Deployment

  • Manages a set of identical pods
  • Provides rolling updates and rollbacks
  • Ensures self-healing (replaces failed pods)

NodePort Service

  • Exposes the application on a static port on each node
  • Allows external access to the application
  • Port range: 30000-32767

Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────────┐
│                         Kubernetes Cluster                                 │
│                                                                              │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │                    Deployment: nginx-deployment                       │ │
│  │                    Replicas: 3                                       │ │
│  │                                                                       │ │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐                           │ │
│  │  │  Pod 1   │  │  Pod 2   │  │  Pod 3   │                           │ │
│  │  │ nginx    │  │ nginx    │  │ nginx    │                           │ │
│  │  │ :80      │  │ :80      │  │ :80      │                           │ │
│  │  └──────────┘  └──────────┘  └──────────┘                           │ │
│  │       │              │              │                                │ │
│  └───────┼──────────────┼──────────────┼────────────────────────────────┘ │
│          │              │              │                                  │
│  ┌───────┼──────────────┼──────────────┼────────────────────────────────┐ │
│  │       ▼              ▼              ▼                                │ │
│  │  ┌──────────────────────────────────────────────────────────────┐   │ │
│  │  │              Service: nginx-service                          │   │ │
│  │  │              Type: NodePort                                  │   │ │
│  │  │              Port: 80 -> TargetPort: 80                     │   │ │
│  │  │              NodePort: 30011                                │   │ │
│  │  └──────────────────────────────────────────────────────────────┘   │ │
│  │                            │                                        │ │
│  │                            ▼                                        │ │
│  │                    http://<node-ip>:30011                          │ │
│  └──────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

🛠️ Troubleshooting

If Pods Are Not Running:

# Check pod status
kubectl get pods

# Check pod details
kubectl describe pod <pod-name>

# Check pod logs
kubectl logs <pod-name>
Enter fullscreen mode Exit fullscreen mode

If Service Is Not Accessible:

# Check service details
kubectl describe service nginx-service

# Check endpoints
kubectl get endpoints nginx-service

# Check if pods are ready
kubectl get pods -o wide
Enter fullscreen mode Exit fullscreen mode

If NodePort Is Out of Range:

# NodePort must be between 30000-32767
# Change nodePort in service YAML
Enter fullscreen mode Exit fullscreen mode

🔍 Additional Verification

# Check deployment rollout status
kubectl rollout status deployment nginx-deployment

# Check deployment history
kubectl rollout history deployment nginx-deployment

# Check resource usage
kubectl top pods

# Check service endpoints
kubectl describe endpoints nginx-service
Enter fullscreen mode Exit fullscreen mode

✅ Task Summary

Requirement Status
Deployment name nginx-deployment
Image nginx:latest
Container name nginx-container
Replicas: 3
Service name nginx-service
Service type NodePort
NodePort 30011

Top comments (0)