Kubernetes 已经成为容器和容器化工作负载的标准编排引擎。它提供了一个通用的开源抽象层,跨越公共和私有云环境。
对于那些已经熟悉 Kubernetes 及其组件的人来说,讨论通常围绕如何最大化 Kubernetes 的能力。但是,当您刚开始学习 Kubernetes 时,最好先了解一些关于 Kubernetes 及其组件(包括 Kubernetes 调度器)的通用知识,如这个高层次视图所示,然后再尝试在生产环境中使用它。
Kubernetes 也使用控制平面和节点。
- 控制平面: 也称为 master,这些节点负责对集群做出全局决策,以及检测或响应集群事件。控制平面组件包括:
- etcd
- kube-apiserver
- kube-controller-manager
- 调度器
- 节点: 也称为工作节点,这些节点集是工作负载驻留的地方。它们应始终与控制平面通信,以获取工作负载运行所需的信息,以及在集群外部进行通信和连接。工作节点组件包括:
- kubelet
- kube-proxy
- 容器运行时接口。
我希望这个背景知识能帮助您理解 Kubernetes 组件是如何堆叠在一起的。
Kubernetes 调度器如何工作
Kubernetes Pod 由一个或多个容器组成,这些容器共享存储和网络资源。Kubernetes 调度器的任务是确保每个 Pod 都被分配到一个节点上运行。
从高层次来看,以下是 Kubernetes 调度器的工作方式
- 每个需要调度的 Pod 都会被添加到队列中
- 当创建新的 Pod 时,它们也会被添加到队列中
- 调度器不断地从队列中取出 Pod 并进行调度
调度器的代码 (scheduler.go
) 很大,大约 9,000 行,而且相当复杂,但需要处理的重要部分是
-
等待/监视 Pod 创建的代码
监视 Pod 创建的代码从 scheduler.go 的第 8970 行开始;它无限期地等待新的 Pod// Run begins watching and scheduling. It waits for cache to be synced, then starts a goroutine and returns immediately. func (sched *Scheduler) Run() { if !sched.config.WaitForCacheSync() { return } go wait.Until(sched.scheduleOne, 0, sched.config.StopEverything)
-
负责将 Pod 排队的代码
负责 Pod 排队的函数是// queue for pods that need scheduling podQueue *cache.FIFO
负责将 Pod 排队的代码从 scheduler.go 的第 7360 行开始。当事件处理程序被触发以指示有新的 Pod 可用时,这段代码会自动将新的 Pod 放入队列中
func (f *ConfigFactory) getNextPod() *v1.Pod { for { pod := cache.Pop(f.podQueue).(*v1.Pod) if f.ResponsibleForPod(pod) { glog.V(4).Infof("About to try and schedule pod %v", pod.Name) return pod } } }
-
处理错误的代码
在 Pod 调度中,您不可避免地会遇到调度错误。以下代码是调度器如何处理错误的。它监听podInformer
,然后输出一个错误,表明 Pod 未被调度并终止// scheduled pod cache podInformer.Informer().AddEventHandler( cache.FilteringResourceEventHandler{ FilterFunc: func(obj interface{}) bool { switch t := obj.(type) { case *v1.Pod: return assignedNonTerminatedPod(t) default: runtime.HandleError(fmt.Errorf("unable to handle object in %T: %T", c, obj)) return false } },
换句话说,Kubernetes 调度器负责
- 在具有足够空间的节点上调度新创建的 Pod,以满足 Pod 的资源需求
- 监听 kube-apiserver 和控制器以了解新创建的 Pod 的存在,然后将它们调度到集群中的可用节点
- 监视未调度的 Pod,并使用
/binding
pod 子资源 API 将它们绑定到节点。
例如,假设正在部署一个应用程序,该应用程序需要 1GB 内存和两个 CPU 核心。因此,应用程序的 Pod 被创建在具有足够可用资源的节点上。然后,调度器继续永远运行,监视是否有需要调度的 Pod。
了解更多
要拥有一个正常工作的 Kubernetes 集群,您需要使上述所有组件协同工作。调度器是一段复杂的代码,但 Kubernetes 是一个很棒的软件,目前,它是采用云原生应用程序时的默认选择。
学习 Kubernetes 需要时间和精力,但将其作为您的技能之一将为您带来优势,这应该在您的职业生涯中带来回报。有很多好的学习资源可用,并且文档也很好。如果您有兴趣了解更多信息,我建议从以下内容开始
您最喜欢的学习 Kubernetes 的方式是什么?请在评论中分享。
评论已关闭。