Most PHP applications eventually run on Kubernetes – but developers rarely touch it until something breaks in production. Understanding the basics of Deployments, Services, ConfigMaps, and HPA makes debugging much faster. I show the minimum Kubernetes knowledge a PHP/Magento developer needs: reading logs, exec into pods, understanding why a pod is crashing, and writing a sensible Deployment YAML.
Core concepts in 5 minutes
| Concept | Docker/Compose equivalent | What it does |
|---|---|---|
| Pod | Container | One or more containers that share network/storage |
| Deployment | Service with replicas | Manages N identical pods, handles rolling updates |
| Service | Port mapping / DNS entry | Stable endpoint for reaching pods (load balances) |
| ConfigMap | .env file | Non-secret configuration injected into pods |
| Secret | secrets: in compose | Sensitive config (passwords, keys) injected into pods |
| Ingress | nginx reverse proxy | Routes external HTTP/HTTPS traffic to Services |
| HPA | N/A in compose | Horizontal Pod Autoscaler – scales replicas based on CPU/mem |
| Namespace | docker-compose project name | Logical isolation group for resources |
Essential kubectl commands for PHP developers
# List pods in namespace kubectl get pods -n magento-prod kubectl get pods -n magento-prod -w # watch for changes # Logs from a pod (like docker logs) kubectl logs -n magento-prod pod/magento-php-abc123 kubectl logs -n magento-prod pod/magento-php-abc123 --previous # crashed pod logs kubectl logs -n magento-prod -l app=magento-php --tail=100 # all pods with label # Execute into a running pod (like docker exec) kubectl exec -it -n magento-prod pod/magento-php-abc123 -- bash kubectl exec -it -n magento-prod pod/magento-php-abc123 -- bin/magento cache:flush # Describe a pod (shows events, which is where errors appear) kubectl describe pod -n magento-prod magento-php-abc123 # Port-forward to access a service locally kubectl port-forward -n magento-prod svc/magento-redis 6379:6379 # Check resource usage kubectl top pods -n magento-prod kubectl top nodes
Deployment YAML for PHP-FPM
apiVersion: apps/v1
kind: Deployment
metadata:
name: magento-php
namespace: magento-prod
spec:
replicas: 3
selector:
matchLabels:
app: magento-php
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # add 1 extra pod during update
maxUnavailable: 0 # never go below desired replicas
template:
metadata:
labels:
app: magento-php
spec:
containers:
- name: php-fpm
image: your-registry/magento:2.4.8-php8.4
ports:
- containerPort: 9000
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
env:
- name: MAGENTO_MODE
value: production
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: magento-db-credentials
key: password
livenessProbe:
exec:
command: ["php-fpm-healthcheck"]
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
exec:
command: ["php-fpm-healthcheck", "--accepted-conn", "1"]
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: magento-media
mountPath: /var/www/html/pub/media
volumes:
- name: magento-media
persistentVolumeClaim:
claimName: magento-media-pvc
Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: magento-php-hpa
namespace: magento-prod
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: magento-php
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # scale up when average CPU > 70%
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Debugging a crashing pod – systematic approach
# Pod is in CrashLoopBackOff - systematic debugging # 1. Check the events first kubectl describe pod -n magento-prod magento-php-abc123 # Look for: Events section at the bottom - most useful diagnostic info # 2. Get logs from the crashed container kubectl logs -n magento-prod magento-php-abc123 --previous # 3. Common causes and fixes: # OOMKilled (Out of Memory): # kubectl describe pod ... | grep -i "OOM\|memory\|killed" # Fix: increase memory limits in Deployment YAML # ImagePullBackOff: # kubectl describe pod ... | grep "image\|pull" # Fix: check registry credentials (imagePullSecrets) # CrashLoopBackOff with "env not found": # The container expects an env var from a Secret that doesn't exist # kubectl get secrets -n magento-prod # kubectl describe secret magento-db-credentials -n magento-prod # Readiness probe failing: # PHP-FPM started but Magento bootstrap fails (missing env var, DB unreachable) # kubectl exec into pod and run the probe command manually: kubectl exec -n magento-prod magento-php-abc123 -- php-fpm-healthcheck
Magento-specific: cron and queue consumers as Jobs/Deployments
# CronJob for Magento cron
apiVersion: batch/v1
kind: CronJob
metadata:
name: magento-cron
namespace: magento-prod
spec:
schedule: "* * * * *" # every minute, like the system cron entry
concurrencyPolicy: Forbid # don't start new job if previous still running
jobTemplate:
spec:
template:
spec:
containers:
- name: cron
image: your-registry/magento:2.4.8-php8.4
command: ["php", "bin/magento", "cron:run"]
restartPolicy: Never
Summary
A PHP developer on a Kubernetes cluster needs six commands: get pods, logs, exec, describe, top, port-forward. Describe is the most valuable for debugging – it shows events and probe failures that logs alone do not capture. The Deployment YAML for PHP-FPM is straightforward once you understand requests/limits, liveness/readiness probes, and rolling update strategy. HPA handles traffic spikes automatically – the main requirement is having proper resource requests set on the Deployment.
