K8s 部署 Lxcfs 准入控制器,实现容器中资源单独可见
文章目录
环境说明
- kubernetes version: v1.17.9 (
kubeadm
) - os: 7.8.2003 (Core)
- kubernetes dashboard: rancher
v2.4.15
概述
docker 使用 linux 内核中的
cgroup
实现了对 容器使用资源的限制,默认容器启动后依旧挂载了宿主机的/proc
目录,其中包涵了,meminfo
、cpuinfo
、stat
、uptime
等资源信息。一些监控工具如free
、top
、htop
或业务应用
还依赖/proc
下文件内容获取资源配置和使用情况。当它们在容器中运行时,实际还是查看到的是宿主机的资源使用,导致资源使用展示源不对,目前社区主流的解决方法是使用lxcfs
的方法进行解决。
lxcfs
lxcfs 是一个开源的 fuse(用户态文件系统)最先实现来支持 lxc 容器,但是它也可以支持 Docker 容器。lxcfs 通过用户态文件系统,在容器中提供下列 procfs 的文件。
1 2 3 4 5 6
/proc/cpuinfo /proc/diskstats /proc/meminfo /proc/stat /proc/swaps /proc/uptime
lxcfs 使用示意图
比如,将宿主机的
/var/lib/lxcfs/proc/memoinfo
文件挂载到 docker 容器中对应的/proc/meminfo
位置后。容器中的进程读取相应文件内容时,lxcfs
的fuse
实现会从容器对应的cgroup
中读取正确的内存限制。从而使得应用获得正确的资源使用情况。
admission webhook
在 Kubernetes apiserver 中包含两个特殊的准入控制器:
MutatingAdmissionWebhook
和ValidatingAdmissionWebhook
,这两个控制器将发送准入请求到外部的 HTTP 回调服务并接收一个准入响应。如果启用了这两个准入控制器,kubernetes 管理员可以在集群中创建和配置一个 admission webhook。
- 检查集群中是否启用了 admission webhook 控制器,并根据需要进行配置。
- 编写处理准入请求的 HTTP 回调,回调可以是一个部署在集群中的简单 HTTP 服务,甚至也可以是一个
serverless
函数,例如 https://github.com/kelseyhightower/denyenv-validating-admission-webhook 这个项目。- 通过
MutatingWebhookConfiguration
和ValidatingWebhookConfiguration
资源配置 admission webhook
这两种 admission webhook 之间的区别是明显的:validating webhooks
可以拒绝请求,但是它们却不能修改准入请求中获取的对象,而 mutating webhooks
可以在返回准入响应之前通过创建补丁来修改对象,如果 webhook 拒绝了一个请求,则会向最终用户返回错误
lxcfs 在 Kubernetes 中实践部署
下面将示例使用 lxcfs-admission-webhook,部署
admission webhook
给 pod 注入 lxcfs 。
各节点
安装依赖
注意这里是,所有节点多需要安装一下,否则节点会提示动态库缺失。
|
|
kubernetes 开启准入控制器
我这里使用的是 kubeadm 搭建的集群,可以通过下面命令查看 apiserver pod 的配置
|
|
上面的
enable-admission-plugins
参数中带上了MutatingAdmissionWebhook
和ValidatingAdmissionWebhook
两个准入控制插件,如果没有的(在 v1.19.x 版本中是默认开启的),需要添加上这两个参数,然后重启 apiserver。
kubeadm 演示如何为 apiserver 添加参数,和重启 apiserver
使用 kubeadm 部署的集群的话,apiserver 使用的部署方式为
静态pod
,即我们只要更改对应机器上的/etc/kubernetes/manifests/kube-apiserver.yaml
文件即可,当 kubelet watch 到配置文件更改后,它将会为我们进行重启生效。
|
|
查看集群是否开启了 准入控制 api
|
|
部署 lxcfs
- git clone 代码
|
|
- 部署 lxcfs 资源清单
|
|
-
更改一下
deployment/install.sh
中部署的命名空间,默认使用的是default
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
sed -i "s#default#lxcfs#g" deployment/mutatingwebhook.yaml # 替换默认模板文件中的命名空间 cat deployment/install.sh #!/bin/bash ./deployment/webhook-create-signed-cert.sh --namespace lxcfs kubectl get secret lxcfs-admission-webhook-certs -n lxcfs kubectl create -f deployment/deployment.yaml -n lxcfs kubectl create -f deployment/service.yaml -n lxcfs cat ./deployment/mutatingwebhook.yaml | ./deployment/webhook-patch-ca-bundle.sh > ./deployment/mutatingwebhook-ca-bundle.yaml kubectl create -f deployment/mutatingwebhook-ca-bundle.yaml -n lxcfs bash deployment/install.sh # 执行部署
测试
这里将部署一个 python 程序,进行模拟测试
- 为命名空间注入 lxcfs
|
|
- 创建测试资源清单
|
|
- 检查资源限制是否生效
|
|
可以看到上面的资源清单,是更具
limits
设置来。展示输出的。
问题记录
-
卸载
1 2 3 4 5 6 7 8 9 10 11 12 13 14
kubectl delete -f deployment/lxcfs-daemonset.yaml -n lxcfs cat deployment/uninstall.sh #!/bin/bash # 对脚本中指定了命名空间卸载 kubectl delete -f deployment/mutatingwebhook-ca-bundle.yaml -n lxcfs kubectl delete -f deployment/service.yaml -n lxcfs kubectl delete -f deployment/deployment.yaml -n lxcfs kubectl delete secret lxcfs-admission-webhook-certs -n lxcfs deployment/uninstall.sh # 执行卸载脚本 rm -rf /var/lib/lxcfs/ # 删除宿主机目录,如无法删除时,请尝试重启一下节点。
-
lxcfs 不支持 使用了
alpine
作为基础镜像的容器。
参考文档
- https://cloud.tencent.com/developer/article/1645542
- https://github.com/denverdino/lxcfs-admission-webhook
- https://www.qikqiak.com/k8strain2/security/admission/
- https://github.com/lxc/lxcfs