Деплой PHP на Kubernetes: базовое руководство для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Деплой 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

Блоги

Рекомендаций по книгам