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

6.2 KiB

Assignment

One of the DevOps team members was trying to install a WordPress website on a LAMP stack, which is deployed on a Kubernetes cluster. It was working well, and we could see the installation page a few hours ago. However, something seems to have gone wrong with the stack after the website went down. Please look into the issue and fix it:

FYI, the deployment name is lamp-wp and it is using a service named lamp-service. Apache is using the default HTTP port, and the NodePort is 30008. From the application logs, it has been identified that the application is facing some issues connecting to the database, in addition to other problems. Additionally, there are some environment variables associated with the pods, such as MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, and MYSQL_HOST

Also, do not attempt to delete or modify any other existing components, such as deployment names, service names, types, labels, secrets and so on.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

Troubleshoot LAMP WordPress — lamp-wp / lamp-service

The WordPress site is down after a bad change. The hints point to two+ problems: a DB-connection issue (env vars) and "other problems" (typically the service port). This diagnoses, then fixes surgically — without touching deployment/service names, types, labels, or secrets, as required.

Step 1 — Diagnose

# Pod + container state
kubectl get pods -l app=lamp-wp                 # adjust selector to match
kubectl describe pod -l app=lamp-wp

# App logs (the DB connection error shows here)
kubectl logs -l app=lamp-wp -c <httpd-or-php-container>
kubectl logs -l app=lamp-wp -c <mysql-container>

# Full specs — find the mismatches
kubectl get deployment lamp-wp -o yaml
kubectl get service lamp-service -o yaml
kubectl get secrets                              # note the secret + keys the env vars use

Look for these specific mismatches:

  1. Service port — Apache serves on 80 (default HTTP). The Service's targetPort must be 80; if the bad edit set it to something else (e.g. 8080), the NodePort routes to a dead port. nodePort stays 30008.
  2. MYSQL_HOST — in the WordPress/PHP container this must equal the DB service name (check kubectl get svc for the MySQL service). If it points at the wrong host/IP, WordPress can't reach the database — the logged connection error.
  3. DB credential env consistency — the WordPress container's MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD must match what the MySQL container was initialized with (usually both pull from the same Secret keys). A key mismatch means WordPress authenticates with wrong credentials.

Step 2 — Fix (surgical; names/types/labels/secrets untouched)

Service targetPort → 80

kubectl patch service lamp-service \
  --type=json \
  -p='[{"op":"replace","path":"/spec/ports/0/targetPort","value":80}]'

MYSQL_HOST → the correct DB service name

# Find the MySQL service name first
kubectl get svc

# Set MYSQL_HOST on the WordPress/PHP container (use its real container name)
kubectl set env deployment/lamp-wp \
  --containers='<httpd-or-php-container>' \
  MYSQL_HOST=<mysql-service-name>

Any wrong credential env / secret key reference

If an env var references a wrong Secret key, correct the reference (not the Secret) in place:

kubectl edit deployment lamp-wp
# fix the mistyped valueFrom.secretKeyRef.key / .name to match `kubectl get secret <name> -o yaml`

Each change updates the pod template and triggers a fresh rollout:

kubectl rollout status deployment/lamp-wp

How it works

Two independent failure planes

This stack breaks in two places that must both be right:

  • Network path<node-ip>:30008 (nodePort) → Service porttargetPort 80 → Apache. If targetPort doesn't match Apache's listen port, the page is unreachable even when the pod is perfectly healthy. That's the "other problem" beyond the DB.
  • App→DB path — WordPress connects to MySQL over the cluster network using MYSQL_HOST plus the credential env vars. MYSQL_HOST must resolve to the MySQL Service (stable DNS name), and the credentials must match what MySQL was initialized with. A wrong host or mismatched credential is the logged "can't connect to database" error.

Fixing one without the other leaves the site down, which is why the task hints at multiple issues.

Why surgical edits, not re-apply

The task forbids changing deployment/service names, types, labels, and secrets. Re-applying a hand-built manifest risks altering those by omission. kubectl patch (targetPort), kubectl set env (one env var on one container), and kubectl edit (a single reference) each touch exactly the broken field and leave every protected component intact. This is the safe way to honor the "don't modify other components" rule.

Why MYSQL_HOST is a Service name

Pod IPs are ephemeral; a Service gives MySQL a stable DNS name inside the cluster. WordPress must target that name so it keeps resolving across pod restarts — hardcoding an IP or using a wrong name breaks on the first reschedule, which is exactly the kind of thing a bad manual edit introduces.

Verify

# Pods running
kubectl get pods -l app=lamp-wp

# Service targetPort is 80, nodePort 30008
kubectl get service lamp-service \
  -o jsonpath='{.spec.ports[0].targetPort}{"  "}{.spec.ports[0].nodePort}{"\n"}'

# WordPress env has correct MYSQL_HOST
kubectl set env deployment/lamp-wp --list | grep MYSQL_HOST

# App reachable / DB connected (no more DB error in logs)
kubectl logs -l app=lamp-wp -c <httpd-or-php-container> | tail
curl -sI http://<node-ip>:30008 | head -n1

Expected — pods Running, service targetPort 80 / nodePort 30008, MYSQL_HOST set to the MySQL service name, no DB-connection errors in the logs, and the WordPress installation/login page loading at <node-ip>:30008.

Paste kubectl get deployment lamp-wp -o yaml and kubectl get service lamp-service -o yaml (plus kubectl get secret <name> -o yaml) and I'll give you the exact patches — the precise fix depends on which values were changed.