简体   繁体   English

如何设置 kubernetes pod 以便 php-fpm 和 nginx 可以操作持久卷上的数据?

[英]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.我正在尝试在 Kubernetes 上运行 Grav CMS However I am running into a permissions problem.但是我遇到了权限问题。 Grav is not able to write to the mounted volume. Grav 无法写入已安装的卷。

These are the relevant object definitions.这些是相关的 object 定义。 The latest version of Grav is already extracted to the persistent volume bound to grav-data .最新版本的 Grav 已被提取到绑定到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.根据上面的定义,php-fpm 应该以 root 身份运行。 But when I exec into the busybox container但是当我执行进入busybox容器时

$ 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.我已经尝试将securityContext添加到 pod 规范中,以确保 nginx 和 php 由同一用户运行,但这会阻止 ZEE434023CF89D7DFB21F63D64F0F44374Z/8 绑定。 I've also tried exec-ing into the pod and I am able to modify files on the PV manually from both containers.我也尝试在 pod 中执行,并且我可以从两个容器手动修改 PV 上的文件。 How can I set up my pod spec so that Grav can write to the persistent volume claim mounted to /var/www/html ?如何设置我的 pod 规范,以便 Grav 可以写入挂载到/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.更新我现在没有时间进一步研究它,但我怀疑这与php-fpm作为www-data用户生成子进程有关。

First of all, it might be easier to use the Docker provided by Grav .首先,使用Grav 提供的 Docker 可能更容易。

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.我正在使用 Minikube StorageClass,因此它会自动为我提供位于 /tmp/hostpath-provisioner/... 的 PersistentVolume,安装在 /usr/share/www/html:ro。

I've installed Grav with composer and ran:我已经用作曲家安装了 Grav 并运行:

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.与 localhost/grav 相同。 It would be great to have some additional details to reproduce the problem (503).如果有一些额外的细节来重现问题(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). 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.您可能不是第一个安装 PHP-FPM 和 NGINX 的人,关于此设置的Digital Ocean 上有一个很棒的教程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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