PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Kubernetes for the PHP developer – kubectl debugging, Deployment YAML, HPA, troubleshooting

by Henryk Tews / Friday, 21 March 2025 / Published in Środowiska

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.

About Henryk Tews

What you can read next

OpenTelemetry – distributed tracing, auto-instrumentation, Jaeger in DDEV
Docker from scratch – Dockerfile, nginx, docker-compose, Xdebug 3.x
GitHub Actions – PHP pipeline, test matrix, staging deploy via SSH

© 2026 Created by

TOP
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Always active
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
Zobacz preferencje
  • {title}
  • {title}
  • {title}