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.不建议在线上环境使用单独挂载文件方式

作者:小家电维修

相见有时,后会无期。

原文地址:https://www.cnblogs.com/lizexiong/p/14990537.html