kubernetes-lxcfs解决资源可见性问题
一. 背景:
在默认的 Docker 或 Kubernetes 环境中,当一个进程运行在容器里时,它通过 /proc
文件系统看到的系统资源(如 CPU 数量、内存总量、内存使用量、交换空间等)是宿主机的资源视图,而不是该容器被限制的资源量。举个例子: 假如你有一个k8s集群,所有node节点配置都是32C128G的, 然后部署了一个pod,它的内存限制 limits.memory
被设置为 1G。当进入这个容器内部,执行 free -h
或 top
命令时,你看到的内存将是宿主机的内存128G,而不是1G。同样,执行 nproc
或查看 /proc/cpuinfo
,看到的也是宿主机的总 CPU 核心数,而不是该容器被限制的 CPU 份额(如 1C)。
导致的问题:
应用程序配置错误:比如基于 JVM 的(如 Java, Scala),会在启动时根据系统的总内存来自动分配堆大小。一个本来只想用 256M 内存的 Java 程序,如果它看到主机有 16G 内存,可能会尝试分配 4G 的堆内存,最终很快就会被 Kubernetes 的 OOMKiller(内存溢出杀手)杀死。
监控工具失效:容器内传统的监控命令(
top
,free
,htop
)变得无意义,因为它们无法反映容器真实的资源使用和限制情况。用户困惑:开发者或运维人员无法在容器内直观地了解当前容器的资源配额和使用情况。
二. 解决方法:
通过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: lxcfstemplate:metadata:labels:app: lxcfsspec:hostPID: truetolerations:- key: node-role.kubernetes.io/mastereffect: NoSchedulecontainers:- name: lxcfsimage: registry.cn-hangzhou.aliyuncs.com/denverdino/lxcfsimagePullPolicy: IfNotPresentsecurityContext:privileged: truevolumeMounts:- name: cgroupmountPath: /sys/fs/cgroup- name: lxcfsmountPath: /var/lib/lxcfsmountPropagation: Bidirectional- name: usr-localmountPath: /usr/localvolumes:- name: cgrouphostPath:path: /sys/fs/cgroup- name: usr-localhostPath:path: /usr/local- name: lxcfshostPath:path: /var/lib/lxcfstype: 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: nginxreplicas: 1template:metadata:labels:app: nginx4spec:containers:- name: nginx4image: nginxports:- containerPort: 80resources:limits:cpu: 100mmemory: 100Mirequests:cpu: 100mmemory: 100Mi
进入pod查看:
- --------------------------------------------------------------------------------------------------------------------------
深耕运维行业多年,擅长运维体系建设,方案落地。欢迎交流!
“V-x”: ywjw996
《 运维经纬 》