php - 如何设置 kubernetes pod,以便 php-fpm 和 nginx 可以操作持久卷上的数据?
问题描述
我正在尝试在 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->save(Array)
#1 /var/www/html/system/src/Grav/Common/File/CompiledFile.php(65): RocketTheme\Toolbox\File\PhpFile->save(Array)
#2 /var/www/html/system/src/Grav/Common/Config/Setup.php(215): Grav\Common\File\CompiledYamlFile->content()
#3 /var/www/html/system/src/Grav/Common/Service/ConfigServiceProvider.php(30): Grav\Common\Config\Setup->init()
#4 /var/www/html/vendor/pimple/pimple/src/Pimple/Container.php(118): Grav\Common\Service\ConfigServiceProvider->Grav\Common\Service\{closure}(Object(Grav\Common\Grav))
#5 /var/www/html/system/src/Grav/Common/Grav.php(166): Pimple\Container->offsetGet('setup')
#6 /var/www/html/system/src/Grav/Common/Grav.php(492): Grav\Common\Grav->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
我尝试securityContext
在 pod 规范中添加一个以确保 nginx 和 php 由同一用户运行,但这会阻止 nginx 绑定到 80/443。我也尝试在 pod 中执行,并且我可以从两个容器手动修改 PV 上的文件。如何设置我的 pod 规范,以便 Grav 可以写入挂载到的持久卷声明/var/www/html
?
更新我现在没有时间进一步研究它,但我怀疑这与作为用户生成php-fpm
子进程有关。www-data
解决方案
首先,使用Grav 提供的 Docker可能会更容易一些。
我尝试使用以下清单重现您的问题:
---
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。
我已经用作曲家安装了 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 的人,关于此设置的Digital Ocean 有一个很棒的教程。
推荐阅读
- php - 尝试为 php 安装 geoip 扩展,找不到错误 pecl5.6 命令
- angular - 使用 ng-packagr 时出错:找不到模块:错误:无法解析
- asp.net - Task.Factory.StartNew 在没有调试模式的情况下运行时不起作用
- gensim - gensim 中 malletmodel2ldamodel 后的主题词分布问题
- regex - sed to edit a line on a file
- django - Django 查询集对象查询花费太多时间?
- python - 在 for 循环中向前 x 个项目添加不同的特定项目,而不使用 enumerate
- regex - 需要一个不接受第二个点的十进制数的正则表达式
- azure - 不支持关键字:@microsoft.keyvault
- javascript - 在 Node.js 模块中使用函数