142 lines
5.1 KiB
Markdown
142 lines
5.1 KiB
Markdown
# 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)
|
||
|
||
```bash
|
||
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
|
||
`30000–32767` 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
|
||
|
||
```bash
|
||
# 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. |