k8s的扩展资源设计和device-plugin
extended-resources
extended-resources在k8s1.9中是一个stable的特性。可以用一句话来概括这个特性:
通过向apiserver发送一个patch node 的请求,为这 个node增加一个自定义的资源类型,用于以该资源的配额统计和相应的QoS的配置。
patch node 的请求:
举例:
curl --header "Content-Type: application/json-patch+json" \ --request PATCH \ --data '[{"op": "add", "path": "/status/capacity/example.com~1dongle", "value": "4"}]' \ http://localhost:8001/api/v1/nodes/10.123.123.123/status
如上,我们为10.123.123.123这个node增加了一个resource:example.com/dongle (命令中的 ~1 会转化为 / ) ,这个node的capicity/allocable中会展示其有4个example.com/dongle资源:
"capacity": { "alpha.kubernetes.io/nvidia-gpu": "0", "cpu": "2", "memory": "2049008Ki", "example.com/dongle": "4",
如果我们要清除这个资源可以使用:
curl --header "Content-Type: application/json-patch+json" \ --request PATCH \ --data '[{"op": "remove", "path": "/status/capacity/example.com~1dongle"}]' \ http://localhost:8001/api/v1/nodes/<your-node-name>/status
QoS配置:
如果对QoS的含义不了解,可以参考我之前的文章
先假设整个k8s集群中我们只对10.123.123.123这个node动了手脚,当我们创建pod时,在spec.containers.resources.requests/limits中可以设置
"example.com/dongle": "2"
从而让pod被调度到10.123.123.123上并消耗其2个example.com/dongle资源。这个资源将与cpu、memory一样,被调度器进行统计,并用在pod的调度算法中。如果node上的example.com/dongle资源耗尽,这类pod将无法成功调度。
device-plugin插件
设备插件从1.8版本开始加入,到1.9目前仍是alpha特性,设备插件的作用是在不更改k8s代码的情况下,向k8s提供各种资源的统计信息和使用预备工作。这里说的资源如GPU、高性能NIC、FPGA、infiniBand或其他。
device-plugin的注册和实施
device-plugin功能由DevicePlugins这个参数控制,默认是禁用的,启用这个参数后就可以令kubelet开放Register 的grpc服务。 device-plugin可以通过这个服务向kubelet注册自己,注册时要告知kubelet:
- 本device-plugin的Unix socket 名称。用于kubelet作为grpc 客户端向本device-plugin发请求;
- 本device-plugin的API版本;
- 本device-plugin要开放的资源名,此处资源名必须遵循一定格式,形如:nvidia.com/gpu
注册成功后,kubelet会向device-plugin调用Listandwatch方法获取设备的列表,此处设备的列表以该资源所有设备的描述信息(id、健康状态)组成数组返回。kubelet将这个资源及其对应的设备个数记录到node.status.capicity/allocable 更新到apiserver。该方法会一直循环检查,一旦设备异常或者从机器上拔出,会将最新的设备列表返回给kubelet。
如此一来,创建pod时,spec.containers.resource.limits/requests 中就可以增加如 "nvidia.com/gpu" : 2 这样的字段,来告知k8s将pod调度到有超过2个nvidia.com/gpu资源余量的nodes上(这里与上文的extended-resources中QoS是一个道理)。当node上要运行该pod时,kubelet会向device-plugin调用Allocate方法,device-plugin在这里可能会做一些初始化的操作,比如GPU清理或QRNG初始化之类。如果初始化成功。该方法会返回分配给该pod使用的设备在容器创建时需要如何配置,这个配置会被传递到container runtime。用于run 容器时作为参数进行配置。
完整的使用流程如下图(图片来源:https://github.com/kubernetes...)
device-plugin 使用的代码解析
我们从创建pod的整个流程中一步步解析代码执行:
创建带特殊资源设备的pod;
调度器从cache中选择满足要求的node;
node收到ADD POD, 对pod执行admit方法进行可运行的判断。
kubelet初始化时增加了一个admitHandler
:
klet.admitHandlers.AddPodAdmitHandler(lifecycle.NewPredicateAdmitHandler(klet.getNodeAnyWay, criticalPodAdmissionHandler, klet.containerManager.UpdatePluginResources))
其中就包括了klet.containerManager.UpdatePluginResources
方法,该方法会执行devicepluginManager
中的Allocate
方法:
func (cm *containerManagerImpl) UpdatePluginResources(node *schedulercache.NodeInfo, attrs *lifecycle.PodAdmitAttributes) error { return cm.devicePluginManager.Allocate(node, attrs) }
上述的Allocate方法,会将kubelet本身缓存记录的资源可用量进行判断和计算;
然后选定要使用的设备,向device-plugin发送Allocate调用,device-plugin会针对request中的设备id,检查是否可用,并将使用这几个设备需要的使用参数返回给kubelet,返回的格式是:
type AllocateResponse struct { // List of environment variable to be set in the container to access one of more devices. Envs map[string]string // Mounts for the container. Mounts []*Mount // Devices for the container. Devices []*DeviceSpec }
最后将要这个pod要使用哪几个资源设备(设备id、以及deviceplugin返回的设备使用参数)记录在podDevices
中,podDevices
就是一个从pod到资源设备详细信息的映射,是一个多层次的map结构。
kubelet要创建pod的容器时,会调用到GenerateRunContainerOptions
方法,用于生成容器runtime要的参数,该方法中会首先调用:
opts, err := kl.containerManager.GetResources(pod, container)
而containerManager
中GetResources
会调用devicePluginManager
中的GetDeviceRunContainerOptions
方法,最后执行deviceRunContainerOptions
方法,从podDevices
中获取这个pod相应的容器需要使用的设备,并组织成容器运行时参数的对象opts
,最终run container时会被用到。比如gpu容器,会在opts
中增加devices参数的指定,最后容器创建时会带有需要的设备。
device-plugin的部署
部署device-plugin插件最佳的方法是使用k8s的daemonset,因为daemonset可以在插件失败是重新启动之,且会自动分布到满足条件的所有node节点上。
本文转自中文社区-k8s的扩展资源设计和device-plugin
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Rancher中的K8S认证和RBAC
Rancher Kubernetes拥有RBAC(基于角色的访问控制)功能,此功能可以让管理员配置不同的策略,允许或拒绝用户和服务帐户访问Kubernetes API资源。 为了更好地理解RBAC功能是如何工作的,本文将阐明如何使用Ku bernetes API进行身份认证,以及RBAC授权模块如何与认证用户协同工作。 在Rancher中使用KUBERNETES验证 Rancher使用Webhook Token身份验证策略来认证用户的bearer token。首先,用户使用Rancher验证通过Kubernetes > CLI选项卡获得kube配置文件,这其中就包含bearer token。然后,kubectl借助此token和web hook远程认证服务,用Kubernetes API对用户进行身份认证: 当用户尝试使用bearer token对Kubernetes API进行认证时,认证webhook会与Rancher Kubernetes认证服务进行通信,并发送包含该token的身份认证审查对象。然后,Rancher Kubernetes认证服务将会发送一个检查状态,该状态...
- 下一篇
k8s与CICD--一个完整的drone demo
前言 在上一篇文章中,我们只是简单介绍了一下drone的部署。接下来会逐步深入 介绍,后期也会翻译一些官方的文档以及我在实际工作中用到的插件的介绍。这篇文章,主要是一个完整的drone demo。pipeline中,包括了git clone 拉取代码,go build 构建,生成docker镜像并推送到harbor,notify 通知。关于通知这块,官方提供的插件都是一些西方喜欢用的即时通讯或是协作工具,比如telegram,slack,line等。所以在后期,我计划写一个微信或是钉钉的插件。 .drone.yml 先上配置文件,有一个大概的认识,再逐一解读。 workspace: base: /go path: src/gogs.xxx.com/baa-cicd pipeline: build: image: golang:latest commands: - go build -o baa-cicd publish: image: plugins/docker registry: registry.xxx.com repo: registry.xxx.com/test/baa-ci...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Red5直播服务器,属于Java语言的直播服务器
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker使用Oracle官方镜像安装(12C,18C,19C)