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

132 lines
5.0 KiB
Markdown

# Assignment
We encountered an issue with our Nginx and PHP-FPM setup on the Kubernetes cluster this morning, which halted its functionality. Investigate and rectify the issue:
The pod name is nginx-phpfpm and configmap name is nginx-config. Identify and fix the problem.
Once resolved, copy /home/thor/index.php file from the jump host to the nginx-container within the nginx document root. After this, you should be able to access the website using Website button on the top bar.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
# Solution
# Troubleshoot nginx + php-fpm — `nginx-phpfpm` (confirmed fix)
## Root cause (confirmed from the live spec)
The nginx config and the two container mounts don't agree on the document root:
| Source | Path |
|--------|------|
| nginx config `root` | `/var/www/html` |
| `nginx-container` shared-files mount | `/var/www/html` ✓ |
| `php-fpm-container` shared-files mount | `/usr/share/nginx/html`**mismatch** |
nginx forwards PHP requests to php-fpm with
`SCRIPT_FILENAME = $document_root$fastcgi_script_name``/var/www/html/index.php`. But in the
**php-fpm** container the shared volume is mounted at `/usr/share/nginx/html`, so the path
`/var/www/html/index.php` doesn't exist there and php-fpm returns **"File not found."** The two
containers share the same `emptyDir` volume, but at **different paths**, so they aren't actually
sharing the document root.
**Fix:** change the php-fpm container's `shared-files` mountPath from `/usr/share/nginx/html`
to `/var/www/html`, so both containers — and the nginx `root`, and the FastCGI
`SCRIPT_FILENAME` — all reference the same path.
## Step 1 — Recreate the pod with the corrected mountPath
A pod's `volumeMounts` are immutable in place, so delete and re-create. This heredoc is your
live spec (from `last-applied-configuration`) with **only** the php-fpm mountPath fixed:
```bash
kubectl delete pod nginx-phpfpm
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: nginx-phpfpm
namespace: default
labels:
app: php-app
spec:
volumes:
- name: shared-files
emptyDir: {}
- name: nginx-config-volume
configMap:
name: nginx-config
containers:
- name: php-fpm-container
image: php:7.2-fpm-alpine
volumeMounts:
- name: shared-files
mountPath: /var/www/html # FIXED: was /usr/share/nginx/html
- name: nginx-container
image: nginx:latest
volumeMounts:
- name: shared-files
mountPath: /var/www/html
- name: nginx-config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
EOF
```
## Step 2 — Copy the PHP file into the shared document root
```bash
kubectl cp /home/thor/index.php nginx-phpfpm:/var/www/html/index.php -c nginx-container
```
Copy into `/var/www/html` (the now-consistent root) via the nginx container. Because the volume
is shared at the same path in both containers, php-fpm sees the file too and can execute it.
## How it works
### Why the mismatch broke it even though the pod was "Running"
Both containers were healthy (`2/2 Running`) — this wasn't a crash. The failure was purely at
request time: nginx served on port 8099, matched `.php`, and handed php-fpm an absolute path
(`/var/www/html/...`) that was valid in nginx's filesystem but pointed at nothing in php-fpm's.
FastCGI passes a **path string**, not a file handle, so both containers must resolve that same
absolute path to the same bytes — which only happens if the shared volume is mounted at the
identical path in each. Aligning php-fpm's mount to `/var/www/html` closes that gap.
### Why copy after recreating
Recreating the pod starts with a fresh empty `shared-files` volume, so `index.php` is copied
**after** the pod is Running. It then lives in the shared root for the pod's lifetime and is
visible to both containers.
### Note on the listen port
The nginx config listens on **8099** (not 80), with `root /var/www/html`. Any Service exposing
this app must target port 8099 — the Website button relies on that mapping. This task doesn't
ask you to change the Service, just to fix the pod and drop in the file.
## Verify
```bash
# Pod healthy after recreate
kubectl get pod nginx-phpfpm
# File present in the shared root, visible from BOTH containers
kubectl exec nginx-phpfpm -c nginx-container -- ls -l /var/www/html/index.php
kubectl exec nginx-phpfpm -c php-fpm-container -- ls -l /var/www/html/index.php
# App renders the PHP page (nginx listens on 8099)
kubectl exec nginx-phpfpm -c nginx-container -- curl -s http://localhost:8099/index.php | head
```
Expected — `nginx-phpfpm` `READY 2/2`, `index.php` visible from **both** containers under
`/var/www/html`, and the curl returning the rendered page. The **Website** button then loads the
site.
> The key sign the fix worked: `ls` succeeds from the **php-fpm** container too. Before the fix
> it would only appear under `/usr/share/nginx/html` there, which is exactly why php-fpm
> couldn't find it at `/var/www/html`.