kubernetes子路径subpath原理及使用场景

举报
可以交个朋友 发表于 2024/02/26 19:36:00 2024/02/26
【摘要】 subpath原理及使用场景介绍

定义

subPath是kubernetes中Pod资源volumeMounts字段的挂载选项。subPath所定义的路径,指的是卷(Volume)内的子路径,用于将卷内subPath所对应的目录或文件,挂载到容器的挂载点,卷内subPath不存在时自动创建。不指定此参数时,默认是将卷的根路径进行挂载。
image.png

作用

subpath的作用如下:

  • 避免覆盖。如果挂载路径是一个已存在的目录,则目录下的内容不会被覆盖。直接将configMap/Secret挂载在容器的路径,会覆盖掉容器路径下原有的文件,使用subpath选定configMap/Secret的指定的key-value挂载在容器中,则不会覆盖掉原目录下的其他文件

  • 文件隔离。pod中含有多个容器公用一个日志volume,不同容器日志路径挂载的到不同的子目录,而不是根路径(Subpath目录会在底层存储自动创建且权限为777,无需手动创建)

案例一:将nginx.conf作为configmap挂载到nginx容器

案例介绍

将配置文件nginx.conf以configmap文件的方式挂载到容器中。为了更通用,可以将使用主nginx.conf include 指定xx.conf方式,主nginx.conf作为一个configmap,具体server.conf对应一个configmap
configmap可以通过ENV环境变量和文件两种方式挂载到容器中,修改configmap后容器中对应的ENV环境变量不会更新;修改configmap后容器中对应的file会自动更新,如果以subpath方式挂载文件,文件内容不会自动更新
image.png

案例演示

  1. 创建configmap

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-config
      namespace: default
    data:
      nginx.conf: |+
        user  nginx;
        worker_processes  8;
        error_log  /var/log/nginx/error.log warn;
        pid        /var/run/nginx.pid;
        events {
            worker_connections  1024;
        }
        http {
            include       /etc/nginx/mime.types;
            default_type  application/octet-stream;
            log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                              '$status $body_bytes_sent "$http_referer" '
                              '"$http_user_agent" "$http_x_forwarded_for"';
            access_log  /var/log/nginx/access.log  main;
            sendfile        on;
            keepalive_timeout  65;
            #gzip  on;
            include /etc/nginx/conf.d/*.conf;
        }
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-server-config
      namespace: default
    data:
      server1.conf: |+
        server {
                listen       80;
                server_name  server1.com;
                location / {
                    root   /usr/share/nginx/html/;
                    index  index.html index.htm;
                }
                error_page   500 502 503 504  /50x.html;
                location = /50x.html {
                    root   html;
                }
            }
      server2.conf: |+
        server {
                listen       81;
                server_name  server2.com;
                location / {
                    root   /usr/share/nginx/html/;
                    index  index.html index.htm;
                }
                error_page   500 502 503 504  /50x.html;
                location = /50x.html {
                    root   html;
                }
            }
    
  2. 部署nginx业务使用对应的cm

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        version: v1
      name: test-reload
      namespace: default
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: test-reload
      template:
        metadata:
           labels:
            app: test-reload
        spec:
          containers:
          - image: nginx:latest
            imagePullPolicy: Always
            name: container-1
            volumeMounts:
            - mountPath: /etc/nginx/conf.d
              name: vol-168233491311961268
            - mountPath: /etc/nginx/nginx.conf
              name: vol-168249948123126427
              readOnly: true
              subPath: nginx.conf
          dnsPolicy: ClusterFirst
          imagePullSecrets:
          - name: default-secret
          restartPolicy: Always
          volumes:
          - configMap:
              defaultMode: 420
              name: nginx-server-config
            name: vol-168233491311961268
          - configMap:
              defaultMode: 420
              name: nginx-config
            name: vol-168249948123126427
    
  3. 查看容器内挂载路径
    image.png

  4. 在Pod所在节点上使用crictl inspect ${ContainerId}查看容器挂载信息
    image.png

案例二:用Pod名称做文件隔离

案例介绍

同一个工作负责下的多个Pod实例挂载同一个存储卷,同时读写卷内的文件会有冲突,为了使每个Pod实例互不影响,在Pod中加入initContainer容器负责在卷内根路径创建名为${POD_NAME}(变量值来源于yaml文件中的env字段)的目录,并将code和zone目录拷贝至该目录。同时通过subpathexpr字段将卷内的$(POD_NAME)/zone$(POD_NAME)/code分别挂载至容器内的/sfs/zone和/sfs/code目录
image.png

案例演示

  1. 创建工作负载test

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: test
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: test
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: test-new
        spec:
          volumes:
            - name: test-subpathexpr
              persistentVolumeClaim:
                claimName: test-subpathexpr
          initContainers:
            - name: container-2
              image: centos:latest
              command:
                - /bin/bash
              args:
                - '-c'
                - mkdir -p /sfs/${POD_NAME} && cp -R /sfs/zone /sfs/${POD_NAME}/ &&  cp -R /sfs/code /sfs/${POD_NAME}/
              env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.name
              resources: {}
              volumeMounts:
                - name: test-subpathexpr
                  mountPath: /sfs
          containers:
            - name: container-1
              image: centos:latest
              command:
                - /bin/bash
              args:
                - '-c'
                - /sfs/zone/start.sh
              env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.name
              volumeMounts:
                - name: test-subpathexpr
                  mountPath: /sfs/code
                  subPathExpr: $(POD_NAME)/code
                - name: test-subpathexpr
                  mountPath: /sfs/zone
                  subPathExpr: $(POD_NAME)/zone
    
  2. 在容器内查看挂载路径
    image.png

  3. 在云服务器上挂载sfs文件存储卷,查看卷内目录结构
    image.png

  4. 在容器内/sfs/zone目录下新建文件test,再次在云服务器上查看卷内目录结构
    image.png
    image.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。