一.创建一个pod的工作流程
kubernetes是基于list-watch机制的控制器架构,实现组件间的交互解耦 其他组件监听自己的负责的资源,当这些资源发生改变时,kube-apiserver会通知对应组件处理。
如上图,创建pod的工作流程
1.kubectl将创建pod的指令发送给kube-apiserver
2.kube-apiserver收到指令后,写入etcd数据库后,转交给scheduler
3.scheduler根据现有node资源,将创建的pod的指令根据调度策略分配个某个node结点上的kubelet,同时将自己的操作发送给kube-apiserver
4. kube-apiserver收到scheduler的操作结果更新到etcd数据库,并通知此结点上的kubelet
5.kubelet收到操作指令后,调用本地的容器引擎(docker run),创建容器实例,完成后,将容器的状态发送给kube-apiserver
6.kube-apiserver收到kubelet创建成功消息后,将此pod的相关信息更新到etcd数据库
7.此时我们使用 kubectl get pod -n namespace 就可以看到pod的状态了
二.资源限制
一般是对内存和CPU进行限制
内存单位:
- 使用以下后缀之一作为平均整数或定点整数表示内存:EPTGMK
- 使用两个字母的等效幂数:EiPiTiGiMiKi
- 通俗来讲就是
i表示(1Mi=1024*1024) M表示(1000*1000) 其他单位以此类推 CPU单位:
- 浮点数:0.25(1/4核) 0.5(半核)
- m:0.25=250m 0.5=500m
示例 :node上的资源无法满足pod最低限制资源,pod无法被调度到任何一个node(pending状态)
apiVersion: v1 kind: Pod metadata: name: pod-resource spec: containers: - name: web image: nginx resources: requests: # 容器最小资源配额 memory: "2Gi" cpu: "250m" limits: # 容器最大资源上限(通常是最小配额的1.5倍,具体根据实际业务) memory: "3Gi" cpu: "500m"
验证: Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 45s (x2 over 45s) default-scheduler 0/3 nodes are available: 3 Insufficient memory.
三.nodeSelector
用于将pod调度到匹配label的node上,如果没有匹配到label会调度失败
作用:
- 约束pod到特殊节点上运行
- 完全匹配节点标签
应用场景:
- 专用节点:根据实际项目中的业务线将node分组管理
- 配备特殊硬件:部分node上配有特殊硬件(ssd、gpu等等)
示例: 确保pod分配到带有SSD硬件的节点上
#先带特殊硬件的node打标签 ##格式:kubectl label nodes node-name label-key=label-value
kubectl label nodes k8s-node1 disktype=ssd 验证: NAME STATUS ROLES AGE VERSION LABELS k8s-master Ready master 7d20h v1.19.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/master= k8s-node1 Ready <none> 7d20h v1.19.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux k8s-node2 Ready <none> 7d20h v1.19.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux
#yaml文件里引入
piVersion: v1 kind: Pod metadata: name: pod-nodeselector spec: nodeSelector: disktype: "ssd" containers: - name: web image: nginx
验证:
[root@k8s-master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-nodeselector 1/1 Running 0 13m 10.244.36.98 k8s-node1 <none> <none>
######注意:如果多个node有相同label,scheduler根据其他既定策略进行调度
四.nodeAffinity
nodeAffinity:节点亲和性,与nodeSelector作用一样。但相比更灵活,满足更多条件
- 匹配更多的逻辑组合,不只是字符串的完全相等
- 调度策略分为软策略和硬策略,而不是硬性要求
-
- 硬(required):必须满足
- 软(preferred):尝试满足,但不保证
操作符:In Notin Exists DoesNotExist Gt Lt
示例1:当node中没有标签为gpu=nvidia时,使用nodeAffinity的软策略
apiVersion: v1 kind: Pod metadata: name: pod-affinity-preferred spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 # 权重优先级,字段值的范围是 1-100 preference: matchExpressions: - key: gpu operator: In # 操作字符 values: - nvidia containers: - name: web image: nginx
####weight官网详解:
对于每个符合所有调度要求(资源请求,RequiredDuringScheduling 亲和表达式等)的节点,调度器将遍历该字段的元素来计算总和,并且如果节点匹配对应的MatchExpressions,则添加“权重”到总和。
然后将这个评分与该节点的其他优先级函数的评分进行组合。总分最高的节点是最优选的。
示例2:硬策略(节点标签中带有disktype=ssd)
apiVersion: v1 kind: Pod metadata: name: pod-affinity-required spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disktype operator: In values: - ssd containers: - name: web image: nginx
五.Taints( 污点)与Tolerations(污点容忍)
Taints:避免pod调度到特定node上
Tolerations:允许pod调度到持有Taints的node上
应用场景:
专用节点:根据业务线将node进行分组,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
配备特殊硬件:部分node配有SSD硬盘、GPU。希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
基于Taint的驱逐
# 给节点添加污点
格式:kubectl taint node node-name taintKey=taintValue:[effect]
[root@k8s-master yaml]# kubectl taint node k8s-node1 disktype=ssd:NoSchedule
node/k8s-node1 tainted
[root@k8s-master yaml]# kubectl describe node |grep Tain
Taints: node-role.kubernetes.io/master:NoSchedule
Taints: disktype=ssd:NoSchedule
effect可取值:
NoSchedule:一定不能被调度,零容忍
PreferNoSchedule:尽量不要调度,非必须配置容忍
NoExecute:不仅不会调度,还会驱逐node上已有的pod
# 去掉污点
kubectl taint node [node] key-
# 配置污点容忍 apiVersion: v1 kind: Pod metadata: name: pod-taint spec: tolerations: # 污点容忍配置 - key: "disktype" operator: "Equal" # key = value value: "ssd" effect: "NoSchedule" # 容忍度 containers: - name: web image: nginx
#如果pod中没配置污点容忍,是不能调度到加了污点的节点上的
六.nodename
pod中指定节点名称,用于将pod调度到指定node上,不经过调度器
# 不常用 当scheduler故障需要紧急调度时,可以临时用用
apiVersion: v1 kind: Pod metadata: name: pod6 spec: nodeName: k8s-node1 containers: - name: web image: nginx
############################################################################################################################
影响pod调度的因素:
资源配额resources
根据资源限制调度到node上(如果所有节点都不能满足该pod的最低资源限制,那么该pod将不会被调度)
标签选择器 nodeSelector:根据节点label进行匹配调度,如果匹配不到,则不会调度 nodeAffinity:亲和性调度 分为软硬两种策略,更灵活,匹配逻辑更多
硬required:必须满足
软preferred:尽量满足,但不保证(存在则优先分配,不存在也不强求,按默认策略调度)
污点与污点容忍
taint:打了污点的node,默认不能被调度
tolerations:配置了污点容忍的pod,才能被调度到打了污点的特定node上
nodename:不经过调度器,直接指定node