نشر PHP على Kubernetes: دليل أساسي
تتطلب تطوير الويب الحديث بشكل متزايد حلولاً قابلة للتوسع ومتسامحة مع الأخطاء. أصبح Kubernetes (K8s) المعيار الفعلي لتنسيق الحاويات. إذا كنت مطور PHP وترغب في إتقان نشر تطبيقاتك على Kubernetes، فهذا الدليل مناسب لك. سننتقل من إنشاء صورة Docker إلى نشر خدمة PHP كاملة في الكتلة.
لماذا نشر PHP على Kubernetes؟
يوفر Kubernetes عددًا من المزايا لتطبيقات PHP:
- التوسع التلقائي: يمكن لـ K8s زيادة عدد الـ Pods عند ارتفاع الحمل وتقليلها عند انخفاضه.
- الشفاء الذاتي: إذا تعطلت الحاوية، سيقوم Kubernetes تلقائيًا بإعادة تشغيلها.
- إدارة التكوين: يمكن بسهولة مركزية متغيرات البيئة وملفات التكوين من خلال ConfigMap و Secrets.
- سهولة التحديثات: تتيح التحديثات المتدرجة (Rolling updates) تحديث التطبيق دون توقف.
هذا مهم بشكل خاص لـ PHP، حيث يصعب توسيع نطاق العديد من المشاريع القديمة بالطرق التقليدية.
الخطوة 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
<?phpecho "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 9000CMD ["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/v1kind: Deploymentmetadata: name: php-app labels: app: php-appspec: 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/v1kind: Deploymentmetadata: name: nginx labels: app: nginxspec: 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