Kubernetes允许为POD指定CPU limit and/or request。
对CPU资源的限制和请求以 cpu单位衡量。 Kubernetes中的一个cpu等效于:
1 AWS vCPU
1 GCP Core
1 Azure vCore
1 IBM vCPU
1 Hyperthread on a bare-metal Intel processor with Hyperthreading
不幸的是,当使用异构集群(例如,使用不同的处理器)时, cpu限制/请求取决于分配了POD的节点;尤其是对于实时应用。
如果我们假设:
是否有一种启动POD的方式,以便CPU限制/请求取决于Kubernetes调度程序选择的节点(或Node标签)?
获得的行为应为(或等效于):
答案 0 :(得分:2)
否,每种节点类型不能有不同的请求。您可以做的是创建一个具有对特定类型节点的节点亲和力的Pod清单,并请求对该节点类型有意义的请求。对于第二类节点,您将需要第二个pod清单,该清单对于该节点类型有意义。这些pod清单的不同之处仅在于它们的相似性规范和资源请求-因此将它们参数化将很方便。您可以使用Helm做到这一点,或者编写一个简单的脚本来做到这一点。
通过这种方法,您可以在节点的子集内启动具有在这些节点上有意义的资源请求的Pod,但是无法根据其最终位置来全局调整其请求/限制。
答案 1 :(得分:0)
在分配POD之前,调度程序会根据节点(或节点标签)检查不同的cpu请求来选择节点
不是使用默认调度程序,最接近的选项是使用node-affinity,就像Marcin建议的那样,因此您可以根据节点标签选择节点。如下所示:
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: podname
image: k8s.gcr.io/pause:2.0
在这种情况下,您将使用标签标记节点以标识其类型或用途,例如: db,cache,web 等。然后设置亲和力以匹配所需的节点类型。
requiredDuringSchedulingIgnoredDuringExecution
表示如果不满足条件,则不会在节点中调度pod。
preferredDuringSchedulingIgnoredDuringExecution
意味着调度程序将尝试查找也符合该条件的节点,但是如果没有节点满足指定条件,则会在任何可能的地方调度pod。
您的另一种选择是编写您的自定义计划程序。
apiVersion: v1
kind: Pod
metadata:
name: annotation-default-scheduler
labels:
name: multischeduler-example
spec:
schedulerName: default-scheduler
containers:
- name: pod-with-default-annotation-container
image: k8s.gcr.io/pause:2.0
Kubernetes附带一个默认的调度程序,描述为here。如果默认调度程序不适合您的需求,则可以实现自己的调度程序。这样,您可以编写复杂的调度逻辑来确定每个POD的位置,仅针对使用默认调度程序无法实现的建议
请记住,Kubernetes中最重要的组件之一是调度程序,默认调度程序经过了实战测试,可以灵活地处理大多数应用程序。编写自己的调度程序会丢失默认调度程序提供的功能,例如负载平衡,策略,过滤。要了解有关默认计划程序提供的功能的更多信息,请查看文档here。
如果您愿意冒险并想编写自定义计划程序,请查看here中的文档。
在运行时,Kublet根据节点(或节点标签)检查特定的cpu限制
在接收到分配容器的请求之前,调度程序会检查节点中的资源可用性,然后将容器分配给节点。 每个节点都有自己的kubelet,该kubelet会检查应该在该节点中初始化的pod,而kubelet唯一要做的就是启动这些pod,它不会决定应将pod移到哪个节点。
Kubelet还会在初始化POD之前检查资源,以防Kubelet无法初始化Pod,它只会失败,并且调度程序将采取措施将Pod调度到其他位置。