共计 5175 个字符,预计需要花费 13 分钟才能阅读完成。
在理解 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
// UpdatePod takes a Kubernetes Pod and updates it within the provider.
UpdatePod(ctx context.Context, pod *corev1.Pod) error
// DeletePod takes a Kubernetes Pod and deletes it from the provider.
DeletePod(ctx context.Context, pod *corev1.Pod) error
// GetPod retrieves a pod by name from the provider (can be cached).
GetPod(ctx context.Context, namespace, name string) (*corev1.Pod, error)
// GetPodStatus retrieves the status of a pod by name from the provider.
GetPodStatus(ctx context.Context, namespace, name string) (*corev1.PodStatus, error)
// GetPods retrieves a list of all pods running on the provider (can be cached).
GetPods(context.Context) ([]*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
// NotifyNodeStatus is used to asynchronously monitor the node.
// The passed in callback should be called any time there is a change to the
// node's status.
// This will generally trigger a call to the Kubernetes API server to update
// the status.
//
// NotifyNodeStatus should not block callers.
NotifyNodeStatus(ctx context.Context, cb func(*corev1.Node))
}
API Endpoints:用于实现 kubectl logs 和 kubectl exec
部署
Provider 部署简略仅须要在要增加指标集群的主机中增加二进制程序并依据 IaaS 层配置启动即可:
./bin/virtual-kubelet –provider=”hc-vmware-provider” –exsi=”X.X.X.X”