【问题标题】:How does the Kubernetes API server start a newly scheduled pod on a node?Kubernetes API 服务器如何在节点上启动一个新调度的 Pod?
【发布时间】:2021-01-23 09:32:20
【问题描述】:

关于kubelet 和kube-apiserver 之间的交互,我试图更好地了解Kubernetes Pod 调度和创建过程的工作原理。

我了解 Kubernetes 调度程序选择一个节点来分配一个新的 pod 并通知 API 服务器。但是,我不清楚 API 服务器如何通知相关节点上的 kubelet 以启动 pod。 kubelet 中是否有一个轮询过程来查询 API 服务器的更改?还是有事件监听/回调类型交互?

如果有人知道答案或可以指出我将不胜感激的一些文档的方向!

【问题讨论】:

    标签: kubernetes kubernetes-pod kube-apiserver


    【解决方案1】:

    阿里巴巴有一个really insightful blog post on the inner workings of the scheduler。来自博客:


    调度器基本上是这样工作的:

    • 调度器维护一个调度的 podQueue 并监听 APIServer。
    • 创建 Pod 时,我们首先通过 APIServer 将 Pod 元数据写入 etcd。
    • 调度器通过 Informer 监听 Pod 状态。添加新 Pod 时,会将 Pod 添加到 podQueue。
    • 主进程不断从 podQueue 中提取 Pod 并将节点分配给 Pod。
    • 调度过程包括两个步骤:过滤匹配节点并根据 Pod 配置(例如,通过资源使用和亲和性等指标)对这些节点进行优先级排序,以对节点进行评分并选择得分最高的节点。
    • 节点分配成功后,调用apiServer的绑定pod接口,将pod.Spec.NodeName设置为分配的pod。
    • 节点上的 kubelet 也监听 ApiServer。如果发现有新的 Pod 被调度到该节点,则调用本地 dockerDaemon 来运行容器。
    • 如果调度器调度Pod失败,如果启用了优先级和抢占,首先进行抢占尝试,删除节点上低优先级的Pod,将要调度的Pod调度到该节点。如果未启用抢占或抢占尝试失败,相关信息将记录在日志中,并将 Pods 添加到 podQueue 的末尾。

    关于 Kubelet 轮询:实际上,API 服务器支持“监视”模式,该模式使用 WebSocket 协议。通过这种方式,Kubelet 会收到主机名与 Kubelet 主机名相同的 Pod 的任何更改。

    【讨论】:

      【解决方案2】:

      在没有源代码链接的情况下回答,但我确信kubelet 的工作方式如下:

      Query Parameters
      ...
      watch   Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.
      

      监视功能继承自 etcd(API 服务器背后的数据库):https://etcd.io/docs/v3.2.17/learning/api/。见Watch streams:

      Watches are long running requests and use gRPC streams to stream event data.
      

      所以这是一种长轮询。

      【讨论】:

      • 非常感谢您的回复。对观看流功能非常感兴趣。
      • 不客气!请务必利用它,它从一开始就存在,因此它是 Kubernetes 中一种非常成熟且广泛使用的方法。
      猜你喜欢
      • 2020-04-10
      • 1970-01-01
      • 2019-09-17
      • 2020-05-19
      • 2020-09-14
      • 1970-01-01
      • 2012-08-23
      • 2020-09-04
      • 1970-01-01
      相关资源
      最近更新 更多