前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >k8s subPathExpr stat no such file or directory 及挂载后找不到文件的问题

k8s subPathExpr stat no such file or directory 及挂载后找不到文件的问题

作者头像
饶文津
发布于 2022-05-11 02:22:56
发布于 2022-05-11 02:22:56
1.7K00
代码可运行
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏
运行总次数:0
代码可运行

在 k8s 集群、云基础架构或是网络设备上我们常常需要用 fluent bit、fluentd 之类的工具来收集日志。其中一种架构是将收集日志的 agent 运行在宿主机上,我们自己的服务写日志,agent 收集日志转发到 elastic search 之类的处理后端上。

如果 agent 和我们自己的服务都是以 pod 的形式运行在 k8s 集群上,我们就需要让他们一个读一个写同一个文件,就都需要挂载同一个目录。而当我们有多个 pod 可能有相同的日志路径时,我们就要保证能区别出不同的 pod 的日志。

挂载时映射到不同路径

一种方法是直接写日志时,写到包含 PODNAME宿POD_NAME 的目录下,于是就考虑 SubPathExpr,这个是 Kubernetes 1.17 后有的功能。

大概的用法如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: apps/v1
kind: Deployment
...
spec:
    spec:
      containers:
      - name: asr
        ...
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        volumeMounts:
          - name: log
            mountPath: /log
            subPathExpr: $(POD_NAME)
      volumes:
        - name: log
          hostPath:
            path: /tmp/log

然而执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
kubectl apply -f deployment.yaml

后,并没有成功运行起来,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
kubectl describe pod my-pod-xxx -n mynamespace

发现报错

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Error: stat /tmp/log: no such file or directory

非常地不解,也只好先加上 type:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
      volumes:
        - name: log
          hostPath:
            path: /tmp/log
            type: DirectoryOrCreate

这下是运行起来了,但是本地怎么就不见 /tmp/log 里有新的文件夹呢?

容器里执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mount | grep "/tmp/log"

得到

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
overlay on /tmp/log type overlay (rw,relatime,lowerdir=/data00/docker/lib/overlay2/l/CCC:....省略...:/data00/docker/lib/overlay2/l/NNN,upperdir=/data00/docker/lib/overlay2/eee/diff,workdir=/data00/docker/lib/overlay2/eee/work)

而其它 hostPath 挂载的长这样

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/dev/vda1 on /opt/tmp/xxx type ext4 (rw,relatime,errors=remount-ro,data=ordered)

后来找到了这个 issue:

https://github.com/kubernetes/kubernetes/issues/61456

