Деплой PHP на Kubernetes: базовое руководство для начинающих
Kubernetes (K8s) стал стандартом де-факто для оркестрации контейнеров. Если вы PHP-разработчик, рано или поздно столкнетесь с необходимостью развернуть своё приложение в кластере. В этом руководстве мы разберем, как превратить обычное PHP-приложение в полноценный сервис, работающий под управлением Kubernetes. Вы узнаете, как подготовить Docker-образ, написать манифесты и запустить всё это в локальном кластере (например, Minikube).
Мы будем использовать классическую связку: PHP-FPM для обработки PHP-скриптов и NGINX в качестве веб-сервера. Это позволит нам добиться высокой производительности и гибкости.
1. Подготовка PHP-приложения и Docker-образа
Первый шаг — упаковка вашего PHP-кода в Docker-контейнер. Мы создадим два образа: один для PHP-FPM, второй для NGINX (или используем один образ с супервизором, но для новичков проще разделить).
Создайте файл Dockerfile для PHP-FPM:
FROM php:8.2-fpm-alpine
# Устанавливаем расширения
RUN docker-php-ext-install pdo_mysql mysqli opcache
# Копируем код приложения
COPY . /var/www/html
# Настройки PHP
COPY php.ini /usr/local/etc/php/conf.d/custom.ini
WORKDIR /var/www/html
EXPOSE 9000
CMD ["php-fpm"]
Для NGINX создайте отдельный Dockerfile:
FROM nginx:alpine
# Копируем конфигурацию
COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf
# Статические файлы (если есть)
COPY public/ /var/www/html/public/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Не забудьте про файл default.conf для NGINX, который проксирует запросы к PHP-FPM:
server {
listen 80;
server_name _;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass php-service:9000; # имя сервиса в K8s
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Соберите образы командой:
docker build -t my-php-app:latest -f Dockerfile.php .
docker build -t my-nginx:latest -f Dockerfile.nginx .
2. Основы Kubernetes: Pods, Deployments и Services
Прежде чем писать манифесты, разберемся с базовыми объектами K8s:
- Pod — минимальная единица развертывания, один или несколько контейнеров.
- Deployment — управляет репликами Pod'ов, обеспечивает обновления и откаты.
- Service — стабильная точка доступа к Pod'ам (внутри кластера или снаружи).
Для нашего PHP-приложения мы создадим два Deployment: один для PHP-FPM, второй для NGINX. Затем свяжем их через внутренний Service.
3. Написание манифестов для PHP и NGINX
Создайте файл php-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-app
spec:
replicas: 2
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"
---
apiVersion: v1
kind: Service
metadata:
name: php-service
spec:
selector:
app: php-app
ports:
- protocol: TCP
port: 9000
targetPort: 9000
Теперь создайте nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: my-nginx:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort # для доступа извне (локально)
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
Обратите внимание: NGINX обращается к PHP-FPM по имени сервиса php-service:9000, которое K8s разрешает в IP-адрес Pod'а.
4. Деплой и проверка работы
Убедитесь, что у вас запущен Minikube или другой кластер. Примените манифесты:
kubectl apply -f php-deployment.yaml
kubectl apply -f nginx-deployment.yaml
Проверьте статус подов:
kubectl get pods
Дождитесь, когда все Pod'ы перейдут в статус Running. Затем получите доступ к приложению:
minikube service nginx-service --url
Если всё настроено правильно, вы увидите вывод вашего PHP-приложения (например, phpinfo() или главную страницу).
5. Масштабирование и обновление
Одно из главных преимуществ Kubernetes — простое масштабирование. Чтобы увеличить количество реплик PHP-FPM, выполните:
kubectl scale deployment php-app --replicas=5
Для обновления образа (например, после изменения кода) используйте стратегию Rolling Update. Измените тег образа в манифесте и примените его снова, либо выполните:
kubectl set image deployment/php-app php-fpm=my-php-app:v2