kubernetes-lxcfs解决资源可见性问题

一. 背景:

在默认的 Docker 或 Kubernetes 环境中,当一个进程运行在容器里时,它通过 /proc 文件系统看到的系统资源(如 CPU 数量、内存总量、内存使用量、交换空间等)是宿主机的资源视图,而不是该容器被限制的资源量。举个例子: 假如你有一个k8s集群,所有node节点配置都是32C128G的, 然后部署了一个pod,它的内存限制 limits.memory 被设置为 1G。当进入这个容器内部,执行 free -htop 命令时,你看到的内存将是宿主机的内存128G,而不是1G。同样,执行 nproc 或查看 /proc/cpuinfo,看到的也是宿主机的总 CPU 核心数,而不是该容器被限制的 CPU 份额(如 1C)。

导致的问题:

  1. 应用程序配置错误:比如基于 JVM 的(如 Java, Scala),会在启动时根据系统的总内存来自动分配堆大小。一个本来只想用 256M 内存的 Java 程序,如果它看到主机有 16G 内存,可能会尝试分配 4G 的堆内存,最终很快就会被 Kubernetes 的 OOMKiller(内存溢出杀手)杀死。

  2. 监控工具失效:容器内传统的监控命令(top, free, htop)变得无意义,因为它们无法反映容器真实的资源使用和限制情况。

  3. 用户困惑:开发者或运维人员无法在容器内直观地了解当前容器的资源配额和使用情况。

二. 解决方法:

通过Kubernetes 中的 lxcfs工具解决资源可视化问题。

  1. 关于lxcfs: lxcfs是一个轻量级的用户态文件系统工具,主要用于解决容器内资源可见性问题,让容器内部看到的资源(如 CPU、内存)更贴近容器实际被分配的资源限额,而非宿主机的物理资源。

  2. 原理:在宿主机上部署 lxcfs服务,它会在宿主机创建虚拟的资源信息文件(如 /var/lib/lxcfs/proc/meminfo);当容器启动时,通过 volumemounts 将宿主机的 lxcfs 虚拟文件挂载到容器内的 /proc 路径(如 /proc/meminfo/proc/cpuinfo 等);容器内读取这些文件时,实际访问的是 LXCFS 提供的虚拟数据,数据值基于容器的 limits 动态计算。

三. 部署方式:

  1. 下载配置

    git clone https://github.com/denverdino/lxcfs-admission-webhook.git cd lxcfs-admission-webhook

  2. 配置deployment:

    #deployment/lxcfs-daemonset.yaml
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
    name: lxcfs
    #namespace: lxcfs #部署到单独的namespace(需要修改deployment目录下相关文件[kubectl过滤])
    labels:
    app: lxcfs
    spec:
    selector:
    matchLabels:
    app: lxcfs
    template:
    metadata:
    labels:
    app: lxcfs
    spec:
    hostPID: true
    tolerations:
    - key: node-role.kubernetes.io/master
    effect: NoSchedule
    containers:
    - name: lxcfs
    image: registry.cn-hangzhou.aliyuncs.com/denverdino/lxcfs
    imagePullPolicy: IfNotPresent
    securityContext:
    privileged: true
    volumeMounts:
    - name: cgroup
    mountPath: /sys/fs/cgroup
    - name: lxcfs
    mountPath: /var/lib/lxcfs
    mountPropagation: Bidirectional
    - name: usr-local
    mountPath: /usr/local
    volumes:
    - name: cgroup
    hostPath:
    path: /sys/fs/cgroup
    - name: usr-local
    hostPath:
    path: /usr/local
    - name: lxcfs
    hostPath:
    path: /var/lib/lxcfs
    type: DirectoryOrCreate

  3. 部署:

    kubectl apply -f deployment/lxcfs-daemonset.yaml kubectl get pods -n default | grep lxcfs

    #部署lxcfs-admission-webhook injector:
    $bash -x deployment/install.sh

    #启用需要注入lxcfs的namespace,命名空间下所有的pod都会被注入:
    $ kubectl label namespace test lxcfs-admission-webhook=enabled

四. 验证:

启动一个应用,登陆查看资源:

复制代码
$ cat nginx4.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx4
    spec:
      containers:
      - name: nginx4
        image: nginx
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 100m
            memory: 100Mi
          requests:
            cpu: 100m
            memory: 100Mi
复制代码

进入pod查看:


深耕运维行业多年,擅长运维体系建设,方案落地。欢迎交流!

"V-x": ywjw996

《 运维经纬 》

相关推荐
sszdzq3 小时前
docker 安装 doris
运维·docker·容器
海的透彻5 小时前
docker容器进程探究
运维·docker·容器
❀͜͡傀儡师6 小时前
ShadowBroker:实时全球情报地图,开源情报(OSINT)的终极聚合平台
docker·容器·llama
么卡6 小时前
我在 Debian 11 上把 K8s 单机搭起来了,过程没你想的那么顺(/opt 目录版)
kubernetes
AI攻城狮7 小时前
Adaptive Thinking 的代价:当 AI 自己决定"想多少"
人工智能·云原生·aigc
Dontla8 小时前
Kubernetes Liveness Probe存活探针 / Readiness Probe就绪探针介绍(Startup Probe启动探针)重启容器
云原生·容器·kubernetes
格林威8 小时前
工业相机 SDK 在 Docker 容器中的部署与权限配置(含 USB/GigE)
开发语言·人工智能·数码相机·计算机视觉·docker·容器·工业相机
AI攻城狮8 小时前
Vibe Coding 时代:为什么你不应该盲目启用 AI 编码插件
人工智能·云原生·aigc
Gofarlic_OMS10 小时前
Windchill的license合规使用报告自动化生成与审计追踪系统
大数据·运维·人工智能·云原生·自动化·云计算
cyber_两只龙宝10 小时前
【Oracle】Oracle之DQL中WHERE限制条件查询
linux·运维·数据库·云原生·oracle