【问题标题】:How can I set a kubernetes pod so php-fpm and nginx can manipulate data on a persistent volume?如何设置 kubernetes pod,以便 php-fpm 和 nginx 可以操作持久卷上的数据?
【发布时间】:2020-07-19 23:23:49
【问题描述】:

我正在尝试在 Kubernetes 上运行 Grav CMS。但是我遇到了权限问题。 Grav 无法写入已安装的卷。

这些是相关的对象定义。最新版本的 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;
        }
      }
    }

根据上面的定义,php-fpm 应该以 root 身份运行。但是当我执行进入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

我尝试在 pod 规范中添加 securityContext,以确保 nginx 和 php 由同一用户运行,但这会阻止 nginx 绑定到 80/443。我也尝试在 pod 中执行,并且我可以从两个容器手动修改 PV 上的文件。如何设置我的 pod 规范,以便 Grav 可以写入挂载到 /var/www/html 的持久卷声明?


更新我现在没有时间进一步研究它,但我怀疑这与php-fpmwww-data 用户的身份产生子进程有关。

【问题讨论】:

    标签: php nginx kubernetes


    【解决方案1】:

    首先,使用Docker provided by Grav 可能更容易。

    我尝试使用以下清单重现您的问题:

    ---
    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;
            }
          }
        }
    

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

    我已经用 composer 安装了 Grav 并运行:

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

    与 localhost/grav 相同。如果有一些额外的细节来重现问题(503),那就太好了。

    考虑到您需要通过 tcp 端口 (127.0.0.1:9000) 或 unix 套接字 (/ var/run/php-fpm.sock)。

    您可能不是第一个安装 PHP-FPM 和 NGINX 的人,这个设置有一个很棒的 tutorial on Digital Ocean

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 2014-04-28
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多