(实际上先搜到的是一个翻译文 ddeevv.com/question/kubernetes-kubernetes-61456.html

原来是因为早期 k8s 不会对 subPath 做检查,于是就存在一个漏洞,用户可以搞一个软链接,让容器可以访问任何宿主机上的目录,后来修复了这个漏洞 https://kubernetes.io/blog/2018/04/04/fixing-subpath-volume-vulnerability/,

就导致容器方式(containerized)运行的 kubelet,用 subPath (或 subPathExpr)后创建的目录就跑到 kubelet 的容器里了。

那要怎么办呢,如果 kubelet 是你自己部署的,那可以把 hostPath 对应的路径给挂载到 kubelet 的容器里,不然就没办法了

其实还有办法,就是不用 subPath(subPathExpr 同),而是搞个 initContainer 来创建目录。

修改写日志的路径

或者绕过去,修改写日志的路径,由于我们有多个日志要写,统一用配置文件来配置这些日志写的路径,所以就可以搞一个 configmap 来存配置文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
kind: ConfigMap
apiVersion: v1
metadata:
  name: log-config
  namespace: development
data:
  log.conf: >+
    xxxxxx
    xxxxxx.File=/log/${POD_NAME}/xxxx.log
    xxxxxx

然后

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
kubectl apply -f configmap.yml

还要编辑 deployment:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
          - name: log
            mountPath: /log/
            # subPathExpr: $(POD_NAME)
          - name: log-config
            mountPath: /conf
            readOnly: true
      volumes:
        - name: log
          hostPath:
            path: /my/log
        - name: log-config
          configMap:
            name: log-config

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
kubectl apply -f development.yml
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Kubernetes 存储概念之Volumes介绍
默认情况下容器中的磁盘文件是非持久化的,对于运行在容器中的应用来说面临两个问题,第一:当容器挂掉,K8S重启它时,文件将会丢失;第二:当Pod中同时运行多个容器,容器之间需要共享文件时。Kubernetes的Volume解决了这两个问题
授客
2022/05/06
2.2K0
在K8S Volume中使用 subPath
有时,在单个 Pod 中共享卷以供多方使用是很有用的。volumeMounts.subPath 属性可用于指定所引用的卷内的子路径,而不是其根路径。
东风微鸣
2022/04/21
1.9K0
在K8S Volume中使用 subPath
k8s之存储篇---数据卷-挂载
挂载是指将定义在 Pod 中的数据卷关联到容器,同一个 Pod 中的同一个数据卷可以被挂载到该 Pod 中的多个容器上。
linus_lin
2024/09/06
2130
k8s之存储篇---数据卷-挂载
k8s配置管理
https://kubernetes.io/zh-cn/docs/concepts/configuration/configmap/
张哥编程
2024/12/07
960
k8s配置管理
k8s的数据存储
● 在前面已经提到,容器的生命周期可能很短,会被频繁的创建和销毁。那么容器在销毁的时候,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器中的数据,kubernetes引入了Volume的概念。
大忽悠爱学习
2022/09/28
1.7K0
k8s的数据存储
Kubernetes-存储卷Volume
由于容器本身是非持久化的,因此需要解决在容器中运行应用程序遇到的一些问题。首先,当容器崩溃时,kubelet将重新启动容器,但是写入容器的文件将会丢失,容器将会以镜像的初始状态重新开始;第二,在通过一个Pod中一起运行的容器,通常需要共享容器之间一些文件。Kubernetes通过存储卷解决上述的两个问题。
菲宇
2019/06/12
5K1
Kubernetes K8S之通过yaml文件创建Pod与Pod常用字段详解
K8S 里所有的资源或者配置都可以用 yaml 或 Json 定义。YAML 是一个 JSON 的超集,任何有效的 JSON 文件也都是一个有效的YAML文件。
踏歌行
2020/10/15
4.3K0
kubesphere磁盘挂载小bug记录
容器中的磁盘文件随着容器的生而生,随着容器的死而灭,这给运行在容器中的重要应用来说存在一些问题:
小石头
2022/11/10
9160
kubesphere磁盘挂载小bug记录
Kubernetes | 存储 - Storage
ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制大对象。
Zkeq
2023/05/13
9250
Kubernetes | 存储 - Storage
K8S学习笔记之Kubernetes数据持久化方案
在开始介绍k8s持久化存储前,我们有必要了解一下k8s的emptydir和hostpath、configmap以及secret的机制和用途。
Jetpropelledsnake21
2019/03/22
1.9K0
K8S学习笔记之Kubernetes数据持久化方案
得物SRE K8s 故障诊断:从 CPU 高负载到挂载泄露根源揭示
现代软件部署中,容器技术已成为不可或缺的一环,在云计算和微服务架构中发挥着核心作用。随着容器化应用的普及,确保容器环境的可靠性成为了一个至关重要的任务。这就是容器SRE(Site Reliability Engineering,站点可靠性工程)的职责所在。容器SRE工程师不仅要保证系统的高可用性,还需要优化运行效率,确保系统在各种压力和突发情况下的韧性。
得物技术
2024/06/11
2740
得物SRE K8s 故障诊断:从 CPU 高负载到挂载泄露根源揭示
《后端学运维》- k8s之数据存储
k8s 的进程到这里我们已经完成了 Namespace、Pod、PodController 几种资源的使用方式,已经过大半了哦~这篇文章我们就继续来了解一下在k8s 中怎么进行数据存储!
蔡不菜丶
2021/06/29
8450
Kubernetes 之数据存储
在之前的博文中,我们已经知道了很多 K8S 中的组件了,包括资源控制器等。在资源控制器中,我们说到了 StatefulSet 这个控制器组件,其专门为了有状态服务而生的,而对应的存储要存放到哪里呢?
民工哥
2021/04/21
2.3K0
K8s——数据持久化
数据的持久化一直都是需要我们非常关心的问题,docker如此,K8s也不例外。在k8s中,有一个数据卷的概念。
小手冰凉
2020/09/11
2.2K0
k8s基础概念及术语
上一篇简单介绍了一下k8s是什么以及如何使用kubeadm快捷安装,今儿来聊一下k8s的几个基础概念及术语。k8s中的资源都可以使用yaml文件进行描述。(文章内容来源于《kubernetes权威指南 第四版》)
Liusy
2020/09/16
1.1K0
k8s基础概念及术语
k8s实践(9)--深入了解Pod
Pod是k8s系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,也是在k8s上运行容器化应用的资源对象,其他的资源对象都是用来支撑或者扩展Pod对象功能的,比如控制器对象是用来管控Pod对象的,Service或者Ingress资源对象是用来暴露Pod引用对象的,PersistentVolume资源对象是用来为Pod提供存储等等,k8s不会直接处理容器,而是Pod,Pod是由一个或者多个container组成的。
黄规速
2022/04/14
1.3K0
k8s实践(9)--深入了解Pod
ubuntu20.04升级k8s集群,etcd备份恢复,k8s集群使用
5.资源对象 rc/rs/deployment、 service、 volume、 emptyDir、 hostpath、 NFS
conanma
2022/03/17
1.5K0
k8s 学习(1)——CentOS 系统搭建 k8s 环境
最近准备系统地学习一下 k8s,所以第一件事就是搭建环境,本篇文章就来记录一下自己在 CentOS 系统上搭建 k8s 环境的经历。
Hopetree
2022/09/26
1.2K0
Kubernetes(k8s)-DaemonSet介绍
我们上一章介绍了Docker基本情况,目前在规模较大的容器集群基本都是Kubernetes,但是Kubernetes涉及的东西和概念确实是太多了,而且随着版本迭代功能在还增加,笔者有些功能也确实没用过,所以只能按照我自己的理解来讲解。
运维小路
2024/12/30
1590
Kubernetes(k8s)-DaemonSet介绍
Prometheus+Grafana+altermanager监控k8s并配置报警[通俗易懂]
通过daemonset部署可使每个节点都有一个Pod来采集数据,node-exporter.yaml 内容如下:
全栈程序员站长
2022/08/25
4.4K0
Prometheus+Grafana+altermanager监控k8s并配置报警[通俗易懂]
相关推荐
Kubernetes 存储概念之Volumes介绍
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档