Деплой PHP на Kubernetes: базовое руководство
Современная веб-разработка всё чаще требует масштабируемых и отказоустойчивых решений. Kubernetes (K8s) стал стандартом де-факто для оркестрации контейнеров. Если вы PHP-разработчик и хотите освоить деплой своих приложений в Kubernetes — это руководство для вас. Мы пройдём путь от создания Docker-образа до развёртывания полноценного PHP-сервиса в кластере.
Зачем деплоить PHP на Kubernetes?
Kubernetes предоставляет ряд преимуществ для PHP-приложений:
- Автоматическое масштабирование: K8s может увеличивать количество подов при росте нагрузки и уменьшать при её спаде.
- Самоисцеление: Если контейнер упадёт, Kubernetes автоматически перезапустит его.
- Управление конфигурацией: Переменные окружения и конфигурационные файлы легко централизовать через ConfigMap и Secrets.
- Простота обновлений: Rolling updates позволяют обновлять приложение без даунтайма.
Для PHP это особенно актуально, так как многие legacy-проекты сложно масштабировать традиционными методами.
Шаг 1: Контейнеризация PHP-приложения
Прежде чем деплоить приложение в Kubernetes, его нужно упаковать в Docker-образ. Рассмотрим пример простого PHP-приложения с использованием Nginx и PHP-FPM.
Создаём структуру проекта
my-php-app/
├── src/
│ └── index.php
├── docker/
│ ├── nginx/
│ │ └── default.conf
│ └── php/
│ └── Dockerfile
└── docker-compose.yml
Пример src/index.php
<?php
echo "Hello from PHP on Kubernetes!";
phpinfo();
?>
Dockerfile для PHP-FPM
FROM php:8.2-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql
COPY src/ /var/www/html/
EXPOSE 9000
CMD ["php-fpm"]
Конфигурация Nginx (docker/nginx/default.conf)
server {
listen 80;
server_name localhost;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Сборка образа
docker build -t my-php-app:latest -f docker/php/Dockerfile .
Шаг 2: Написание манифестов Kubernetes
Теперь, когда образ готов, создадим манифесты для развёртывания в кластере.
Deployment для PHP-FPM
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-app
labels:
app: php-app
spec:
replicas: 3
selector:
matchLabels:
app: php-app
template:
metadata:
labels:
app: php-app
spec:
containers:
- name: php-fpm
image: my-php-app:latest
ports:
- containerPort: 9000
env:
- name: DB_HOST
value: "mysql-service"
- name: DB_NAME
value: "mydb"
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
Deployment для Nginx
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
volumes:
- name: nginx-config
configMap:
name: nginx-config
ConfigMap для конфигурации Nginx
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
server {
listen 80;
server_name _;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php-service:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Service для доступа к приложению
apiVersion: v1
kind: Service
metadata:
name: php-service
spec:
selector:
app: php-app
ports:
- protocol: TCP
port: 9000
targetPort: 9000
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
Шаг 3: Развёртывание в кластере
Теперь применим все манифесты:
kubectl apply -f deployment-php.yaml
kubectl apply -f deployment-nginx.yaml
kubectl apply -f configmap-nginx.yaml
kubectl apply -f services.yaml
Проверим статус подов:
kubectl get pods
Вы должны увидеть что-то вроде:
NAME READY STATUS RESTARTS AGE
php-app-7d4b9f6b8c-abc12 1/1 Running 0 2m
php-app-7d4b9f6b8c-def34 1/1 Running 0 2m
php-app-7d4b9f6b8c-ghi56 1/1 Running 0 2m
nginx-5c8d7f9b78-jkl78 1/1 Running 0 2m
nginx-5c8d7f9b78-mno90 1/1 Running 0 2m
Доступ к приложению
Если вы используете Minikube, выполните:
minikube service nginx-service
В облачном кластере (GKE, EKS, AKS)