简体   繁体   中英

How can I set a kubernetes pod so php-fpm and nginx can manipulate data on a persistent volume?

I am trying to run Grav CMS on Kubernetes. However I am running into a permissions problem. Grav is not able to write to the mounted volume.

These are the relevant object definitions. The latest version of Grav is already extracted to the persistent volume bound to grav-data .

# pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  volumes:
    - name: shared-files
      persistentVolumeClaim:
        claimName: grav-data
    - name: nginx-config-volume
      configMap:
        name: nginx-config
  containers:
    - name: app
      image: php:7.4-fpm
      imagePullPolicy: Always
      volumeMounts:
        - name: shared-files
          mountPath: /var/www/html
    - name: nginx
      image: nginx:1.7
      volumeMounts:
        - name: shared-files
          mountPath: /var/www/html
        - name: nginx-config-volume
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
    - name: tty      
      image: busybox:latest
      command: [ "/bin/sh", "-c", "sleep 6000" ]
      volumeMounts:
        - name: shared-files
          mountPath: /var/www/html



---

# configMap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
data:
  nginx.conf: |
    events {}
    http {
      error_log /dev/stdout info;
      server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        root /var/www/html;
        index index.php;
        location / {
            try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
          include fastcgi_params;
          fastcgi_param REQUEST_METHOD $request_method;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_pass 127.0.0.1:9000;
        }
      }
    }

From the definitions above, php-fpm should be running as root. But when I exec into the busybox container

$ k exec -it --container=tty web
$ wget -O - localhost
Connecting to localhost (127.0.0.1:80)
writing to stdout
<br />
<b>Fatal error</b>:  Uncaught RuntimeException: Creating directory failed for /var/www/html/cache/compiled/files/40779d000b68629af00dd987148afc06.yaml.php in /var/www/html/ve
ndor/rockettheme/toolbox/File/src/File.php:325
Stack trace:
#0 /var/www/html/vendor/rockettheme/toolbox/File/src/PhpFile.php(31): RocketTheme\Toolbox\File\File-&gt;save(Array)
#1 /var/www/html/system/src/Grav/Common/File/CompiledFile.php(65): RocketTheme\Toolbox\File\PhpFile-&gt;save(Array)
#2 /var/www/html/system/src/Grav/Common/Config/Setup.php(215): Grav\Common\File\CompiledYamlFile-&gt;content()
#3 /var/www/html/system/src/Grav/Common/Service/ConfigServiceProvider.php(30): Grav\Common\Config\Setup-&gt;init()
#4 /var/www/html/vendor/pimple/pimple/src/Pimple/Container.php(118): Grav\Common\Service\ConfigServiceProvider-&gt;Grav\Common\Service\{closure}(Object(Grav\Common\Grav))
#5 /var/www/html/system/src/Grav/Common/Grav.php(166): Pimple\Container-&gt;offsetGet('setup')
#6 /var/www/html/system/src/Grav/Common/Grav.php(492): Grav\Common\Grav-&gt;Grav\Common\{closure}()
#7 /var/ in <b>/var/www/html/system/src/Grav/Common/File/CompiledFile.php</b> on line <b>81</b><br />
-                    100% |******************************************************************************************************************************|  1167  0:00:00 ETA
written to stdout

I've tried adding a securityContext to the pod spec just to make sure nginx and php are run by the same user, but this prevents nginx from binding on 80/443. I've also tried exec-ing into the pod and I am able to modify files on the PV manually from both containers. How can I set up my pod spec so that Grav can write to the persistent volume claim mounted to /var/www/html ?


UPDATE I don't have time to look further into it right now, but I suspect this is related to php-fpm spawning child processes as www-data user.

First of all, it might be easier to use the Docker provided by Grav .

I tried to reproduce your problem with the following manifest:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grav-data
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard
---
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    run: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      run: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        run: web
    spec:
      volumes:
        - name: shared-files
          persistentVolumeClaim:
            claimName: grav-data
        - name: nginx-config-volume
          configMap:
            name: nginx-config
      containers:
        - name: app
          image: php:7.4-fpm
          imagePullPolicy: Always
          volumeMounts:
            - name: shared-files
              mountPath: /usr/share/nginx/html:ro
        - name: nginx
          image: nginx:1.7
          volumeMounts:
            - name: shared-files
              mountPath: /usr/share/nginx/html:ro
            - name: nginx-config-volume
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf
        - name: tty      
          image: busybox:latest
          command: [ "/bin/sh", "-c", "sleep 6000" ]
          volumeMounts:
            - name: shared-files
              mountPath: /usr/share/nginx/html:ro
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
data:
  nginx.conf: |
    events {}
    http {
      error_log /dev/stdout info;
      server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name localhost;
        root /usr/share/www/html;
        index index.php;
        location / {
            try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
          include fastcgi_params;
          fastcgi_param REQUEST_METHOD $request_method;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_pass 127.0.0.1:9000;
        }
      }
    }

I'm using the Minikube StorageClass, so it provides me automatically with a PersistentVolume at /tmp/hostpath-provisioner/..., mounted at /usr/share/www/html:ro.

I've installed Grav with composer and ran:

wget -O - localhost
Connecting to localhost (127.0.0.1:80)
wget: server returned error: HTTP/1.1 404 Not Found

Same with localhost/grav. It would be great to have some additional details to reproduce the problem (503).

I think your life will be so much easier if you deploy PHP-FPM and NGINX in separate pods with the service abstraction, considering you need to configure communication through the tcp port (127.0.0.1:9000) or unix socket (/var/run/php-fpm.sock).

You're probably not the first to install PHP-FPM and NGINX, there's a great tutorial on Digital Ocean for this set-up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM