You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Kubernetes中Apache+PHP Pod以遵守内存资源限制?

How to Configure Apache to Respect Kubernetes Memory Limits (2GB Per Pod)

Great question—this is one of the most common hurdles when running Apache + PHP in Kubernetes, where strict resource limits mean you can’t let Apache’s process pool run wild and trigger OOM kills. Let’s walk through how to calculate the right settings, apply them, and fix the tradeoffs you’re worried about.

First: Understand the Core Math

Apache’s total memory usage boils down to a simple formula:
Total Memory ≈ Number of Apache/PHP Processes × Average Memory Per Process

Your pod has a 2GB (2048MB) limit, so you need to make sure this product stays well below 2GB (leave a 10-15% buffer to avoid unexpected OOM triggers—aim for ~1.7-1.8GB max).

Step 1: Estimate Per-Process Memory Usage

First, figure out how much memory a single Apache + PHP process consumes:

  • Run a test pod, then exec into it: kubectl exec -it <pod-name> -- /bin/bash
  • Check running processes with ps aux | grep httpd—look at the RSS column (actual memory used per process, in KB). For example, if RSS is ~50000 KB, that’s 50MB per process.
  • You can also check PHP’s baseline memory with php -r "echo memory_get_usage(true) / 1024 / 1024 . 'MB';"—add this to Apache’s own process overhead to get a safe average.

Step 2: Configure Apache’s Core Process Limits

Based on your per-process estimate, adjust these key Apache directives (in httpd.conf or apache2.conf):

Let’s say your average per-process memory is 50MB, and you’re leaving a 200MB buffer:
Max Usable Memory = 2048MB - 200MB = 1848MB
Max Processes = 1848MB / 50MB ≈ 36

Here’s what to set:

  • ServerLimit 36: Sets the maximum number of processes Apache can ever spawn (must be ≥ MaxRequestWorkers).
  • MaxRequestWorkers 36: The total number of concurrent requests Apache can handle—this is the main limit controlling memory usage.
  • StartServers 5: Number of processes to start initially—keep this low to avoid wasting memory on startup.
  • MinSpareServers 5 / MaxSpareServers 10: Controls idle processes to avoid frequent creation/destruction (saves CPU and memory).

Don’t Forget PHP’s memory_limit

In your php.ini, set memory_limit to less than your per-process estimate—e.g., 40MB if your per-process is 50MB. This prevents a single PHP script from eating up all the memory allocated to its Apache process.

Step 3: Apply the Configuration in Kubernetes

Instead of hardcoding these settings into your Docker image (which makes updates a pain), use a ConfigMap to mount the config files into your pod:

  1. Create the ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
  name: apache-php-config
data:
  httpd.conf: |
    # Keep your existing Apache config, add/update these lines:
    ServerLimit 36
    MaxRequestWorkers 36
    StartServers 5
    MinSpareServers 5
    MaxSpareServers 10
  php.ini: |
    # Update PHP memory limit
    memory_limit = 40M
    # Add optimizations like OPcache
    opcache.enable = 1
    opcache.memory_consumption = 64
  1. Update your Deployment to mount the ConfigMap:
spec:
  replicas: 3 # Your desired starting replicas
  template:
    spec:
      containers:
      - name: apache-php
        image: your-apache-php-image:tag
        resources:
          limits:
            memory: "2Gi"
            cpu: "1" # Adjust based on your workload
          requests:
            memory: "1Gi" # Help scheduler place pods efficiently
            cpu: "500m"
        volumeMounts:
        - name: apache-config
          mountPath: /usr/local/apache2/conf/httpd.conf # Match your image's config path
          subPath: httpd.conf
        - name: apache-config
          mountPath: /usr/local/etc/php/php.ini # Match your PHP ini path
          subPath: php.ini
      volumes:
      - name: apache-config
        configMap:
          name: apache-php-config

Fixing the Tradeoffs: What If Concurrent Capacity Drops?

Lowering MaxRequestWorkers reduces your pod’s concurrent capacity—but Kubernetes has tools to offset this:

1. Use Horizontal Pod Autoscaler (HPA)

Let Kubernetes automatically add/remove pods based on CPU/memory usage. Example:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: apache-php-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: apache-php-deployment
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

This adds replicas when CPU hits 70%—so total concurrent capacity scales with demand.

2. Switch to a More Efficient Apache MPM

If you’re using the default prefork MPM (one process per request), switch to event MPM. It uses threads for request handling, cutting memory usage per request drastically. Note: If you use mod_php, event may cause issues—instead, use PHP-FPM with Apache (Apache forwards requests to a PHP-FPM pool, which manages processes more efficiently).

3. Optimize PHP and Apache

  • Enable OPcache for PHP: Caches compiled scripts, reducing memory and CPU load.
  • Disable unused Apache modules: Every enabled module adds overhead—strip out what you don’t need (e.g., mod_autoindex if you don’t serve static directories).
  • Clean up PHP code: Fix memory leaks, avoid loading unnecessary libraries, and use efficient data structures.

4. Monitor and Tweak

Track these metrics (use Kubernetes’ built-in tools or Prometheus + Grafana):

  • Pod memory usage (aim for ~80% of the limit under peak load)
  • Apache’s request queue length (if consistently high, increase MaxRequestWorkers or add replicas via HPA)
  • PHP-FPM pool status (if using FPM)

Final Tips

  • Always leave a memory buffer: Kubernetes’ OOM killer is aggressive—don’t let Apache use 100% of the limit.
  • Test with load: Use ab or wrk to simulate traffic and validate settings:
    ab -n 1000 -c 50 http://your-service-url/
    
  • Add liveness/readiness probes: Restart unresponsive pods or those using too much memory (a last-resort safety net):
    livenessProbe:
      httpGet:
        path: /health.php # Create a simple health check endpoint
        port: 80
      initialDelaySeconds: 30
      periodSeconds: 10
      failureThreshold: 3
    

内容的提问来源于stack exchange,提问作者Jan Imrich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:20:05