ConfigMap挂载与Subpath在Nginx容器中的应用

本文分享自华为云社区《nginx.conf以configmap文件形式挂载到nginx容器中以及subpath使用场景》,作者:可以交个朋友。

背景

nginx.conf通过configmap文件形式挂载到容器内,可以更加方便的修改nginx.conf配置

方案简介

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

将nginx.conf作为configmap挂载到容器中

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

subpath拓展

subpath的作用如下:

  • 避免覆盖。如果挂载路径是一个已存在的目录,则目录下的内容不会被覆盖。直接将configMap/Secret挂载在容器的路径,会覆盖掉容器路径下原有的文件,使用subpath选定configMap/Secret的指定的key-value挂载在容器中,则不会覆盖掉原目录下的其他文件
  • 文件隔离。pod中含有多个容器公用一个日志volume,不同容器日志路径挂载的到不同的子目录,而不是根路径(Subpath目录会在底层存储自动创建且权限为777,无需手动创建)

避免覆盖效果演示

1.创建一个工作负载nginx,并用普通方式挂载configmap配置文件

复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  test-subpath.conf: |+
    test subpath;
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      volumes:
      - configMap:
          defaultMode: 420
          name: config
        name: vol-168249948123126427
      containers:
      - image: centos:latest
        name: centos
        command:
        - /bin/bash
        args:
        - -c
        - while true;do sleep 1 &&  echo hello;done
        volumeMounts:
        - mountPath: /tmp
          name: vol-168249948123126427

2.使用docker inspect ${容器id}命令查看容器挂载信息,挂载目标为tmp目录,tmp目录下原有内容被覆盖

复制代码
[root@test-746c64649c-pzztn /]# ls -l /tmp/
total 0
lrwxrwxrwx 1 root root 24 Feb 27 03:02 test-subpath.conf -> ..data/test-subpath.conf

3.创建一个工作负载nginx,并用subpath方式挂载configmap配置文件

复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  test-subpath.conf: |+
    test subpath;
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      volumes:
      - configMap:
          defaultMode: 420
          name: config
        name: vol-168249948123126427
      containers:
      - image: centos:latest
        name: centos
        command:
        - /bin/bash
        args:
        - -c
        - while true;do sleep 1 &&  echo hello;done
        volumeMounts:
        - mountPath: /tmp/test-subpath.conf
          name: vol-168249948123126427
          subPath: test-subpath.conf

4.使用docker inspect ${容器Id}命令查看容器挂载信息,挂载目标为test-subpath.conf文件,所以tmp目录下原来的文件不会被覆盖

复制代码
[root@test-7b64fd6bb-56lpp /]# ls -l /tmp/
total 12
-rwx------ 1 root root 701 Dec  4  2020 ks-script-esd4my7v
-rwx------ 1 root root 671 Dec  4  2020 ks-script-eusq_sc5
-rw-r--r-- 1 root root  14 Feb 27 03:07 test-subpath.conf

文件隔离演示

1.创建工作负载test,使用hostPath卷类型持久化日志文件

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test
spec:
  replicas: 2
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      volumes:
      - hostPath:
          path: /tmp/log   #该路径必须在节点上已存在
        name: vol-168249948123126427
      containers:
      - image: centos:latest
        name: centos
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        command:
        - /bin/bash
        args:
        - -c
        - while true;do echo $(POD_NAME) >> /tmp/log/app.log && sleep 900 ;done
        volumeMounts:
        - mountPath: /tmp/log
          name: vol-168249948123126427
          subPathExpr: $(POD_NAME)

2.两个Pod实例调度至同一个节点

复制代码
[root@test ~]# kubectl get pod -owide -l app=test
NAME                    READY   STATUS    RESTARTS   AGE   IP            NODE           NOMINATED NODE   READINESS GATES
test-69dfc665cd-2nhg5   1/1     Running   0          95s   172.16.4.59   172.16.2.172   <none>           <none>
test-69dfc665cd-z7rsj   1/1     Running   0          77s   172.16.4.25   172.16.2.172   <none>           <none>

3.进入容器内查看日志文件

复制代码
[root@test ~]# kubectl exec -it test-69dfc665cd-2nhg5 bash
[root@test-69dfc665cd-2nhg5 /]# cat /tmp/log/app.log 
test-69dfc665cd-2nhg5
[root@test-69dfc665cd-2nhg5 /]# exit
exit
[root@test ~]# kubectl exec -it test-69dfc665cd-z7rsj bash
[root@test-69dfc665cd-z7rsj /]# cat /tmp/log/app.log 
test-69dfc665cd-z7rsj

4.在节点上查看挂载路径,每个Pod的日志文件用目录进行隔离,目录名为Pod名称

复制代码
[root@172 log]# pwd
/tmp/log
[root@172 log]# ll
total 0
drwxr-xr-x 2 root root 60 Feb 27 15:08 test-69dfc665cd-2nhg5
drwxr-xr-x 2 root root 60 Feb 27 15:09 test-69dfc665cd-z7rsj
[root@172 log]# cat test-69dfc665cd-2nhg5/app.log 
test-69dfc665cd-2nhg5
[root@172 log]# cat test-69dfc665cd-z7rsj/app.log 
test-69dfc665cd-z7rsj

点击关注,第一时间了解华为云新鲜技术~

相关推荐
AC赳赳老秦3 分钟前
Kubernetes 与 DeepSeek:高效 Pod 部署配置与资源调度优化指南
人工智能·云原生·容器·kubernetes·自动化·notepad++·deepseek
阿方索1 小时前
Kubernetes Pod 管理
云原生·容器·kubernetes
哪里不会点哪里.1 小时前
Docker
运维·docker·容器
汪碧康1 小时前
一文掌握k8s的健康检查探针
云原生·容器·kubernetes·k8s·xkube·k8s管理平台
七七powerful1 小时前
docker 搭建wtsap代理
运维·docker·容器
Shanxun Liao2 小时前
Docker vlmcsd 完整管理指南
运维·docker·容器
有谁看见我的剑了?3 小时前
K8s crictl 客户端学习
学习·容器·kubernetes
KubeSphere 云原生3 小时前
云原生周刊:Kubernetes 1.35 新机制与云原生生态更新
云原生·容器·kubernetes
大房身镇、王师傅3 小时前
【Docker】RockyLinux10 安装 docker-compose
运维·docker·容器·docker-compose·rockylinux10
衫水5 小时前
Docker 常用指令大全(完整整合版)
运维·docker·容器