# Assignment The Nautilus DevOps team is gearing up to deploy applications on a Kubernetes cluster for migration purposes. A team member has been tasked with creating a ReplicaSet outlined below: Create a ReplicaSet using httpd image with latest tag (ensure to specify as httpd:latest) and name it httpd-replicaset. Apply labels: app as httpd_app, type as front-end. Name the container httpd-container. Ensure the replica count is 4. Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster. # Solution # Kubernetes ReplicaSet — `httpd-replicaset` A ReplicaSet maintaining 4 `httpd:latest` pods, labeled `app: httpd_app` and `type: front-end`. Applied inline via a heredoc — no manifest file on disk. ## Apply (heredoc → kubectl) ```bash kubectl apply -f - <<'EOF' apiVersion: apps/v1 kind: ReplicaSet metadata: name: httpd-replicaset labels: app: httpd_app type: front-end spec: replicas: 4 selector: matchLabels: app: httpd_app type: front-end template: metadata: labels: app: httpd_app type: front-end spec: containers: - name: httpd-container image: httpd:latest 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 manifest, field by field - **`apiVersion: apps/v1` / `kind: ReplicaSet`** — a ReplicaSet ensures a specified number of identical pod replicas are running at all times, recreating any that die. (In practice you'd usually use a Deployment, which manages ReplicaSets and adds rollouts — but the task asks for a bare ReplicaSet.) - **`metadata.name: httpd-replicaset`** — the RS name, exactly as required. - **`metadata.labels`** — `app: httpd_app` and `type: front-end` on the ReplicaSet object itself, as required. - **`spec.replicas: 4`** — the desired pod count. The RS controller works continuously to keep exactly 4 matching pods running. - **`spec.selector.matchLabels`** — how the RS identifies the pods it owns. This **must** match the pod template's labels, or the API rejects the manifest with `selector does not match template labels`. - **`spec.template`** — the pod blueprint: - **`template.metadata.labels`** — `app: httpd_app`, `type: front-end` stamped on every pod. These are what the selector targets. - **`template.spec.containers`** — one container: **`name: httpd-container`** with **`image: httpd:latest`** (tag stated explicitly, as required). ### Why the selector and template labels must agree A ReplicaSet is decoupled from its pods and tracks them purely by label selector. `spec.selector.matchLabels` is the query; `spec.template.metadata.labels` is what gets stamped on each pod. If they don't match, the RS couldn't recognize its own pods, so Kubernetes rejects the config outright. Both carry `app: httpd_app` + `type: front-end` to satisfy that contract. > Selector caution: because a ReplicaSet adopts **any** existing pod matching its selector, > reusing labels that other pods already carry can cause it to adopt (or fight over) them. > The two-label selector here is specific enough to avoid that in a clean environment. ## Verify ```bash # ReplicaSet exists with 4 ready replicas kubectl get rs httpd-replicaset # Pods are running and labeled kubectl get pods -l app=httpd_app,type=front-end --show-labels # Container image is correct kubectl get rs httpd-replicaset \ -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' ``` Expected — `httpd-replicaset` showing `DESIRED 4 / CURRENT 4 / READY 4`, four pods `Running` with both labels, and the image printing `httpd:latest`. > If pods sit in `ImagePullBackOff`, the `httpd:latest` pull failed (node offline / > rate-limited). `kubectl describe pod ` shows the pull events.