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

141 lines
5.5 KiB
Markdown

# Assignment
We are working on an application that will be deployed on multiple containers within a pod on Kubernetes cluster. There is a requirement to share a volume among the containers to save some temporary data. The Nautilus DevOps team is developing a similar template to replicate the scenario. Below you can find more details about it.
Create a pod named volume-share-nautilus.
For the first container, use image ubuntu with latest tag only and remember to mention the tag i.e ubuntu:latest, container should be named as volume-container-nautilus-1, and run a sleep command for it so that it remains in running state. Volume volume-share should be mounted at path /tmp/beta.
For the second container, use image ubuntu with the latest tag only and remember to mention the tag i.e ubuntu:latest, container should be named as volume-container-nautilus-2, and again run a sleep command for it so that it remains in running state. Volume volume-share should be mounted at path /tmp/apps.
Volume name should be volume-share of type emptyDir.
After creating the pod, exec into the first container i.e volume-container-nautilus-1, and just for testing create a file beta.txt with the content Welcome to xFusionCorp Industries under the mounted path of first container i.e /tmp/beta.
The file beta.txt should be present under the mounted path /tmp/apps on the second container volume-container-nautilus-2 as well, since they are using a shared volume.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
# Solution
# Kubernetes Shared-Volume Pod — `volume-share-nautilus`
Two `ubuntu:latest` containers sharing one `emptyDir` volume mounted at different paths, then a
test proving a file written in one appears in the other. Applied inline via a heredoc — no
manifest file on disk.
## Step 1 — Apply the pod (heredoc → kubectl)
```bash
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: volume-share-nautilus
spec:
volumes:
- name: volume-share
emptyDir: {}
containers:
- name: volume-container-nautilus-1
image: ubuntu:latest
command:
- /bin/sh
- -c
- "sleep infinity"
volumeMounts:
- name: volume-share
mountPath: /tmp/beta
- name: volume-container-nautilus-2
image: ubuntu:latest
command:
- /bin/sh
- -c
- "sleep infinity"
volumeMounts:
- name: volume-share
mountPath: /tmp/apps
EOF
```
## Step 2 — Write the test file in container 1
```bash
kubectl exec -it volume-share-nautilus -c volume-container-nautilus-1 -- \
bash -c 'echo "Welcome to xFusionCorp Industries" > /tmp/beta/beta.txt'
```
## Step 3 — Confirm it appears in container 2
```bash
kubectl exec -it volume-share-nautilus -c volume-container-nautilus-2 -- \
cat /tmp/apps/beta.txt
```
Expected output: `Welcome to xFusionCorp Industries`
## How it works
### The heredoc apply pattern
- **`kubectl apply -f -`** reads from **stdin**; nothing written to disk.
- **`<<'EOF'` (delimiter quoted)** keeps the manifest literal — the right default for k8s YAML.
### One volume, two mount points
The heart of this task: a **single** `emptyDir` volume (`volume-share`) declared once under
`spec.volumes`, then mounted into **both** containers via `volumeMounts` — but at **different
paths**:
- container 1 sees it at `/tmp/beta`
- container 2 sees it at `/tmp/apps`
Both `volumeMounts` reference the same volume `name: volume-share`, so they're two windows onto
the **same underlying storage**. A write through one window is instantly visible through the
other — which is why `beta.txt` created at `/tmp/beta/beta.txt` shows up at
`/tmp/apps/beta.txt`. The mount paths are just where each container chooses to see the shared
data; the bytes are shared.
### `emptyDir` — pod-lifetime shared scratch
- **`emptyDir: {}`** creates an empty directory when the pod is scheduled to a node, shared by
all containers in the pod, and deleted when the pod is removed. It's the standard choice for
ephemeral data shared between containers in a pod — exactly this "temporary data" scenario.
### Why the `sleep` command
`ubuntu:latest` has no long-running default process — it would start, find nothing to do, and
exit, crash-looping the pod. Giving each container `sleep infinity` (via `/bin/sh -c`) provides
a foreground process that never returns, so both containers stay **Running** and remain
available to `exec` into. `sleep infinity` is cleaner than a fixed duration (which would
eventually exit); `tail -f /dev/null` or a `while true` loop are equivalent.
### `kubectl exec -c` targets a specific container
Because the pod is multi-container, `kubectl exec` **requires** `-c <container>` to say which
one — without it, kubectl defaults to the first container but warns; being explicit avoids
ambiguity. Step 2 targets container 1 to write; Step 3 targets container 2 to read.
## Verify
```bash
# Both containers up
kubectl get pod volume-share-nautilus # READY should be 2/2
# The shared file, read from container 2's mount path
kubectl exec volume-share-nautilus -c volume-container-nautilus-2 -- cat /tmp/apps/beta.txt
```
Expected — `volume-share-nautilus` `READY 2/2 Running`, and the `cat` returning
`Welcome to xFusionCorp Industries` from container 2's `/tmp/apps` path.
> If a container is in `CrashLoopBackOff`, its `sleep` command didn't take — confirm with
> `kubectl get pod volume-share-nautilus -o jsonpath='{.spec.containers[*].command}'`.