介绍OpenShift Scheduler算法
Pod调度程序确定将新Pod放置到OpenShift集群中的节点上。它被设计为高度可配置的,并适应于不同的集群。红帽OpenShift容器平台4.2随附的默认配置通过使用节点标签,相似性规则和反相似性规则来支持区域和区域的通用数据中心概念。
OpenShift pod调度程序算法遵循三个步骤:
1.过滤节点 Filtering nodes.
调度程序通过针对一组谓词(例如主机端口的可用性)或是否可以将Pod调度到遇到磁盘或内存压力的节点来过滤正在运行的节点的列表。
此外,pod可以定义与群集节点中的标签匹配的node selector。标签不匹配的节点不符合条件。
Pod还可以为计算资源(例如CPU,内存和存储)定义资源请求。可用计算机资源不足的节点不符合条件。
另一个过滤检查将评估节点列表是否有taints,如果是,则容器是否一有 toleration 可以接受taints。如果Pod无法接受节点的taints,则该节点不符合条件。默认情况下,主节点包括taintnode-role.kubernetes.io/master:NoSchedule。
过滤步骤的最终结果通常是有资格运行Pod的节点候选列表的较短列表。在某些情况下,不会过滤掉任何节点,这意味着Pod可以在任何节点上运行。在其他情况下,所有节点都被过滤掉,这意味着只有在具有所需先决条件的节点可用之前,才能调度Pod。
谓词及其描述的完整列表可以在参考部分中找到。
2.优先考虑过滤后的节点列表
候选节点列表是使用多个优先级标准进行评估的,这些标准的总和为加权得分。值较高的节点更适合运行Pod。
在标准区域中,亲和力和反亲和力规则。对Pod具有较高亲和力的节点得分较高,而具有较高抗亲和力的节点得分较低。
由于性能原因,亲和性规则的常见用法是安排相关的容器彼此靠近。一个示例是将相同的网络主干用于彼此同步的Pod。
anti-affinity规则的常见用法是安排彼此之间不太近的相关Pod,以实现高可用性。一个示例是避免将所有Pod从同一应用程序调度到同一节点。
3.选择最适合的节点
根据这些得分对候选列表进行排序,并选择得分最高的节点来托管该pod。如果多个节点具有相同的高分,则以循环方式选择一个。
调度程序非常灵活,可以针对高级调度情况进行定制。此外,也可以使用Pod亲和力和反亲和力规则以及节点亲和力和反亲和力规则来放置Pod。
调度与拓扑
大型数据中心(例如云提供商)的常见拓扑是将主机组织到regions和zones:
配置label和selector
标记节点
作为OpenShift集群管理员,您可以向节点添加其他标签。例如,您可以使用dev,qa或prod值将节点标记为env标签,以将开发,质量保证和生产工作负载部署到特定的节点子集。您选择的标签是任意的,但是您必须将标签及其关联的值发布给开发人员,以便他们可以适当地配置其应用程序。
使用oc label命令作为集群管理员可以立即添加,更新或删除节点标签。例如,使用以下命令使用env = dev标记节点:
[user@demo ~]$oc label nodenode1.us-west-1.compute.internalenv=dev
使用--overwrite选项可以更改现有标签。
[user@demo ~]$oc label nodenode1.us-west-1.compute.internalenv=prod --overwrite
通过指定标签名称后跟连字符(例如env-)来删除标签。
[user@demo ~]$oc label nodenode1.us-west-1.compute.internal env-
标签及其值均区分大小写。应用程序节点选择器必须匹配实际标签的大小写和应用于该节点的值。
将--show-labels选项与oc get nodes命令一起使用可查看分配给节点的区分大小写的标签。
[user@demo ~]$oc get nodenode2.us-west-1.compute.internal--show-labels
NAME ... ROLES ... LABELS
node2.us-west-1.compute.internal ... worker ... beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m4.xlarge,beta.kubernetes.io/os=linux,tier=gold,failure-domain.beta.kubernetes.io/region=us-west-1,failure-domain.beta.kubernetes.io/zone=us-west-1c,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux,node-role.kubernetes.io/worker=,node.openshift.io/os_id=rhcos
请注意,一个节点可能具有由OpenShift分配的几个默认标签。集群管理员不应更改其密钥包含kubernetes.io的标签,因为调度程序在内部使用它们。
群集管理员还可以使用-L选项来确定单个标签的值。例如:
[user@demo ~]$oc get node -L failure-domain.beta.kubernetes.io/region
NAME ... ROLES ... REGION
ip-10-0-131-214.us-west-1.compute.internal ... master ... us-west-1
ip-10-0-139-250.us-west-1.compute.internal ... worker ... us-west-1
ip-10-0-141-144.us-west-1.compute.internal ... master ... us-west-1
ip-10-0-152-57.us-west-1.compute.internal ... master ... us-west-1
ip-10-0-154-226.us-west-1.compute.internal ... worker ... us-west-1
支持oc get中的多个-L选项。例如:
[user@demo ~]$oc get node -L failure-domain.beta.kubernetes.io/region \>-L failure-domain.beta.kubernetes.io/zone -L env
NAME ... REGION ZONE ENV
ip-10-0-131-214.us-west-1.compute.internal ... us-west-1 us-west-1b
ip-10-0-139-250.us-west-1.compute.internal ... us-west-1 us-west-1b dev
ip-10-0-141-144.us-west-1.compute.internal ... us-west-1 us-west-1b
ip-10-0-152-57.us-west-1.compute.internal ... us-west-1 us-west-1c
ip-10-0-154-226.us-west-1.compute.internal ... us-west-1 us-west-1c
Labeling Machine Sets
OCP4对IaaSMachine API I资源全部驻留在openshift-machine-api命名空间中。它们不是群集作用域。
MachineSet(定义了与IaaS对接的凭证、创建machine的模板、默认machine的数量)==》Machine==>Node
MachineAutoscaler:定义的machinset副本最大值和最小值
ClusterAutoscaler:设置machinet副本增加和减少的触发条件(CPU和内存阈值)。每个OCP集群只能有一个ClusterAutoscaler。用名为default的ClusterAutoscaler。
尽管节点标签是持久性的,但如果OpenShift群集包含Machine Sets(如果使用完全堆栈自动化方法安装了群集则创建了计算机集),则还应将标签添加到计算机集配置中。这样可以确保新机器(以及从中生成的节点)也将包含所需的标签。
您可以通过在openshift-machine-api namespace中列出机器并包括-o wide选项来识别机器和节点之间的关系。
[user@demo ~]$oc get machines -n openshift-machine-api -o wide
NAME ... NODE
...output omitted...ocp-qz7hf-worker-us-west-1b-rvx6w ... ip-10-0-139-250.us-west-1.compute.internal
ocp-qz7hf-worker-us-west-1c-v4n4n ... ip-10-0-154-226.us-west-1.compute.internal
machine由machineset产生。给machineset设置了label,由此产生的machine都会有这个label。
[user@demo ~]$oc get machineset -n openshift-machine-api
NAME DESIRED CURRENT READY AVAILABLE ...
ocp-qz7hf-worker-us-west-1b 1 1 1 1 ...
ocp-qz7hf-worker-us-west-1c 1 1 1 1 ...
编辑machine set,以使由此产生的新机器具有所需的标签。
修改machine set不会将更改应用于现有计算机或节点。
[user@demo ~]$oc edit machinesetocp-qz7hf-worker-us-west-1b\>-n openshift-machine-api
下面突出显示的行显示了在机器集中添加标签的位置。
...output omitted...
spec:
metadata:
creationTimestamp: null
labels:env: dev
providerSpec:
...output omitted..
控制pod的位置
OpenShift集群中的许多与基础架构相关的Pod配置为在主节点上运行。示例包括DNS Operator,OAuth Ope和OpenShift API服务器的容器。在某些情况下,这是通过在守护程序集或副本集的配置中使用节点选择器node-role.kubernetes.io/master:来完成的。
同样,某些用户应用程序可能需要在一组特定的节点上运行。例如,某些节点为某些类型的工作负载提供硬件加速,或者集群管理员不想将生产应用程序与开发应用程序混合使用。使用节点标签和节点选择器可以实现这些方案。
node selector是单个容器定义的一部分。在部署资源或部署配置资源中定义节点选择器,以便从该资源生成的任何新容器都将具有所需的node selector。如果您的deployments或dc受版本控制,请修改资源文件并使用oc apply -f命令应用更改。
或者,可以使用oc edit命令或oc patch命令添加或修改节点选择器。例如,要配置myappdeployment使其仅在具有env = qa标签的节点上运行,请使用oc edit命令:
oc edit deployment/myapp
...output omitted...
spec:
...output omitted...
template:
metadata:
creationTimestamp: null
labels:
app: myapp
spec:
nodeSelector:env: dev
containers:
- image: quay.io/redhattraining/scaling:v1.0
...output omitted..
以下oc patch命令可完成相同的操作:
[user@demo ~]$oc patch deployment/myapp --patch \>'{"spec":{"template":{"spec":{"nodeSelector":{"env":"dev"}}}}}'
无论使用oc edit命令还是oc patch命令,更改都会触发新的部署,并且根据节点选择器计划新的Pod。
为项目配置node selector
如果集群管理员不希望开发人员控制其Pod的node selector,则应在项目资源中配置默认的node selector。集群管理员可以在创建项目时定义node selector,也可以在创建项目后添加或更新node selector。使用oc adm new-project命令在项目创建时添加节点选择器。例如,以下命令创建一个名为“ demo”的新项目,其中所有Pod将部署到标签为“ tier = 1”的节点上。
[user@demo ~]$oc adm new-project demo --node-selector "tier=1"
要为现有项目配置默认的节点选择器,请使用openshift.io/node-selector键向名称空间资源添加注释。oc annotate命令可以添加,修改或删除节点选择器注释:
[user@demo ~]$oc annotate namespace demo \>openshift.io/node-selector="tier=2" --overwrite
扩展Pod副本数
尽管大多数部署和部署配置资源都是从创建单个Pod开始的,但是Pod的副本(或副本)数量经常增加。这可以通过扩展部署或部署配置来实现。稍后将介绍多种缩放方法,但是一种方法使用theoc scale命令。例如,可以使用以下命令将myappdeployment中的pod的数量缩放为三个:
[user@demo ~]$oc scale --replicas 3 deployment/myapp