Day 53 of DevOps, Day 3 of Azure. Both tasks today came down to the same thing being known by more than one name.
Two containers shared a volume and still could not see the same file, because they disagreed about where it lived. And an Ubuntu release on Azure turned out to have two valid image names, with an alias quietly choosing one of them for me.
One Kubernetes task, one Azure task. Fix a broken nginx and PHP-FPM pod, then create an Azure VM from the CLI using an image alias. The tasks come from the KodeKloud Engineer platform.
Two containers, one volume, two paths
The pod, nginx-phpfpm, runs two containers. nginx takes the requests and hands PHP files to PHP-FPM, and both mount one shared volume for the site's files. nginx's configuration lives in a ConfigMap. The site was not working.
kubectl describe pod nginx-phpfpm
kubectl get configmap nginx-config -o yaml
The ConfigMap set nginx's document root to /var/www/html, and describe showed where each container mounted the shared volume. The nginx side matched the root. The PHP-FPM container mounted the volume somewhere else.
Why does that break the site? Because nginx does not hand PHP-FPM a file. It hands it a path. Nginx passes the script's location in a FastCGI parameter, SCRIPT_FILENAME, which nginx's own documentation describes as what PHP uses to determine the script name. PHP-FPM then opens that path inside its own container. With the volume mounted elsewhere, the path pointed at a directory where the site's files were not.
The volume was shared correctly. The two containers just did not agree on where it was.
A pod you fix by replacing it
The fix was one line of YAML, and it still needed a new pod. The Kubernetes docs list what an update to an existing pod may change: container images, a couple of timing fields, tolerations and scheduling gates. Volume mounts are not on the list.
kubectl get pod nginx-phpfpm -o yaml > po.yaml
# in po.yaml, set the php-fpm-container mountPath to /var/www/html
kubectl delete pod nginx-phpfpm
kubectl apply -f po.yaml
kubectl replace --force -f po.yaml does the delete and the re-create in one step.
Then the file the task asked for:
kubectl cp /home/thor/index.php nginx-phpfpm:/var/www/html -c php-fpm-container
I copied it in through the PHP-FPM container, and that is fine, because after the fix both containers mount the same volume at the same path. A shared volume does not care which container a file arrives through. The copy has to come after the new pod exists, though. The file needs to land in the volume the new pod mounts, and if that volume is an emptyDir, its data is deleted along with the old pod.
One thing the task did not test, and worth knowing: if the ConfigMap had been the broken part, editing it would not have been enough. A container that mounts a ConfigMap with subPath never receives updates, and nginx's documentation says configuration changes are not applied until nginx is told to reload or is restarted.
An alias picks one of two names
The Azure task was another VM, this time with the image given as an alias, Ubuntu2204:
--image Ubuntu2204 --size Standard_B2s --admin-username azureuser --generate-ssh-keys
The alias resolved to Canonical:0001-com-ubuntu-server-jammy:22_04-lts-gen2:latest. Yesterday's 24.04 image was Canonical:ubuntu-24_04-lts:server:latest. Same publisher, two different naming schemes.
My notes explained that as Canonical changing its naming between 22.04 and 24.04. Canonical's own documentation says otherwise. The 0001-com-ubuntu offers are its legacy format, and "With Ubuntu 22.04 LTS, Canonical began deploying a unified offer structure". Canonical lists 22.04 under the new scheme too, as Canonical:ubuntu-22_04-lts:server:latest. So 22.04 has two valid names, and the alias happens to point at the older one.
That makes the lesson stronger rather than weaker. You cannot derive an image URN from a version number, because one release can have more than one. Use an alias, or look the URN up, and filter the search: Microsoft notes that az vm image list --all "can take several minutes to produce the entire list". The alias list itself varies by Azure CLI version and cloud, so an alias that works on one machine can be missing on another.
And check what booted, not just what was requested:
ssh -o StrictHostKeyChecking=no azureuser@$VM_IP 'hostname; grep PRETTY_NAME /etc/os-release'
devops-vm
PRETTY_NAME="Ubuntu 22.04.5 LTS"
The image SKU in the VM's configuration says what Azure was asked for. /etc/os-release says what is actually running. Only the second one is evidence.
One smaller thing carried over from yesterday. The temporary disk at /mnt was 8 GiB this time instead of 4, because it comes with the VM size, and Microsoft's size table lists exactly those figures for B1s and B2s. Some newer sizes have no temporary disk at all.
Same thing, different names
A volume that both containers mount is not a path they both agree on. A release of Ubuntu is not a single image name. In both cases the thing each side depended on existed. They were using different names for it, and nothing flagged the difference until something looked in the wrong place.
So here is the Day 53 question. Where in your setup do two components have to agree on a path or a name, with nothing checking that they do?
Day 53 down. Forty-seven to go.
Top comments (0)