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

5.1 KiB
Raw Blame History

Assignment

A new java-based application is ready to be deployed on a Kubernetes cluster. The development team had a meeting with the DevOps team to share the requirements and application scope. The team is ready to setup an application stack for it under their existing cluster. Below you can find the details for this:

Create a namespace named tomcat-namespace-datacenter.

Create a deployment for tomcat app which should be named as tomcat-deployment-datacenter under the same namespace you created. Replica count should be 1, the container should be named as tomcat-container-datacenter, its image should be kodekloud/centos-ssh-enabled:tomcat and its container port should be 8080.

Create a service for tomcat app which should be named as tomcat-service-datacenter under the same namespace you created. Service type should be NodePort and nodePort should be 32227.

Before clicking on Check button please make sure the application is up and running.

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

Tomcat on Kubernetes — namespace + deployment + service (datacenter)

A Tomcat Deployment and NodePort Service inside a dedicated namespace. All objects in one multi-document heredoc — no manifest file on disk.

Apply (heredoc → kubectl)

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

kubectl rollout status deployment/tomcat-deployment-datacenter -n tomcat-namespace-datacenter

How it works

The heredoc apply pattern

  • kubectl apply -f - reads from stdin; --- separates the three documents, applied in order so the Namespace exists before the Deployment and Service land in it.
  • <<'EOF' (delimiter quoted) keeps the manifest literal — the right default for k8s YAML.

Everything scoped to one namespace

All three objects carry namespace: tomcat-namespace-datacenter (the Namespace defines it, the Deployment and Service reference it). Creating the namespace first in the same stream avoids a namespaces "..." not found error. Because the Service and Deployment are in the same namespace, the Service can select the deployment's pods by label directly.

The Deployment

  • name: tomcat-deployment-datacenter, container name: tomcat-container-datacenter, image: kodekloud/centos-ssh-enabled:tomcat, replicas: 1 — all exactly as required.
  • containerPort: 8080 — Tomcat serves on 8080 inside the container.
  • app: tomcat label (free choice) on the template — ties the Deployment to its pods and the Service to those pods.
  • selector.matchLabels: app: tomcat equals the template labels — the Deployment↔pod link.

The Service — targetPort 8080

  • type: NodePort exposes Tomcat outside the cluster.

  • selector: app: tomcat targets the deployment's pod by label.

  • Port mapping:

    • port: 8080 — the Service's ClusterIP port.
    • targetPort: 8080 — the container port; must be 8080 to reach Tomcat.
    • nodePort: 32227 — the external port on each node, exactly as required (valid 3000032767 range).

    Path: <node-ip>:32227 → Service :8080 → Tomcat pod :8080.

"Up and running" before Check

kubectl rollout status blocks until the pod is Ready. This image bundles Tomcat on a CentOS/SSH base, so give it a moment to start the Tomcat service after the pod reports Ready, then confirm the app responds at <node-ip>:32227.

Verify

# Pod running in the namespace
kubectl get deployment tomcat-deployment-datacenter -n tomcat-namespace-datacenter
kubectl get pods -n tomcat-namespace-datacenter -l app=tomcat

# Service on 32227 with an endpoint
kubectl get service tomcat-service-datacenter -n tomcat-namespace-datacenter
kubectl get endpoints tomcat-service-datacenter -n tomcat-namespace-datacenter

# Tomcat responding
kubectl exec -n tomcat-namespace-datacenter deploy/tomcat-deployment-datacenter -- \
  sh -c 'curl -sI http://localhost:8080 | head -n1' 2>/dev/null || true

Expected — deployment READY 1/1, tomcat-service-datacenter NodePort 8080:32227/TCP with one endpoint, and Tomcat reachable at <node-ip>:32227.

Everything is in tomcat-namespace-datacenter — keep -n tomcat-namespace-datacenter on every command. If endpoints is empty, the service selector doesn't match the pod labels.