k8s中subpath挂载单个文件报错处理
1.报错环境
此环境是由于k8s中挂载单个配置文件导致,需要挂载的目标配置文件为/etc/nginx/conf.d/default.conf。
以下演示仅分为2步,首先创建configmap,然后在deployment的配置文件中引用挂载这个configamap到pod中容器为nginx的默认文件上。
首先创建一个configmap
[root@public test]# kubectl create configmap nginx-php-config --from-file=./nginx.conf -n devcon #该Nginx配置文件只是一个默认的nginx配置文件 [root@public test]# cat nginx.conf server{ listen 80; charset utf-8; proxy_connect_timeout 5; proxy_read_timeout 10; proxy_send_timeout 15; fastcgi_connect_timeout 5; fastcgi_read_timeout 10; fastcgi_send_timeout 15; fastcgi_buffers 2 256k; fastcgi_buffer_size 128k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; location / { rewrite ^/(.*)$ /index.php?s=/$1 last; } location ~ [^/]\.php(/|$) { root /usr/share/nginx/html/public; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
查看deployment.yaml文件,pod里面有2个容器,nignx和php。主要是挂载到nginx的默认配置文件。
apiVersion: apps/v1 kind: Deployment metadata: name: gcc-21ldj-backend namespace: dev spec: replicas: 1 selector: matchLabels: app: gcc-21ldj-backend template: metadata: labels: app: gcc-21ldj-backend spec: containers: - image: denadocker.tencentcloudcr.com/h5-web/gcc-21ldj-backend:develop-7 lifecycle: postStart: exec: command: - /bin/sh - -c - cp -r /app/. /usr/share/nginx/html name: php-fpm ports: - containerPort: 9000 resources: limits: cpu: 500m memory: 500Mi requests: cpu: 100m memory: 100Mi volumeMounts: - mountPath: /usr/share/nginx/html name: nginx-www - image: nginx:1.19.10-alpine name: nginx ports: - containerPort: 80 resources: limits: cpu: 500m memory: 500Mi requests: cpu: 100m memory: 100Mi volumeMounts: - mountPath: /usr/share/nginx/html name: nginx-www - mountPath: /etc/nginx/conf.d/default.conf name: nginx-php-config #这里就是挂载单独配置文件的配置 subPath: default.conf imagePullSecrets: - name: tcr-h5web-dev volumes: - emptyDir: {} name: nginx-www - configMap: name: nginx-php-config name: nginx-php-config
在volumeMouonts.mountPath.subPath中指定挂载的配置文件,(官方指定挂载单个文件固定方式)。一切都没有问题,但是在部署的时候,nginx的一直无法启动,提示如下错误。
报错Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type,并且pod只有一个容器是启动状态。
2.报错处理
经过各种问题排查,使用过其它镜像,k8s版本等等其它方式,都没有解决。最后仔细看了一下挂载的文件路径/etc/nginx/conf.d/default.conf,最后核对发现,创建configmap.yaml时,文件名是nginx.conf,会不会是这个问题?将nginx.conf改名为default.conf之后果然解决。
首先看一下使用文件名nginx.conf创建configmap后的k8s输出。
[root@public test]# kubectl create configmap nginx-php-config --from-file=./nginx.conf -n devcon [root@public test]# kubectl get configmap nginx-php-config -n dev -o yaml apiVersion: v1 data: #配置文件名为nginx.conf nginx.conf: |+ server{ listen 80; charset utf-8; proxy_connect_timeout 5; proxy_read_timeout 10; proxy_send_timeout 15; fastcgi_connect_timeout 5; fastcgi_read_timeout 10; fastcgi_send_timeout 15; fastcgi_buffers 2 256k; fastcgi_buffer_size 128k; ……… #这里只展示一些重要配置
可以看到,配置文件名是nginx.conf.
现在将配置文件改名然后在创建configmap
[root@public test]# kubectl delete configmap nginx-php-config -n dev [root@public test]#kubectl create configmap nginx-php-config --from-file=./default.conf -n devcon [root@public test]# kubectl get configmap nginx-php-config -n dev -o yaml apiVersion: v1 data: #配置文件名改为default.conf default.conf: |+ server{ listen 80; charset utf-8; proxy_connect_timeout 5; proxy_read_timeout 10; proxy_send_timeout 15; fastcgi_connect_timeout 5; fastcgi_read_timeout 10; fastcgi_send_timeout 15; fastcgi_buffers 2 256k; fastcgi_buffer_size 128k; ……… #这里只展示一些重要配置
因为是subpath,不会更新configmap(后面会说明),所以需要重新deployment发布后查看pod是否正常。
3.总结
1.若需要挂载单个文件,configmap的文件名需要与目标挂载名保持一致
2.容器以subPath卷挂载方式使用ConfigMap时,将无法接收ConfigMap的更新。需要重新发布。
3.不建议在线上环境使用单独挂载文件方式