一、概述
1、上集讲了Scheduler在实现调度时分三步实现调度过程。首先是预选,即从所有节点中选择基本符合选择条件的节点。而后在基本符合条件的节点中使用优选函数计算他们各自的得分并加以比较。并从最高得分的节点中随机选择出一个运行pod的节点,这就是我们的控制平面中scheduler所实现负责的主要功用。同时如果在某些调度场景中我们期望能够通过自己的预设去影响他的一些调度方式,比如就是把我们的pod运行在某些特定的节点之上的时候可以通过自己的预设操作去影响他的预选和优选过程从而使得调度操作能符合我们的期望。我们也说过,此类的影响方式通常有四种。
b、节点亲和性调度:nodeAffinity
二、调度方式
1、节点选择器调度:nodeSelector,nodeName,对nodeName来讲如果我们期望把pod调度到某一特定节点上就在pod的spec的nodeName属性中直接给定这个nodeName的名称即可,这个对应的Pod一定只能调度到这个对应的节点上,如果有一类节点都符合我们的调度方式,那么建议使用nodeSelector,意思就是说我们可以给一段节点打上特有标签,而后我们在pod.spec的属性中使用nodeSelector去匹配这些标签。节点能够适配这些标签的就是pod可运行的节点之一,否则就不是,这种选择方式可以极大的缩小预选范围。他的用法也简单,直接给定我们选定的标签即可。也可以组合多个标签,以默认的逻辑域的方式来选择,只有所有标签都满足的pod node才会运行此pod
[[email protected] ~]# kubectl explain pod.spec.nodeSelector KIND: Pod VERSION: v1 FIELD: nodeSelector <map[string]string> DESCRIPTION: NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node‘s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
a、接下来我们简单操作一波
[[email protected] schedule]# cat pod-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: #也可以在此处写上{app:myapp,tier:frontend}代替下面两行 app: myapp #应用层级标签 tier: frontend #架构层级标签,在分层架构中属于frontend层 annotations: wohaoshuai.com/created-by: "cluster admin" spec: containers: #是一个列表,具体定义方式如下 - name: myapp image: ikubernetes/myapp:v1 nodeSelector: disktype: ssd [[email protected] schedule]# kubectl apply -f pod-demo.yaml pod/pod-demo created [[email protected] schedule]# kubectl get pods -o wide --show-labels NAME READY STATUS RESTARTS AGE IP NODE LABELS pod-demo 1/1 Running 0 25s 10.244.1.3 k8snode1 app=myapp,tier=frontend [[email protected] schedule]# kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS k8smaster Ready master 103d v1.11.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=k8smaster,node-role.kubernetes.io/master= k8snode1 Ready <none> 103d v1.11.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/hostname=k8snode1 k8snode2 Ready <none> 103d v1.11.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=k8snode2
b、假如我们系统上不存在拥有此标签的节点时会出现什么情况呢?可以看到pod会一直处于pending状态,因为调度是无法成功的,这也就意味着nodeSelector是一种强约束,只要不满足第一个条件在预选关就无法通过就不要说优选了。
[[email protected] schedule]# cat pod-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: #也可以在此处写上{app:myapp,tier:frontend}代替下面两行 app: myapp #应用层级标签 tier: frontend #架构层级标签,在分层架构中属于frontend层 annotations: wohaoshuai.com/created-by: "cluster admin" spec: containers: #是一个列表,具体定义方式如下 - name: myapp image: ikubernetes/myapp:v1 nodeSelector: disktype: hirddisk [[email protected] schedule]# kubectl apply -f pod-demo.yaml pod/pod-demo created [[email protected] schedule]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE pod-demo 0/1 Pending 0 21s <none> <none> [[email protected] schedule]# kubectl describe pods pod-demo Name: pod-demo Namespace: default Priority: 0 PriorityClassName: <none> Node: <none> Labels: app=myapp tier=frontend Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"wohaoshuai.com/created-by":"cluster admin"},"labels":{"app": "myapp","tier":"frontend"},"nam... wohaoshuai.com/created-by=cluster admin Status: Pending IP: Containers: myapp: Image: ikubernetes/myapp:v1 Port: <none> Host Port: <none> Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-jvtl7 (ro) Conditions: Type Status PodScheduled False Volumes: default-token-jvtl7: Type: Secret (a volume populated by a Secret) SecretName: default-token-jvtl7 Optional: false QoS Class: BestEffort Node-Selectors: disktype=hirddisk Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 2s (x16 over 45s) default-scheduler 0/3 nodes are available: 3 node(s) didn‘t match node selector.
我们现在手动给一节点打上该标签他就会立即生效了
[[email protected] schedule]# kubectl label nodes k8snode2 disktype=hirddisk --overwrite node/k8snode2 labeled [[email protected] schedule]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE pod-demo 1/1 Running 0 6m 10.244.2.3 k8snode2
2、节点亲和性调度nodeAffinity,在我们pod.spec内嵌有一个属性就叫Affinity,他的值是一个对象,这个对象中我们有下面三种,之所以叫affinity是因为其内嵌的所谓的节点亲和性,pod亲和性,和Pod反亲和性都在这儿定义,此外我们此处说的是nodeAffinity
[[email protected] schedule]# kubectl explain pods.spec.affinity KIND: Pod VERSION: v1 RESOURCE: affinity <Object> DESCRIPTION: If specified, the pod‘s scheduling constraints Affinity is a group of affinity scheduling rules. FIELDS: nodeAffinity <Object> Describes node affinity scheduling rules for the pod. podAffinity <Object> Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). podAntiAffinity <Object> Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).
原文地址:https://www.cnblogs.com/Presley-lpc/p/11382068.html