Интеграция PHP с Kubernetes: развертывание и управление приложениями

Интеграция PHP с Kubernetes: Развертывание и Управление Приложениями

Kubernetes (K8s) уже давно стал стандартом де-факто для оркестрации контейнеров. Это платформа, которая автоматизирует развертывание, масштабирование и управление приложениями, упакованными в контейнеры. Для PHP разработчиков, привыкших к традиционным хостинговым решениям, переход на Kubernetes может показаться сложным, но преимущества в плане масштабируемости, отказоустойчивости и эффективности использования ресурсов стоит того. В этой статье мы рассмотрим, как интегрировать PHP-приложение с Kubernetes, включая шаги по развертыванию и управлению.

Docker – неотъемлемая часть Kubernetes. Перед тем как говорить о Kubernetes, убедитесь, что вы владеете основами работы с Docker, включая создание и запуск контейнеров. Мы будем подразумевать, что у вас уже настроена среда разработки с Docker и kubectl (командная строка для управления Kubernetes).


1. Контейнеризация PHP-приложения с Docker

Первый шаг – упаковка PHP-приложения в Docker-контейнер. Это изолирует приложение и его зависимости, гарантируя, что оно будет работать одинаково на разных средах.

Создайте файл Dockerfile в корне вашего PHP-проекта:

FROM php:8.2-fpm-alpine  # Используем официальный PHP образ на базе Alpine Linux
WORKDIR /var/www/html
Установка необходимых расширений PHP
RUN docker-php-ext-install pdo pdo_mysql mysqli  && \
composer install --no-interaction --optimize-autoloader
Копирование файлов приложения
COPY . .
Установка прав доступа

* FROM: Задает базовый образ, в нашем случае – PHP 8.2 с FPM (FastCGI Process Manager) на Alpine Linux. Alpine – легковесный дистрибутив Linux, что делает образ более компактным.

* WORKDIR: Устанавливает рабочую директорию внутри контейнера.

* RUN: Выполняет команды внутри контейнера. Здесь мы устанавливаем необходимые PHP-расширения (PDO, MySQL, mysqli) и запускаем composer install для установки зависимостей проекта.

* COPY: Копирует файлы приложения из текущей директории в контейнер.

* chown: Изменяет владельца файлов, чтобы веб-сервер имел доступ к ним.

Теперь соберите Docker-образ:

docker build -t my-php-app .

После этого запустите контейнер локально для проверки:

docker run -d -p 9000:9000 my-php-app

Если все настроено правильно, вы сможете зайти в приложение через http://localhost:9000.

> Важно: Убедитесь, что ваше приложение правильно настроено для работы с PHP-FPM. Обычно, это предполагает наличие nginx или другого обратного прокси, который будет перенаправлять запросы к FPM.


2. Создание Kubernetes Deployment и Service

Теперь, когда у нас есть Docker-образ, мы можем развернуть его в Kubernetes. Для этого нам понадобятся два основных ресурса: Deployment и Service.

* Deployment управляет репликами вашего приложения (контейнерами) и обеспечивает их желаемое состояние.

* Service предоставляет стабильный IP-адрес и DNS-имя для доступа к вашему приложению.

Создайте файл deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-php-app-deployment
spec:
replicas: 3  # Запускаем 3 реплики
selector:
matchLabels:
app: my-php-app
template:
metadata:
labels:
app: my-php-app
spec:
containers:
- name: my-php-app-container
image: my-php-app
ports:

Создайте файл service.yaml:

apiVersion: v1
kind: Service
metadata:
name: my-php-app-service
spec:
selector:
app: my-php-app
ports:
- protocol: TCP
port: 80
targetPort: 9000

Примените эти файлы к Kubernetes:

kubectl apply -f deployment.yaml

> Важно: type: LoadBalancer не всегда поддерживается (особенно в локальной среде). В этом случае можно использовать type: NodePort и получить доступ к приложению через IP-адрес узла Kubernetes и порт, указанный в YAML. Для Minikube можно использовать kubectl port-forward service/my-php-app-service 8080:80.


3. Конфигурация Persistent Volumes (PV) и Persistent Volume Claims (PVC)

Если ваше PHP-приложение использует базу данных или хранит файлы, критичные для работы, вам потребуется Persistent Volumes и Persistent Volume Claims. Persistent Volumes предоставляют постоянное хранилище, которое не привязывается к определенному контейнеру. Persistent Volume Claims позволяют контейнерам запрашивать Persistent Volumes.

В реальной среде, PV обычно предоставляются администратором кластера. Для демонстрации, предположим, что у нас есть PV, и мы создаем PVC для использования этого PV.

Создайте файл pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-php-app-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:

Отредактируйте deployment.yaml, чтобы подключить PVC к контейнеру:

volumeMounts:
- name: my-php-app-volume

Создайте файл pv.yaml (только для демонстрации, в реальной среде PV уже должен существовать):

apiVersion: v1
kind: PersistentVolume
metadata:
name: my-php-app-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:

Примените файлы:

kubectl apply -f pvc.yaml

> Важно: Использование hostPath для Persistent Volumes подходит только для целей разработки и тестирования. В production среде нужно использовать настоящие Persistent Volumes, предоставленные вашим провайдером Kubernetes (например, AWS EBS, Google Persistent Disk). Также, ReadWriteOnce не подходит для нескольких контейнеров, которым нужен доступ к хранилищу.


4. Использование ConfigMaps и Secrets

ConfigMaps позволяют хранить конфигурационные данные отдельно от кода приложения, что облегчает управление и изменение конфигурации. Secrets предназначены для хранения конфиденциальной информации, такой как пароли и ключи API.

Создайте файл configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
name: my-php-app-config
data:
APP_NAME: "My Awesome App"

Отредактируйте deployment.yaml, чтобы сделать ConfigMap доступным для контейнера:

env:
- name: APP_NAME
valueFrom:
configMapKeyRef:
name: my-php-app-config
key: APP_NAME
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: my-php-app-config

Создайте файл secret.yaml:

apiVersion: v1
kind: Secret
metadata:
name: my-php-app-secret
type: Opaque
data:
DATABASE_PASSWORD: $(echo -n "mysecretpassword" | base64) # Пример, нужно использовать настоящий base64 encoding

Отредактируйте deployment.yaml, чтобы сделать Secret доступным для контейнера:

env:
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: my-php-app-secret
key: DATABASE_PASSWORD
- name: API_KEY
valueFrom:
secretKeyRef:
name: my-php-app-secret

Примените файлы:

kubectl apply -f configmap.yaml

<?php
//  Доступ к ConfigMap и Secret переменным окружения
$appName = getenv('APP_NAME');
$databaseHost = getenv('DATABASE_HOST');
$databasePassword = getenv('DATABASE_PASSWORD');
$apiKey = getenv('API_KEY');
echo "App Name: " . $appName . "<br>";
echo "Database Host: " . $databaseHost . "<br>";
echo "Database Password: " . $databasePassword . "<br>";
echo "API Key: " . $apiKey . "<br>";


Заключение

Интеграция PHP с Kubernetes требует определенных усилий на старте, но она открывает огромные возможности для масштабирования, автоматизации и повышения отказоустойчивости ваших приложений. Описанные шаги – это лишь отправная точка. Kubernetes предоставляет множество других возможностей, таких как health checks, liveness probes, readiness probes, horizontal pod autoscaling и другие, которые позволяют еще более эффективно управлять PHP-приложениями. Освоив эти концепции, вы сможете создавать мощные и надежные PHP-приложения, готовые к работе в современных облачных средах. Удачи!