Files

144 lines
5.7 KiB
Markdown

# Assignment
The Nautilus DevOps team needs a time check pod created in a specific Kubernetes namespace for logging purposes. Initially, it's for testing, but it may be integrated into an existing cluster later. Here's what's required:
Create a pod called time-check in the nautilus namespace. The pod should contain a container named time-check, utilizing the busybox image with the latest tag (specify as busybox:latest).
Create a config map named time-config with the data TIME_FREQ=7 in the same namespace.
Configure the time-check container to execute the command: while true; do date; sleep $TIME_FREQ;done. Ensure the result is written /opt/finance/time/time-check.log. Also, add an environmental variable TIME_FREQ in the container, fetching its value from the config map TIME_FREQ key.
Create a volume log-volume and mount it at /opt/finance/time within the container.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
# Solution
# Kubernetes Pod + ConfigMap — `time-check` in `nautilus`
A `time-check` pod that loops `date` into a log file on a mounted volume, reading its
sleep interval from a ConfigMap-backed env var. Applied inline via a multi-document
heredoc — no manifest file on disk.
## Apply (heredoc → kubectl)
```bash
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Namespace
metadata:
name: nautilus
---
apiVersion: v1
kind: ConfigMap
metadata:
name: time-config
namespace: nautilus
data:
TIME_FREQ: "7"
---
apiVersion: v1
kind: Pod
metadata:
name: time-check
namespace: nautilus
spec:
containers:
- name: time-check
image: busybox:latest
command:
- /bin/sh
- -c
- "while true; do date; sleep $TIME_FREQ; done >> /opt/finance/time/time-check.log"
env:
- name: TIME_FREQ
valueFrom:
configMapKeyRef:
name: time-config
key: TIME_FREQ
volumeMounts:
- name: log-volume
mountPath: /opt/finance/time
volumes:
- name: log-volume
emptyDir: {}
EOF
```
## How it works
### The heredoc apply pattern
- **`kubectl apply -f -`** reads from **stdin**; `---` separates the three documents,
processed in order so the **Namespace → ConfigMap → Pod** dependency chain is satisfied.
- **`<<'EOF'` (delimiter quoted)** is critical here: it stops the jump-host's shell from
expanding `$TIME_FREQ` when you paste the command. The literal `$TIME_FREQ` must reach the
manifest untouched so the **container's** shell expands it at runtime from the env var.
An unquoted heredoc would blank it out before it ever got to Kubernetes.
### The Namespace
- **`kind: Namespace` / `name: nautilus`** — created first so the ConfigMap and Pod have
somewhere to live. If `nautilus` already exists, `apply` is idempotent and simply no-ops.
### The ConfigMap
- **`name: time-config`, `namespace: nautilus`** — as required.
- **`data.TIME_FREQ: "7"`** — the key/value the pod reads. The value is **quoted** because
ConfigMap values must be strings; an unquoted `7` would be a YAML integer and rejected.
### The Pod
- **`name: time-check`, `namespace: nautilus`**, container **`name: time-check`**,
**`image: busybox:latest`** — all exactly as required.
- **`command`** — run via `/bin/sh -c` so the shell interprets the loop and, crucially,
expands `$TIME_FREQ`. The loop prints `date` every `$TIME_FREQ` seconds; the
`>> /opt/finance/time/time-check.log` redirect on the **whole loop** opens the log file
once and appends each timestamp to it continuously. That satisfies "the result is written
to /opt/finance/time/time-check.log."
- **`env` with `valueFrom.configMapKeyRef`** — injects an env var named `TIME_FREQ` whose
value is pulled from the `TIME_FREQ` key of the `time-config` ConfigMap. This is the link
between requirement 2 and the `$TIME_FREQ` in the command — the container gets `7` at
runtime without hardcoding it.
- **`volumeMounts` + `volumes`** — the two halves of attaching storage:
- **`volumes: - name: log-volume / emptyDir: {}`** declares a volume named `log-volume`.
`emptyDir` is an ephemeral, pod-lifetime scratch volume — the simplest choice for a log
location the task doesn't require to persist.
- **`volumeMounts: - name: log-volume / mountPath: /opt/finance/time`** mounts that volume
into the container at `/opt/finance/time`, which is where the log file is written. The
`name` on both sides must match, or Kubernetes can't wire them together.
### Why the mount path and log path line up
The command writes to `/opt/finance/time/time-check.log`, and the volume is mounted at
`/opt/finance/time`. So the log file lands **inside** the mounted volume — meaning the
directory exists (the mount creates it) and the write succeeds. If the mount path and the
log directory didn't match, the write could fail or land on the container's ephemeral
root filesystem instead.
## Verify
```bash
# ConfigMap present with the value
kubectl get configmap time-config -n nautilus -o jsonpath='{.data.TIME_FREQ}{"\n"}'
# Pod running
kubectl get pod time-check -n nautilus -o wide
# Env var resolved from the ConfigMap
kubectl exec time-check -n nautilus -- printenv TIME_FREQ
# Log file is being written inside the mounted volume
kubectl exec time-check -n nautilus -- cat /opt/finance/time/time-check.log
```
Expected — ConfigMap value `7`, pod `Running`, `printenv` showing `TIME_FREQ=7`, and the
log file accumulating timestamps roughly every 7 seconds.
> Remember `-n nautilus` on every command — nothing here is in `default`. If the pod is
> `Error`/`CrashLoopBackOff`, check `kubectl logs time-check -n nautilus` (though output goes
> to the log file, so the pod's stdout may be quiet).