【问题标题】:How to correctly use subdirs with projected volumes and configMaps如何正确使用具有预计卷和 configMaps 的子目录
【发布时间】:2020-11-22 01:10:55
【问题描述】:

我有一个使用 docker swarm 部署的 nginx Web 服务器,我希望也能够使用 kubernetes 部署它。

现在我无法将 nginx 配置文件插入到容器中。

我将首先在这里发布我在 docker swarm 中已经做过的事情,然后是我在 kubernetes 中尝试过的事情。

Dockerfile:

FROM    "nginx:1.19.1-alpine"   AS nginx
[...]
RUN                                                             \
        rm -fv  /etc/nginx/nginx.conf                           && \
        ln -svT /usr/local/etc/nginx/nginx.conf                 \
                /etc/nginx/nginx.conf                           && \
        rm -frv /etc/nginx/conf.d                               && \
        ln -svT /usr/local/etc/nginx/conf.d                     \
                /etc/nginx/conf.d
[...]

基本上我设置了映像,以便我可以将自定义 nginx 配置文件放入 /usr/local/etc/ 而不是 /etc/

Docker 群:

docker-compose.yaml:

configs:
    nginx_conf:
        file: /run/configs/www/etc/nginx/nginx.conf
    nginx_conf_security-parameters:
        file: /run/configs/www/etc/nginx/conf.d/security-parameters.conf
    nginx_conf_server:
        file: /run/configs/www/etc/nginx/conf.d/server.conf

networks:
    alejandro-colomar:

services:
    www:
        configs:
        -
            mode: 0440
            source: nginx_conf
            target: /usr/local/etc/nginx/nginx.conf
        -
            mode: 0440
            source: nginx_conf_security-parameters
            target: /usr/local/etc/nginx/conf.d/security-parameters.conf
        -
            mode: 0440
            source: nginx_conf_server
            target: /usr/local/etc/nginx/conf.d/server.conf
        deploy:
            placement:
                constraints:
                -   node.role == worker
            replicas: 1
            restart_policy:
                condition: any
        image: "alejandrocolomar/www:0.16-a6-kube"
        networks:
        -
            "alejandro-colomar"
        ports:
        -   "32001:8080"

version: "3.8"

在这里,我使用 nginx 自定义配置文件,我首先将它们放入 /run/configs/ 和脚本中,以便它们在 ram 中,并将它们作为配置引入容器中的正确位置(/usr/local/etc/nginx/ 及其子目录 @ 987654329@)。

我想在 kubernetes 中做同样的事情,我读到我应该为此使用预计的卷(如果它适用于普通卷或以其他方式,而不必使用任何肮脏的解决方法,我也对此持开放态度),所以我尝试了以下方法(在看到一些我不太清楚的例子之后):

config.sh:


kubectl create configmap "nginx-conf-cm"                        \
        --from-file "/run/configs/www/etc/nginx/nginx.conf"
kubectl create configmap "nginx-conf-security-parameters-cm"    \
        --from-file "/run/configs/www/etc/nginx/conf.d/security-parameters.conf"
kubectl create configmap "nginx-conf-server-cm"                 \
        --from-file "/run/configs/www/etc/nginx/conf.d/server.conf"

deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
    name: www-deploy
spec:
    replicas: 1
    selector:
        matchLabels:
            service: www-svc
    template:
        metadata:
            labels:
                service: www-svc
        spec:
            containers:
            -
                image: "alejandrocolomar/www:0.16-a6-kube"
                name: www-container
                volumeMounts:
                -
                    mountPath: /usr/local/etc/nginx/
                    name: nginx-volume
                    readOnly: true
            volumes:
            -
                name: nginx-volume
                projected:
                    sources:
                    -
                        configMap:
                            name: nginx-conf-cm
                            path: "nginx.conf"
                    -
                        configMap:
                            name: nginx-conf-security-parameters-cm
                            path: "conf.d/security-parameters.conf"
                    -
                        configMap:
                            name: nginx-conf-server-cm
                            path: "conf.d/server.conf"

service.yaml:(这个我放在这里只是为了完整)

apiVersion: v1
kind: Service
metadata:
    name: www
