Linux利用CGroup实现了对容器资源的限制,但是在容器内部还是默认挂载宿主机 /proc 目录下的资源信息文件,如:meminfo,cpuinfo,stat,uptiem等。当进入Containers执行free,df,top等命令的时候,这时候默认读取的是 /proc 目录内的资源信息文件内容,而这些资源信息文件使用的是宿主机的,所以我们看到的是宿主机的使用信息。
LXCFS简介
LXCFS是一个开源的FUSE(用户态文件系统),用来支持LXC容器,也支持Docker容器,社区中常用此工具来实现容器中的资源可见性。
LXCFS原理
以内存资源为列:通过将宿主机的 /var/lib/lxcfs/meminfo 文件挂载到容器内的/proc/meminfo,然后LXCFS会从容器的CGroup中读取正确的内存限制,然后应用到 /var/lib/lxcfs/meminfo ,这时候容器内部从而就得到了正确的内存信息。
说明:/var/lib/lxcfs/meminfo 是服务启动的时候默认指定的目录
具体使用方法
安装LXCFS
wget https://copr-be.cloud.fedoraproject.org/results/ganto/lxd/epel-7-x86_64/00486278-lxcfs/lxcfs-2.0.5-3.el7.centos.x86_64.rpm
yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm
启动LXCFS
systemctl start lxcfs
systemctl enable lxcfs
启动一个容器测试
docker run -it -m 256m --cpuset-cpus "0,1,2" \
-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \
-v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \
-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
-v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
ubuntu:16.04 /bin/bash
说明:-m 选项用来限制内存,--cpuset-cpus 选项用来限制使用使用CPU的核数,并指定 0,1,2,三核。
查看内存
root@32f05068ffa3:/# free -m
total used free shared buff/cache available
Mem: 256 6 249 23 0 249
Swap: 256 0 256
查看CPUs,实际宿主机为8核
root@32f05068ffa3:/# top
top - 09:52:34 up 0 min, 0 users, load average: 0.21, 0.70, 0.86
Tasks: 2 total, 1 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu0 : 1.7 us, 0.7 sy, 0.0 ni, 97.3 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
%Cpu1 : 0.7 us, 0.7 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 3.7 us, 0.7 sy, 0.0 ni, 95.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 262144 total, 255112 free, 7032 used, 0 buff/cache
KiB Swap: 262144 total, 262144 free, 0 used. 255112 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 18224 1976 1508 S 0.0 0.8 0:00.04 bash
13 root 20 0 36648 1704 1252 R 0.0 0.7 0:00.00 top
基于Kubernetes实战
克隆LXCFS基于Kubernetes项目到本地
git clone https://github.com/denverdino/lxcfs-initializer
部署LXCFS到每个节点
在些命令的前面需要每个节点先安装LXCFS,不需要启动
kubectl apply -f lxcfs-initializer/lxcfs-daemonset.yaml
开启Kubernetes对Initializer扩展机制的支持,如果使用的是阿里云Kubernetes默认已支持
查看是否支持
kubectl api-versions | grep admission.*v1alpha1
在启动kube-apiserver的时候增加下面两个参数,让其支持,如果是kubeadm部署,修改 /etc/kubernetes/manifests/kube-apiserver.yaml 此文件应用即可
--enable-admission-plugins=NodeRestriction,Initializers
--runtime-config=admissionregistration.k8s.io/v1alpha1=true
备注:在apply的时候有可能会会报“connection refused”,这时候kubectl无法与kube-apiserver通讯,只需要手动 telnet 下对应的 IP:PORT 即可。只是在本人自己环境出现这样的情况,各位视情况而定,执行成功后再次查看是否支持
部署Initializer扩展机制,用于自动的完成对LXCFS文件的自动挂载
kubectl apply -f lxcfs-initializer/lxcfs-initializer.yaml
确保所有程序已运行
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
lxcfs-2ppnp 1/1 Running 4 3m7s
lxcfs-bm4t6 1/1 Running 4 3m7s
lxcfs-initializer-769d7fb857-bhgbv 1/1 Running 0 11s
lxcfs-pmmj8 1/1 Running 0 3m7s
测试,通过添加 initializer.kubernetes.io/lxcfs: true 就会自动的挂载相对应的文件
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
"initializer.kubernetes.io/lxcfs": "true"
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: centos
imagePullPolicy: Always
command:
- "/bin/bash"
- "-c"
- "while true;do echo `date` && sleep 3;done"
resources:
requests:
memory: "512Mi"
limits:
memory: "1024Mi"
验证
$ kubectl exec -ti web-65dd5b55f-6ngp8 -- free -m
total used free shared buff/cache available
Mem: 1024 0 1022 17 0 1022
参考资料
https://www.lijiaocn.com/%E6%8A%80%E5%B7%A7/2019/01/09/kubernetes-lxcfs-docker-container.html
https://yq.aliyun.com/articles/566208/
转载于:https://blog.51cto.com/270142877/2363725