第7章 Kubernetes调度
- 创建一个pod的工作流程
 - Pod中影响调度的主要属性
 - 资源限制对pod调度的影响
 - nodeSelector&nodeAffnity
 - Taints & Tolerations
 - nodeName
 - DaemonSet控制器
 - 调度失败原因分析
 
7.1 创建一个pod的工作流程
kubernets基于list-watch机制的控制器架构,实现组件间交互的解耦。
其他组件监控自己负责的资源,当这些资源发生变化是,kube-APIServer会通知这些组件,这个过程类似于发布订阅。

1) Kubectl run 创建一个pod,将请求发送给apiserver,apiserver将数据存储到etcd中。
2) Secheduler将创建的pod根据自己的调度算法选择一个合适的节点,订一个标记NodeName=k8s-node1,返回给apiserver,存储到etcd。
3) Kubectl发现有新的pod分配到我这个了,调用docker api创建容器,并将容器状态返回给apiserver,存储到etcd
4) Kubectl get pods
Controller-manager 负责常规后台任务,例如:deployment
Kube-proxy:负责容器网络,具体service实现
7.2 Pod中影响调度的主要属性

7.3 资源限制对pod调度的影响
容器资源限制: • Resources.limits.cpu • Resources.limits.memory 容器使用的最小资源需求,作为容器调度时资源分配的依据: • Resources.requests.cpu • Resources.requests.memory CPU单位:可以写m也可以写浮点数,例如0.5=500m,1=1000m 1、资源限制,容器里应用程序使用的最大资源上限 2、资源请求值对调度的影响 1、limits 容器里应用程序使用的最大资源上限(0.5Core/500Mi) 2、requests 请求值,预留性质,不是实际占用,用于资源分配的参考值,判断node可否容纳(k8s是一个大的资源池) 3、requests 一般良性参考是小于limits的20%-30% 4、节点上limits总和不能超宿主机实际物理配置的20%,否则限制意义不大了 5、requests必须小于limits 6、当请求的值没有节点能够满足时,pod处于pendding
K8s会根据Request的值去查找有足够资源的Node来调度此Pod 实例: apiVersion: v1 kind: Pod metadata: name: resources-pod spec: containers: - name: web image: nginx resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" 验证: kubectl describe pod resources-pod kubectl describe k8s-node1 #该节点运行的pod及资源使用汇总。
7.4 nodeSelector & nodeAffinity、pod节点调度
nodeSelector:用于将pod调度到匹配label的Node上,如果没有匹配的标签会调度失败。
作用:
•    约束pod到特定的节点运行
•    完全匹配节点标签
应用场景:
•    专用节点:根据业务线将Node分组管理
•    匹配特殊硬件:部分Node配有SSD硬盘、GPU
7.4.1NodeSelector&nodeAffinity调度场景
示列:确保pod分配到具有SSD硬盘的节点上
第一步:给节点添加标签
格式:kubectl label nodes <node-name> <label-key>=<label-value>
例如:kubectl label nodes k8s-node1 disktype=ssd
验证:kubectl get nodes --show-labels
第二步:添加nodeSelector字段到Pod配置中
apiVersion: v1 kind: Pod metadata: name: my-pod spec: nodeSelector: disktype: "ssd" containers: - image: nginx:1.16 name: my-pod restartPolicy: Always 最后,验证: kubectl get pods -o wide
7.4.2nodeAffinity的软硬策略
nodeAffinity:节点亲和类似于nodeSelector,可以根据节点上的标签来约束pod可以调度到那些节点。
相比:nodeselector:
- 匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作符有:In、NotIn,Exists、DoesNotExist、Git、Lt
- In:部署在满足多个条件的节点上
 - NotIn:不部署在满足这些条件的节点上
 - Exists:部署在具有某个存在key为指定的值得node节点上
 - DoesNotExist:和Exists相反
 - Gt 大于指定的条件
 - Lt小于指定的条件
 
 - 调度分为软策略和硬策略,而不是硬性要求
 
硬(requireed):必须满足
软(preferred):尝试满足,但不保证

apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: gpu operator: In values: - nvidia-tesla preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: group operator: In values: - ai containers: - name: web image: nginx
7.5 Taint(污点)与Tolerations(污点容忍)
Taints:避免pod调度到特定Node上
Tokerations:允许Pod调度到特有Taints的Node上
应用场景:
•    专用节点:根据业务线将Node分组管理,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
•    配置特殊硬件:部分Node配置有SSD硬盘,GPU,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
•    基于Taint的驱逐
7.5.1pod使用污点
第一步:给节点添加污点 格式:kubectl taint node [node] key=value:[effect] 例如:kubectl taint node k8s-node1 gpu=yes:NoSchedule 验证:kubectl describe node k8s-node1 |grep Taint 删除污点:kubectl taint node k8s-node1 gpu=yes:NoSchedule- 其中【effect】可取值: • NoSchedule:一定不能被调度 • PreferNoSchedule:尽量不要调度,非必须配置容忍 • NoExecute:不仅不会调度,还会驱逐Node上已有的pod 第二步:如果希望Pod可以被分配到带有污点的节点上,要在pod配置中添加污点容忍(tolrations)字段 去除污点: Kubectl taint node [node] key:[effect]-
apiVersion: v1 kind: Pod metadata: name: pod-taints spec: containers: - name: pod-taints image: busybox:latest tolerations: - key: "gpu" operator: "Equal" value: "yes" effect: "NoSchedule"
7.6NodeName调度
nodeName:指定节点名称,用于将pod调度到指定的Node上,不经过调度器。

apiVersion: v1 kind: Pod metadata: name: nodename-pod labels: app: nginx spec: nodeName: k8s-master1 containers: - name: nginx image: nginx:1.15
7.7DaemonSet
DaemonSet功能:
•    在每一个Node上运行一个pod
•    新加入的Node也同样会自动运行一个pod
应用场景:网络插件、监控agent、日志agent

7.7.1DaemonSet示列:
示例:部署一个日志采集程序

7.8pod调度失败原因分析
查看调度结果:
kubectl get pod <NAME> -o wide
查看调度失败原因:kubectl describe pod <NAME>
• 节点CPU/内存不足
• 有污点,没容忍
• 没有匹配到节点标签
Affinity:亲和力总结
requiredDuringSchedulingIgnoredDuringExecution:硬亲和力,即支持必须部署在指定的节点上,也支持必须不部署在指定的节点上。 a=b preferredDuringSchedulingIgnoredDuringExecution:软亲和力,尽量部署在满足条件的节点上,或者是尽量不要部署在被匹配的节点。 PodAffinity: pod的亲和力 例如:A应用A应用C应用,将A应用根据某种策略尽量或者部署在一块。Label A:app=a B:app=b requiredDuringSchedulingIgnoredDuringExecution: 将A应用和B应用部署在一块 preferredDuringSchedulingIgnoredDuringExecution: 尽量将A应用和B应用部署在一块 PodAffinity:pod反亲和力 例如:A应用A应用C应用,将A应用根据某种策略尽量或者不部署在一块。Label requiredDuringSchedulingIgnoredDuringExecution: 不要将A应用与之匹配的应用部署在一块 preferredDuringSchedulingIgnoredDuringExecution: 尽量。。
                    
                
                
            
        
浙公网安备 33010602011771号