Files

108 lines
3.8 KiB
Markdown

# Assignment
The Nautilus DevOps team has noticed performance issues in some Kubernetes-hosted applications due to resource constraints. To address this, they plan to set limits on resource utilization. Here are the details:
Create a pod named httpd-pod with a container named httpd-container. Use the httpd image with the latest tag (specify as httpd:latest). Configure the following container-level resource requests and limits for the container:
Requests: Memory: 15Mi, CPU: 100m
Limits: Memory: 20Mi, CPU: 100m
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
# Solution
# Kubernetes Pod with Resource Limits — `httpd-pod`
A pod running `httpd:latest` with container-level CPU/memory requests and limits.
Applied inline via a heredoc — no manifest file on disk.
## Apply (heredoc → kubectl)
```bash
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: httpd-pod
labels:
app: httpd
spec:
containers:
- name: httpd-container
image: httpd:latest
resources:
requests:
memory: "15Mi"
cpu: "100m"
limits:
memory: "20Mi"
cpu: "100m"
EOF
```
## How it works
### The heredoc apply pattern
- **`kubectl apply -f -`** reads from **stdin**; the heredoc feeds the YAML in, nothing
on disk.
- **`<<'EOF'` (delimiter quoted)** disables shell expansion, keeping `$VAR`/backticks
literal — the right default for Kubernetes YAML.
### The pod
- **`metadata.name: httpd-pod`** and container **`name: httpd-container`** — exactly as
required.
- **`image: httpd:latest`** — Apache HTTP Server at the `latest` tag, stated explicitly.
### The `resources` block — the heart of this task
Resource controls are set **per container**, under `spec.containers[].resources`:
- **`requests`** — the amount the scheduler **reserves** for the container. Kubernetes
places the pod on a node that has at least this much free, and the request is what
counts against node allocatable capacity. Here: `memory: 15Mi`, `cpu: 100m`.
- **`limits`** — the hard **ceiling** the container may use at runtime. Here:
`memory: 20Mi`, `cpu: 100m`.
The two behave very differently when exceeded:
| Resource | Over the limit → |
|----------|------------------|
| **CPU** | **Throttled** — the container is capped at its CPU limit; it's slowed, never killed. |
| **Memory** | **OOM-killed** — memory is incompressible, so exceeding the limit terminates the container (it restarts per its policy). |
### Units explained
- **`100m` CPU** = 100 millicores = 0.1 of a vCPU. CPU is measured in millicores; `1000m`
= 1 full core. Request and limit are both `100m` here, so the container is guaranteed
0.1 core and capped at 0.1 core.
- **`15Mi` / `20Mi` memory** — `Mi` is **mebibytes** (base-2, 1 Mi = 1,048,576 bytes),
distinct from `M` (megabytes, base-10, 1,000,000 bytes). The task specifies `Mi`, so
use `Mi` exactly — mixing units is a common mistake.
### Requests ≤ limits
Note memory request (`15Mi`) is below its limit (`20Mi`), while CPU request equals its
limit (`100m`). That's valid: a request must never exceed its limit, but being lower is
fine and normal — it lets the container burst up to the limit when the node has spare
capacity while only reserving the smaller request amount.
## Verify
```bash
# Pod running
kubectl get pod httpd-pod
# Requests and limits are set correctly
kubectl get pod httpd-pod \
-o jsonpath='{.spec.containers[0].resources}{"\n"}'
```
Expected — `httpd-pod` in `Running` status, and the resources printing requests
`{cpu:100m, memory:15Mi}` with limits `{cpu:100m, memory:20Mi}`.
> If the pod is `OOMKilled` on start, `httpd:latest` needed more than the `20Mi` memory
> limit — but Apache's base footprint fits comfortably, so the given values are fine.