spec:
    ports:
    -
        nodePort: 32001
        port: 8080
    selector:
        service: www-svc
    type: NodePort

部署当然失败了,但我认为这并没有错。当我进入容器调试时,问题是这三个文件都放到/usr/local/etc/nginx/中,而子目录conf.d/没有创建:

/usr/local/etc/nginx/nginx.conf
/usr/local/etc/nginx/security-parameters.conf
/usr/local/etc/nginx/server.conf

我应该如何解决这个问题(大概在deployment.yaml),以便我在容器中有以下文件?:

/usr/local/etc/nginx/nginx.conf
/usr/local/etc/nginx/conf.d/security-parameters.conf
/usr/local/etc/nginx/conf.d/server.conf

【问题讨论】:

    标签: docker kubernetes subdirectory docker-volume


    【解决方案1】:

    有多种方法可以处理此问题。一种解决方案是从这些单独的配置映射中创建 3 个单独的卷,并将每个卷安装到相应的目标文件/文件夹中。

    volumes:
            - name: nginx-cm
              configMap:
                  name: nginx-conf-cm
            - name: nginx-sec
              configMap:
                  name: nginx-conf-security-parameters-cm
            - name: nginx-serv
              configMap:
                  name: nginx-conf-server-cm
    
            ...
            containers:
                -
                    image: "alejandrocolomar/www:0.16-a6-kube"
                    name: www-container
                    volumeMounts:
                    -   mountPath: /usr/local/etc/nginx/nginx.conf
                        name: nginx-cm
                        subPath: nginx.conf
                        readOnly: true
                    -   mountPath: /usr/local/etc/nginx/conf.d/security-parameters.conf
                        name: nginx-sec
                        subPath: security-parameters.conf
                        readOnly: true
                    -   mountPath: /usr/local/etc/nginx/conf.d/server.conf
                        name: nginx-serv
                        subPath: server.conf
                        readOnly: true
    
    

    volumeMounts 中使用mountPathsubPath 允许您从给定的配置映射中选择特定文件(无关紧要,因为您每厘米都有一个文件)并将其挂载为文件(不覆盖现有文件夹中的其他内容)。

    解释一下上面的代码:

    -   mountPath: /usr/local/etc/nginx/nginx.conf
        name: nginx-cm
        subPath: nginx.conf
    

    告诉 kubernetes 使用带有 namenignx-cm 的卷(在卷部分中定义)。选择可以在相关配置映射中找到的文件nginx.conf(通过subpath)并将其公开在容器(mountPath)的位置/usr/local/etc/nginx/nginx.conf

    我没有运行代码,所以可能有错别字

    PS:请注意,最好在../etc/nginx/conf.d/ 内创建自定义配置文件,而不是覆盖../etc/nginx/nginx.conf。这样您就不必担心破坏原始文件 ../etc/nginx/ 并且可以挂载整个卷而不是使用 subpath(以避免配置更新问题)

    【讨论】:

    • 哦,那真是太好了!!我不知道可以在不覆盖现有文件夹内容的情况下使用卷。这就是我尝试使用预计数量的原因。所以我不再需要预计的数量了(还)! :)
    • 遗憾的是,我确实需要编写我的自定义 nginx.conf。原因是其中有一行 (keepalive_timeout 65;) 我想用 keepalive_timeout 10s 10s; 替换它。而且我没有找到不涉及替换文件的解决方案。
    • 不,如果您不担心覆盖现有文件,则不需要子路径。是的,您可以将一个卷挂载为另一个已挂载卷的子目录。这个问题有很多不同的解决方案。
    • 关于子路径的另一件事是,您的配置映射可能包含针对不同容器的许多不同配置,您可能不想将一个配置映射中的所有文件挂载到所有这些挂载点。子路径允许您从 configmap 中挑选出哪些确切的文件将被复制到哪个位置。
    • 顺便说一句,我相信您也可以在 serverlocation 上下文中覆盖默认的 keep_alive
    猜你喜欢
    • 2018-05-11
    • 2018-08-02
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 2012-04-26
    • 1970-01-01
    相关资源
    最近更新 更多