# 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) ```bash 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 `30000–32767` range). Path: `: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 ```bash # 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 (`: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.