后 Kubernetes 时代的虚拟机管理技术之 Virtual-Kubelet 篇
在了解 virtual-Kubelet 之前,我们先了解下什么是 Kubelet。
Kubelet 是在每个 Node 节点上运行的主要 “节点代理”。在 Kubernetes 集群中每个节点都会启动一个 kubelet 进程,kubelet 基于 PodSpec 来工作。每个 Pod Spec 是一个描述 Pod 的 YAML 或 JSON 对象。Kubelet 接受通过各种机制(主要是通过 Apiserver)提供的一组 Pod Spec,并确保这些 Pod Spec 中描述的容器处于运行状态且运行状况良好。同时 Kubelet 还通过 cAdvisor 监控容器和节点资源,定期向上报当前节点的健康状态以及资源使用情况,可以把 Kubelet 理解成[Server-Agent]架构中的 Agent。
Virtual-Kubelet 是基于 Kubelet 的典型特性实现,向上伪装成 Kubelet,从而模拟出 Node 对象,对接 Kubernetes 的原生资源对象;向下提供 API,可对接其他资源管理平台提供的 Provider。不同的平台通过实现 Virtual-Kubelet 定义的方法,允许节点由其对应的 Provider 提供(如 ACI,AWS Fargate,IoT Edge,Tensile Kube 等)支持,实现 Serverless,或者将其扩展到如 Docker Swarm、Openstack Zun 等容器平台中,也可以通过 Provider 纳管其他 Kubernetes 集群,甚至是原生的 IaaS 层平台(VMware、zstack、openstack)。
最好的描述是 Kubernetes API on top,programmable back。Virtual-Kubelet 如何管理虚拟机是本文讨论重点。
Virutal-Kubelet 的架构
Virtual-Kubelet 模拟了 Node 资源对象,并负责对 Pod 调度到 Virtual-Kubelet 伪装的虚拟节点之后,对 Pod 进行生命周期管理。
当前支持原生 Kubernetes 特性:
创建,删除和更新 Pod
Container 的日志,管理和监控
获取单个 Pod 或多个 Pod 状态
节点地址,节点容量,节点守护程序端点
管理操作系统携带私有虚拟网络
Virtual-Kubelet 如何管理虚拟机?
虚拟机生命周期管理
Virtual-Kubelet 在虚拟机调度和操作方面可以复用 Kubernetes 原生的资源对象,但 Pod 在 Kubelet 管理下的生命周期仅存在创建、运行和销毁,实际对于虚拟机的开关机、备份和迁移等操作无法实现映射关系,因此对于复杂的生命周期管理,需要通过自定义 CRD 方式支持不同类型的 IaaS 平台,每一个 VM-CR 对应一个 IaaS 层 VM 实例。
对于 VM-CR 操作主要可以分为两类:
对 VM 运行状态变更
创建和销毁:可以对应一个 VM-CR 的 create/delete
VM 启停操作对应 VM-CR replicas 数量的变更:开机 0→1 关机 1→0
VM 规格变更:修改 VM-CR Spec 资源定义
kubectl logs/exec VM-pod:实现对 Pod 的访问
对 VM 进行备份/迁移
VM 备份采用创建对应 Backup-Job 对象,通过与 VM-CR 实例 pod 亲和方式,将 Backup-Job 调度置 VM 实际节点所运行的 Virtual-Kubelet 节点上,备份状态与 Job 执行状态一致
VM 迁移采用 Kubernetes 原生的节点调度方式,IaaS 平台每一个负载 VM 的物理机对应一个 Kubernetes 集群内的 Virtual-Kubelet,VM-CR 实例 Pod 的调度由 Kubernetes 控制面管理
虚拟机存储管理
由于 Virtual-Kubelet 中 Pod 仅作为逻辑概念,IaaS 层存储无法与 Kubernetes 集群公用,但可抽象为 Kubernetes 原生定义的 PV/PVC,PV 的 access mode 能力依赖 IaaS 层能力,并需要实现对应平台和底层存储的 Provider 和 Provisioner。
Virtual-Kubelet 如何实现容器与虚拟机交互
容器和虚拟机互通
Virtual-Kubelet 对应的 Node 会上报节点上 Pod 的 Endpoint,假定 Kubernetes 集群和 IaaS 层平台部署在同一个二层网络下,则集群内容器 Pod 可以访问 VM-Pod,但容器 Pod 对于 VM-Pod 不可见;
针对上一点可以通过 Macvlan 等网络插件,将容器-Pod,降维至二层网络上,实现容器-Pod 和虚拟机互通,有一定硬件要求。
如何实现一套集群下虚拟机与容器的混合调度与资源隔离
Virtual-Kubelet 提供的是一个虚拟节点用来向 Kubernetes 上报 Node 对象和 Pod 的状态和资源情况,虚拟机资源和集群内节点资源完全隔离;
在引入 Virtual-Kubelet 的情况下,需要对 Virtual-Kubelet 节点配置 Taint 和 Tolerations,保证容器-Pod 和 VM-Pod 调度分离。
服务发现
Virtual-Kubelet,通过 Provider 实现的 API 将 IaaS 层 VM 信息抽象成对应 Pod 对象的信息的方式来上报 Endpoints,可以通过给 CR 添加 no selector Service,待 VM-Pod 拉起后补充 address 至对应的 Service。
Virutal-Kubelet 适用场景
适用场景
Virtual-Kuberlet 适合在已有 IaaS 层管理平台和 Kubernetes 集群环境下进行二者的打通,实现在 Kubernetes 集群上统一管理容器和非容器平台,同时由于 Virtual-Kubelet 在 Serverless 和纳管其他已有容器平台(Openstack Zun,Docker Swarm)方面也具有很高适配性,Virtual-Kubelet 可以提供一套统一的 API,方便开发者打通全流程。
Virtual-Kubelet 的优缺点
优点
一个开源的 Kubelet 实现,使用 Kubernetes 源语,使构建、部署更简单
提供 Kubelet 典型特性接口,Provider 仅需实现对应服务管理平台资源到 Node 和 Pod 对象特性的实现,不需要考虑如何访问 Kubernetes
灵活性高,Severless 实践、对接现有容器平台、对接现有 IaaS 平台均有一定前景
Virtual-Kubelet 设计将 virtual-kubelet 和 Provider 高度分离,Virtual-Kubelet 使对于异构服务平台具有很高的兼容性(不同架构如:ARM、S390x,不同 CRI 如:Kata、PodMan),不光是可以纳关 IaaS 平台对于其他 Kubernetes 集群也可以实现管理
缺点
将非集群内资源抽象成 Node 和 Pod 对象对资源使用上有一定局限性,很难提供超出原有 kubelet 和 IaaS 平台能力范畴,IaaS 深度整合需要自行实现 CRD
仅能作为转换器,用于容器和虚拟机统一管理时还是需要依托已有的平台能力,无法像 Kubevirt 等方案作为一个单独的 Iaas 管理平台使用
Virtual-Kubelet 开发及部署
开发自定义的 Provider
Virtual-Kubelet 项目本身并不提供 Provider,而是提供一系列定义 Kubelet 典型操作的接口,开发者需要根据应用场景实现对应的 Provider。使 Kubernetes 可以进行按需和几乎即时的 Container 的计算、调度,而无需管理 VM 基础结构,同时仍可利用可移植的 KubernetesAPI。
实现遵循以下三个准则:
提供必要的后端管道(back-end plumbing),以在 Kubernetes 的 Context 中支持 Pods,Containers 和相关资源的的生命周期管理
符合 Virtual-Kubelet 当前提供的 API
没有访问 Kubernetes APIServer 的权限,通过实现具有定义良好的回调机制来获取 Secrets 或 Configmap 之类的数据
创建一个新的 Provider 主要需要通过调用 Virtual-Kubelet 提供的库实现如下三个接口:
PodLifecylceHandler:用于 Pod 生命周期的管理
type PodLifecycleHandler interface {// CreatePod takes a Kubernetes Pod and deploys it within the provider.CreatePod(ctx context.Context, pod *corev1.Pod) error
}
PodNotifier:该接口允许 Provider 提供异步通知 Virtual-Kubelet 有关 Pod 状态更新的信息,如未实现该接口的话,Virtual-Kubelet 会定期检查所有 Pod 的状态,在计划运行大量 Pod 的场景中强烈推荐实现该接口
type PodNotifier interface {// NotifyPods instructs the notifier to call the passed in function when// the pod status changes.//// NotifyPods should not block callers.NotifyPods(context.Context, func(*corev1.Pod))}
NodeProvider:NodeProvider 负责通知虚拟小程序有关节点状态更新的信息。
Virtual-Kubelet 将定期检查节点的状态并相应地更新 Kubernetes,如果不打算额外定义 Node 特性,可以直接使用 Virtual-Kubelet 提供的 NativeNodeProvider
type NodeProvider interface {// Ping checks if the node is still active.// This is intended to be lightweight as it will be called periodically as a// heartbeat to keep the node marked as ready in Kubernetes.Ping(context.Context) error
}
API Endpoints:用于实现 kubectl logs 和 kubectl exec
部署
Provider 部署简单仅需要在要添加目标集群的主机中添加二进制程序并根据 IaaS 层配置启动即可:./bin/virtual-kubelet --provider="hc-vmware-provider" --exsi="X.X.X.X"
版权声明: 本文为 InfoQ 作者【谐云】的原创文章。
原文链接:【http://xie.infoq.cn/article/53ef483bf56b656120b30348e】。文章转载请联系作者。
评论