1、Deployment创建流程

- kubectl提交创建Pod,APIServer响应请求,通过一系列的认证授权,把请求数据存储到etcd,并返回状态。
- Controller-Manager通过list-watch机制,检测发现存在未分配的deployment资源,发现该资源没有关联Pod和ReplicaSet,启动Deploument Controller创建ReplicaSet资源,在启用ReplicaSet Controller创建Pod。
- 所有Controller正常后,将Deployment,replicaSet,pod资源信息更新到etcd。
- Scheduler通过list-watch机制,检测发现存在未分配的Pod资源,通过调度算法选择合适的Node进行Pod的绑定。将绑定结果更新的etcd
- kubelet每个20s向kube-apiserver通过NodeName获取自身Node上所要运行的Pod清单,通过与自己的内存缓存进行比较,调用docker api创建容器。
- kubelet获取docker创建容器的状态,并汇报给apiserver,apiserver将Pod信息及状态更新的etcd。
2、影响Pod调度的因素
2.1、资源限制对Pod调度的影响
2.1.1、容器最大资源限制
- resources.limits.cpu
限制Pod最大允许使用CPU,CPU单位为m,也可以写为浮点数,例如0.5=500m,1=1000m - resources.limit.memory
限制Pod最大允许使用的内存,内存单位为Mi、Gi
2.1.2、容器(最小)初始资源请求
- resource.requests.cpu
指定Pod创建时最小请求的CPU大小 - resource.requests.memory
限制Pod创建时最小请求的内存大小
2.1.3、资源限制示例
创建一个具有一个容器的 Pod。容器将会请求 0.5 个 CPU,而且最多限制使用 1 个 CPU,请求128Mi内存,最多限制使用512Mi
apiVersion: v1kind: Podmetadata:name: cpu-demonamespace: cpu-examplespec:containers:- name: cpu-demo-ctrimage: nginxresources:limits: # 最大资源限制cpu: "1"memory: "512Mi"requests: # 初始请求资源cpu: "0.5"memory: "128Mi"
2.1.4、资源限制总结
资源限制包括CPU和内存对Pod调度的影响。
- 如果指定限制条件,则会计算node节点是否满足Pod对资源的需要,如果不满足,则不会调度到此Node上。
- 如果不指定限制条件,会发生以下情况之一。
- 容器可以使用所有CPU资源。
- 容器运行在有默认CPU限制的命名空间中,系统会自动为容器设置资源限制。
- 如果设置了最大资源限制但没有设置初始资源请求,K8S会自动设置与最大限制相同的请求值。
- 如果容器初始资源请求超过Node空闲资源,则Pod会处于Pending状态,直到满足条件。
2.2、nodeSelector
nodeSelector是影响Pod调度最简单的方式,通过对node添加标签label的方式,来选择Pod创建在哪个节点上。
2.2.1、nodeSelector示例
- 添加标签label到node
# 给节点添加disktype为ssd的标签
kubectl label nodes k8s-slave1 disktype=ssd
# 查看node标签
kubectl get nodes --show-labels
- 创建Pod是指定node标签
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector: # 选择nodeSelector
disktype: ssd
此时创建的Pod只会在k8s-slave1上运行。
2.3、nodeAffinity
节点亲和性类似于nodeSelector,可以根据节点上的标签来约束Pod可以调度到哪些节点。相比于nodeSelector。
- 匹配支持更多的逻辑组合,不只是字符串的完全相等,支持的操作符有
- In、NotIn、Exists、DoesNotExist、Gt、Lt
- 和nodeSelector完全匹配的硬性要求不同,调度分为软策略和硬策略
- 硬(required):必须满足
- 软(preferred):尝试满足,但不保证
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略,必须满足
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
preferredDuringSchedulingIgnoredDuringExecution: # 软策略,不保证满足
- weight: 1 # 权重值,1-100,权重越大,调度到匹配节点的可能性越大。
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: with-node-affinity
image: k8s.gcr.io/pause:2.0
2.4、Taint(污点)与Tolerations(污点容忍)
Taint与节点亲和性相反,它使节点能够排斥一类特定的Pod。
2.4.1、Taint
避免Pod调度到指定的Node上
2.4.1.1、污点常用指令
- 给节点添加污点。
kubectl taint nodes [node] key=value:[effect]
[effect]可取值为:- NoSchedule:一定不能被调度
- PreferNoSchedule:尽量不要被调度,非必须配置容忍
- NoExecute:不仅不会调度,还会驱逐Node上已有的Pod
# 给节点k8s-node1增加一个污点,键名为key1,值为value1,效果为NoSchedule。表示只有拥有和这个污点想匹配容忍度的Pod才能被分配到这个节点。
kubectl taint nodes k8s-node1 key1=value1:NoSchedule
- 移除节点上的污点
kubectl taint nodes k8s-node1 key1=value1:NoSchedule-
- 查看节点上的污点
[root@k8s-master resource]# kubectl describe node |grep Taint
Taints: node-role.kubernetes.io/master:NoSchedule
Taints: key1=value1:NoSchedule
Taints: <none>
2.4.1.2、污点调度示例
- 创建deployment,查看调度情况
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 6
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx
name: nginx
resources: {}
执行kubectl apply -f taint.yaml后,可以发现所有Pod均调度到node2上。
2.4.2、Tolerations
允许Pod调度到指定Taints的Node上,并非一定会调度到指定的Node上。Taint和tolerations相互配合,可以用来避免Pod被分配到不合适的节点上。
2.4.2.1、污点容忍示例
- 创建deployment,配置污点容忍,查看调度情况
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 6
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
tolerations:
- key: "key1" # 容忍key
operator: "Equal" # 键值比对选项
value: "value1" # 值
effect: "NoSchedule"
containers:
- image: nginx
name: nginx
resources: {}
operator默认值为Equal
- 如果operator为Exists,表示只要存在和key相同的污点或相同污点调度策略则允许调度。为Exists时,不能存在value
- 如果operator为Equal,则污点容忍要与value相等。
两种特殊情况:
- 如果一个容忍度的key为空且operator为Exists,表示这个容忍度与任意的key、value、effect都匹配,即这个容忍度可以容忍任意污点。
- 如果effect为空,则和所有key1的节点相匹配。
执行kubectl apply -f talerations.yaml后,可以发现node1和node2均会调度Pod。
2.5、nodeName
指定节点名称,用于将Pod调度到指定Node上,不经过调度器,不会受调度策略的影响。
使用nodename字段选择节点的一些限制“
- 如果指定的节点不存在。
- 如果指定的节点没有资源容纳Pod,Pod会调度失败。
- 节点名称变化的情况。
