一、创建一个Pod的工作流程
kubernetes基于list-watch机制的控制器架构,实现组建间交互的解耦。其他组件监控自己负责的资源,当这些资源发生变化时,kube-apiserver会通知这些组件,这个过程类似于发布与订阅。
创建流程:
1、kubectl run/apply创建一个pod,向apiserver发起请求
2、apiserver会将请求的配置写到etcd
3、etcd响应处理结果给apiserver,apiserver响应处理结果给kubectl
4、scheduler收到需要创建pod的请求,根据自己调度算法选择一个合适的节点分配,并将结果反馈给apiserver
5、kubelet收到需要创建这个节点的pod,在调度容器引擎创建容器,容器引擎将结果反馈给kubelet,kubelet汇总pod状态反馈给apiserver
工作流程图:少了controller-manager和kube-proxy组件,创建pod是不需要这两个组件的。
controller-manager是创建工作负载控制器才会用到
kube-proxy创建service才使用的
二、Pod中影响调度的主要属性
三、资源限制对Pod调度的影响
容器资源限制:
1、resources.limits.cpu
2、resources.limits.memory
容器使用的最小资源需求,作为容器调度事资源分配的依据:
1、resources.requests.cpu
2、resources.requests.memory
cpu单位:可以写m也可以写浮点数。如:0.5=500m,1=1000m
k8s会根据request的值去查找有足够资源的node来调度pod
资源配额注:
1、request必须小于limits。
2、requests配置建议低于limits的20%-30%
3、m是cpu的一个计量单位,称为毫核,如节点2C4G,2C=2*1000m。
4、如果设置cpu的值是浮点数,会自动转m单位
5、如果没有节点满足requests配置要求,pod不会被创建
问题:
1、如果request配置超出节点配置会怎么样?
pod无法分配,pendding状态
2、如果只是limits超出节点配置会怎么样?
pod正常分配,可以超卖
3、如果limits设置太大(超出节点配置)会怎样?
pod正常分配,可以超卖,但是如果超出节点配置比较多,出现节点资源打满的几率就比较大
4、怎么查看节点资源分配情况?
# kubectl describe node <所有node>
# kubectl get nodes <获取所有node>
# # kubectl describe node hs-develop-560 <获取指定node资源分布>
四、node Selector & nodeAffinity
1、nodeSelector:
用于将pod调度到匹配label的Node上,如果没有匹配的标签会调度失败。
作用:
a、约束Pod到特定的节点运行
b、完全匹配节点标签
应用场景:
a、专用节点:根据业务线将Node分组管理
b、配备特殊硬件:部分Node配有ssd硬盘、GPU
示例:
第一步、给节点添加标签
格式:# kubectl label nodes <node-name> <label-key>=<label-value>
例如:# kubectl label nodes k8s-node1 disktype=ssd
验证:# kubectl get nodes --show-labels
第二步、添加nodeSelector字段到Pod配置中
最后验证:
# kubectl get pods -o wide
2、nodeAffinity:
节点亲和性,与nodeSelector作用一样,但相比更灵活,满足更多条件。如:
1、匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作符:In,Notln,Exists,DoesNotExist,Gt,Lt
2、电镀分为软策略和硬策略,而不是硬性要求
a、硬<required>: 必须满足
b、软<preferred>: 尝试满足,但不保证
查看标签为gpu的node:
# kubectl get node -l gpu=yes
硬性配置:
软性配置:
注:weight:1-100,值越大,权重越大,pod调度到符合标签的节点概率越高
五、Taint(污点) & Tolerations(污点容忍)
Taints:避免Pod调度到特定Node上
Tolerations:允许Pod调度到持有Taints的Node上
应用场景:
1、专用节点:根据业务线将Node分组管理,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配。
2、配备特殊硬件:部分Node配有ssd硬盘、GPU,希望在more情况下不调度该节点,只有配置了污点容忍才允许分配
3、基于Taint的驱逐
第一步:给节点添加污点
格式:# kubectl taint node [node] key=value:[effect]
例如:# kubectl taint node k8s-node1 gpu=yes:NoSchedule
验证: # kubectl describe node k8s-node1 | grep Taint
其中[effect]可取值:
1、NoSchedule:一定不能被调度
2、PreferNoChedule:尽量不要调度,非必须配置容忍
3、NoExecute:不仅不会调度,还会驱逐Node上已有的pod
第二步、添加污点容忍(tolrations)字段到pod配置中
去掉污点:
# kubectl taint node [node] key:[effect]-
小结:
# nodeSelector:节点做好分组,希望pod根据配置调度到部分节点
# Taints:节点做特殊用途,不希望正常pod分配过来
容忍所有污点:
调度失败原因分析:# kubectl describe pod xxx
1、pod配置的requests.cpu没有满足
2、pod配置的nodeSelector没有节点满足
3、节点都有污点,pod没有配置污点容忍
六、nodeName
指定节点名称,用于将pod调度到指定的Node上,不经过调度器。