使用LXCFS实现容器资源的视图隔离

01

问题背景

大家都知道,当我们使用 top 等命令的时候,背后的逻辑是读取 /proc 目录下相应的资源文件。本篇文章就通过查看使用 top所执行的系统调用,来窥探一二。

strace  top -b -n 1

bc4455d72655961a86c06dfcf3ef79b1.png

事实上在容器环境下,/proc 文件系统使用的是宿主机的信息,这会导致一系列的问题:

  • 从容器的视角来看,通常有一些业务开发者已经习惯了在传统的物理机,虚拟机上使用 top, free 等命令来查看系统的资源使用情况,但是容器还没有做到资源视图隔离,那么在容器里面看到的数据还是物理机的数据。

  • 从应用程序的视角来看,在容器里面运行进程,与在物理机或虚拟机上运行进程的运行环境是不同的。并且部分应用在容器里面运行进程时,还会存在一些安全隐患,例如:

(1)对于很多基于 JVM 的 java 程序,应用启动时会根据系统的资源上限来分配 JVM 的堆和栈的大小。而在容器里面运行 JAVA 应用时,由于 JVM 获取的内存数据还是物理机的数据,而容器分配的资源配额又小于 JVM 启动时需要的资源大小,就会导致程序启动失败。

(2)对于需要获取 host cpu info 的程序,例如golang 服务端,在开发时需要获取 golang 中runtime.GOMAXPROCS(runtime.NumCPU()) ,又或者是运维人员在设置服务启动进程数量时(例如nginx 配置中的 worker_processes auto ),都习惯通过程序自动判断所在运行环境 CPU 的数量。但是在容器内的进程,总会从 /proc/cpuinfo 中获取到 CPU 的核数,而容器里面的/proc 文件系统还是宿主机的,因此会影响到运行在容器里面服务的运行状态。

那么这种情况下,我们需要如何去解决呢?就需要请出我们今天的主角 lxcfs。

02

什么是LXCFS

官网定义

LXCFS is a small FUSE filesystem written with the intention of making Linux containers feel more like a virtual machine. It started as a side-project of LXC but is useable by any runtime.

通俗来说 LXCFS 是一个开源的 FUSE(用户态文件系统), 它可以让容器内的应用在读取内存和 CPU 信息的时候通过 LXCFS 的映射,转到自己的通过对 cgroup 中容器相关定义信息读取的虚拟数据上。


03

LXCFS 原理

lxcfs 实现的基本原理是通过文件挂载的方式,把 cgroup 中容器相关的信息读取出来,存储到 lxcfs 相关的目录下,并将相关目录映射到容器内的 /proc 目录下,从而使得容器内执行 top , free 等命令时拿到的/proc 下的数据是真实的cgroup 分配给容器的CPU和内存数据。


04

使用方式

4.1编译安装

尝试在本地安装LXCFS,如下

yum -y fuse-devel
wget https://linuxcontainers.org/downloads/lxcfs/lxcfs-$LXCFS.tar.gz && \
mkdir /lxcfs && tar xzvf lxcfs-$LXCFS.tar.gz -C /lxcfs  --strip-components=1 && \
cd /lxcfs && ./configure && make install
lxcfs -h


4.2使用

将其挂载到/var/lib/lxcfs,

lxcfs /var/lib/lxcfs

同时启动一个容器,用 LXCFS 维护的 /proc 文件替换容器中的 /proc 文件,容器内存设置为256M。

docker run -it -m 256m \
      -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:ro \
      -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:ro \
      -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:ro \
      -v /var/lib/lxcfs/proc/stat:/proc/stat:ro \
      -v /var/lib/lxcfs/proc/swaps:/proc/swaps:ro \
      -v /var/lib/lxcfs/proc/uptime:/proc/uptime:ro \
      ubuntu:latest /bin/bash

在容器内看到内存大小是256M,

# free -h
              total        used        free      shared  buff/cache   available
Mem:           256M        1.2M        254M        6.1M        312K        254M
Swap:          256M          0B        256M

容器的CPU设置有两种方式,一个是--cpus 2,限定容器最多只能使用两个逻辑 CPU,另一个是--cpuset-cpus "0,1" ,限定容器 可以使用的宿主机CPU 。

top 命令显示的是容器可以使用的宿主机CPU,如果使用 --cpus 2,看到的CPU 个数是宿主机上的CPU个数。使用 --cpuset-cpus "0,1" 的时候,在容器看到的CPU个数是 --cpuset 指定的 CPU 的个数。

docker run -it --rm -m 256m  --cpus 2 --cpuset-cpus "0,1" \
      -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:ro \
      -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:ro \
      -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:ro \
      -v /var/lib/lxcfs/proc/stat:/proc/stat:ro \
      -v /var/lib/lxcfs/proc/swaps:/proc/swaps:ro \
      -v /var/lib/lxcfs/proc/uptime:/proc/uptime:ro \
      ubuntu:latest /bin/sh

这时候在容器内看到的 CPU 个数是2个,

top - 07:30:32 up 0 min,  0 users,  load average: 0.03, 0.09, 0.13
Tasks:   2 total,   1 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.6 us,  0.6 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.6 us,  0.0 sy,  0.0 ni, 99.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

4.3在Kubernetes中使用LXCFS

下面使用 lxcfs-on-kubernetes 项目来一键安装。首先,需要安装好 helm, 这是一个能管理 Kubernetes 应用程序。

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

其次,在Kubernetes中部署 cert-manager。

kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.4.0/cert-manager.yaml

接下来安装lxcfs-on-kubernetes,

helm repo add lxcfs-on-kubernetes https://cndoit18.github.io/lxcfs-on-kubernetes/
helm upgrade --install lxcfs lxcfs-on-kubernetes/lxcfs-on-kubernetes -n lxcfs --create-namespace

同时我们将default命名空间打上 mount-lxcfs=enabled,那么之后创建的 Pod 都会自动挂载上 LXCFS。

kubectl label namespace default mount-lxcfs=enabled

大功告成,接下来,就可以在default命名空间创建自己的 Pod , 检查资源视图是否完成更改。

参考链接:

  • https://www.huweihuang.com/kubernetes-notes/resource/lxcfs/lxcfs.html

  • https://github.com/cndoit18/lxcfs-on-kubernetes

  • https://juejin.cn/post/6847902216511356936

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值