Files
kodekloud-engineer/kubernetes/level 2/task-9.md

4.2 KiB
Raw Blame History

Assignment

The Nautilus development team has completed development of one of the node applications, which they are planning to deploy on a Kubernetes cluster. They recently had a meeting with the DevOps team to share their requirements. Based on that, the DevOps team has listed out the exact requirements to deploy the app. Find below more details:

Create a deployment using kodekloud/centos-ssh-enabled:node image, replica count must be 2.

Create a service to expose this app, the service type must be NodePort, targetPort must be 8080 and nodePort should be 30012.

Make sure all the pods are in Running state after the deployment.

You can check the application by clicking on NodeApp button on top bar.

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.

Solution

Node App on Kubernetes — Deployment + NodePort Service

A 2-replica Node app Deployment exposed via a NodePort Service. Names/labels are free choice; the required values are the image, replica count, and port mapping. One multi-document heredoc — no manifest file on disk.

Apply (heredoc → kubectl)

kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-deployment
  labels:
    app: node-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: node-app
  template:
    metadata:
      labels:
        app: node-app
    spec:
      containers:
        - name: node-container
          image: kodekloud/centos-ssh-enabled:node
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: node-service
  labels:
    app: node-app
spec:
  type: NodePort
  selector:
    app: node-app
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 30012
EOF

kubectl rollout status deployment/node-deployment

How it works

The heredoc apply pattern

  • kubectl apply -f - reads from stdin; --- separates the two documents.
  • <<'EOF' (delimiter quoted) keeps the manifest literal — the right default for k8s YAML.

The Deployment

  • image: kodekloud/centos-ssh-enabled:node and replicas: 2 — the two hard requirements. Name (node-deployment), container name (node-container), and labels (app: node-app) are free choices, kept simple.
  • containerPort: 8080 — the Node app listens on 8080 inside the container, matching the service's targetPort.
  • selector.matchLabels: app: node-app equals the template labels — the Deployment↔pod link, and what the Service selects on.

The Service — the port mapping is the graded part

  • type: NodePort exposes the app outside the cluster.

  • selector: app: node-app targets the deployment's two pods by label and load-balances across them.

  • Port mapping:

    • port: 8080 — the Service's ClusterIP port.
    • targetPort: 8080 — the container port, exactly as required; must match where the app listens.
    • nodePort: 30012 — the external port on each node, exactly as required (valid 3000032767 range).

    Path: <node-ip>:30012 → Service :8080 → one of the two pods :8080.

Ensuring all pods are Running (requirement 3)

kubectl rollout status blocks until both replicas are Ready. Only then is the deployment fully available and the app reliably reachable through the Service — so wait for it to report success before hitting the NodeApp button.

Verify

# Both replicas running
kubectl get deployment node-deployment
kubectl get pods -l app=node-app

# Service on 30012 with two endpoints (one per pod)
kubectl get service node-service
kubectl get endpoints node-service

# App responding inside the cluster
kubectl exec deploy/node-deployment -- \
  sh -c 'curl -sI http://localhost:8080 | head -n1' 2>/dev/null || true

Expected — deployment READY 2/2, both pods Running, node-service NodePort 8080:30012/TCP with two endpoints, and the app loading via the NodeApp button (<node-ip>:30012).

If endpoints shows fewer than two IPs, a pod isn't Ready yet — give it a moment. Empty endpoints means the service selector doesn't match the pod labels.