目录
pod优先级调度(pod Priority Preemption)
pod资源调度
很少情况下我们会去直接创建一个Pod,大多数情况下我们都是通过RC,deployment,daemonSet等等完成一组Pod的创建,调度。 早期只有一个副本控制器RC,它通过label与Pod之家建立松耦合的关系。主要实现的是Pod的创建于销毁。而后其继承者deployment的出现,改进了RC,deployment可以时间Pod副本的创建,销毁,版本更新,回滚等功能,其实在在rc与deployment之间还有一个中间版本的出现是replicaSet(rs),rs来自于rc,deployment则来自于rs。所有的控制器都是通过副本的方式进行。保证副本的数量既保证服务能够正常提供服务。一个Pod管理器至少含有三个部分标签选择,副本控制,模板。
Replication controller(RC)
最早时期 的副本控制器,负责创建Pod,保证Pod副本的数量,以及调度,在kubernetes1.2版本之后没有再进行使用.取代它的而是的replicaSet。但是它是pod控制器的最初形式,其基本概念贯穿整个pod控制器。主要三个部分:标签选择selector ,模板template, 副本控制replicas
ReplicaSet
ReplicaSet在RC 相对于RC进一步增强了标签选择。不同版本的标签控制等功能。实际运用当中,没有直接去使用RS。而是使用的Deployment这个更高级的资源管理
selector支持两种选择matchLabels和matchExpresssions,使得标签的选择更加的灵活,多个的标签存在时,管理器管理选择的Pod的逻辑关系为“与”,多个标签同时满足时,才会标记到指定的pod。
示例:
apiVersion:apps/v1
kind: ReplicaSet
#控制的器的metadata
metadata:
name:myapp
namespace: default
labels:
name: myapp
#控制器的spec
spec:
replicas:2
selector:
matchLables:
app: myapp
release: canary
#pod的模板
template:
#pod的metadata
metadata:
name: rs-pod
labels:
app: myapp
release: canary
#pod内容器的容器的配置
spec:
containers:
- name: rs-contianer
image: busybox
运行结果:创建了一个名称为myapp的rs控制器,控制器下控制了两个pod,myapp-78qsj与myapp-ctwfc,后面的字符为控制器的自动的生成。
扩容与缩容
扩容与缩容本质为修改YAML文件当中的replicas参数的即可。使用命令:
#直接编辑YAML文件,或使用edit编辑控制器都可以实现。建议使用edit进行编辑。
kubectl edit rs Deployment_name
示例:
...........
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: canary
...........
..
#显示结果
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness 0/1 CrashLoopBackOff 607 16d
myapp-78qsj 0/1 CrashLoopBackOff 91 7h25m
myapp-ctwfc 0/1 Completed 92 7h25m
myapp-wbngr 0/1 CrashLoopBackOff 1 6s
#pod副本数量的增加到3个
版本更新
编辑YAML文件
...........
spec:
containers:
- image: busybox:v1
imagePullPolicy: IfNotPresent
........
查看结果:
[root@master ~]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myapp 3 3 0 7h37m myapp-container busybox:v1 app=myapp,release=canary
这个时候pod当中的容器使用的镜像的版本还是原来,更新使用的是灰度发布的流程。只有当正在使用原始版的pod失败的时候。新的版本就会将其替代。可以使用kubectl delete 删除一个pod,自然新的pod就会进行替代。
rs总结:
1,通过selector方式实现对对应标签副本的控制
2,通过replicas参数进行自动的扩容与缩容
3,通过image参数实现版本的更新。
apiverion:
kind:
metadata:
name:
namespace:
#POD控制器的标签
labels:
spec:
replicas:
selector:
matchlabels:
template:
#pod的基本信息
metadata:
name:
#可以不写,默认匹配的是和控制器的相同的namespace
namespace:
#这里的labe标签与selector选择器的标签一致,这样pod控制的器才能对pod资源进行控制。
labels:
#pod内容器的相关的配置
spec:
containers:
- name:
image:
ports:
- name:
containerPort:
Deployment
Deployment内部其实是通过RS实现的,但是在rs之上对容器的编排方式进行升级。Deployment对象通过管理rs,rs管理pod实现pod资源的控制。
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dp-daemon
namespace: default
labels:
name: mydp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
name: my-pod
labels:
app: myapp
release: canary
spec:
containers:
- name: my-container
image: busybox
显示结果:
[root@master ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
dp-daemon 0/1 1 0 3m14s
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
dp-daemon-664c8574bf 1 1 0 3m23s
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dp-daemon-664c8574bf-wnxpx 0/1 CrashLoopBackOff 1 3m31s
liveness 0/1 CrashLoopBackOff 616 16d
结果显示deployment创建了一个rs,创建了一个pod。
扩容与缩容
修改YAML文件当中的replicas
kubectl edit deploy deployment_name
.....
replicas:3
.....
#结果 显示
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dp-daemon-664c8574bf-6hqdd 0/1 CrashLoopBackOff 1 29s 10.244.2.5 node02 <none> <none>
dp-daemon-664c8574bf-n5xp2 0/1 CrashLoopBackOff 1 29s 10.244.1.5 node01 <none> <none>
dp-daemon-664c8574bf-wnxpx 0/1 CrashLoopBackOff 14 12h 10.244.2.4 node02 <none> <none>
liveness 0/1 CrashLoopBackOff 634 16d 10.244.1.3 node01 <none> <none>
版本升级与回滚
升级
编辑yaml文件当
#修改yaml文件的镜像版本
.....
image:busybox:v1
.....
#查看升级过程
kubectl rollout status deloyment/dp-damon
[root@master ~]# kubectl rollout status deployment/dp-daemon
Waiting for deployment "dp-daemon" rollout to finish: 1 out of 3 new replicas have been updated...
更新过程:可以使用kubctl describe deployment/dp-deamon查看详细的更新过程
1,修改之后,系统会创建一个新replicaSet,并将副本数量扩容1个。
2,将原本的副本数量减少1个,之后延续之前的步骤,直到版本都更新完成
这个过程由strategy控制
#deployment.spec.strategy
更新策略分为两类:recreate(重建)与rollingout,默认的策略我rollingout
recreate:在进行更新的时候,会先杀掉所有deployment所控制的pod,然后再进行更新。
rollingout:通过对pod以滚动的方式的进行更新,
其中两个重要的参数为:
maxUnavaiilble:更新过程当中最大的不可用的副本数量上限,数值可以是数值的绝对值或者是百分比。确保在更新过程当中可用的数量。
maxSurge:更新过程当中副本的最大数上限
-----------
.....
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
........
注意:当上次更新正在进行时,deployment再次更新,新的replicaSet会被创建,之前的正在执行的replicaSet停止扩容。并将其将其加入旧replicaSet列表当中。
回滚
查看deploymen部署的历史记录:
kubectl rollout history
--------------
回滚
kubectl rolldout undo deployment/deployment_name --version=STRING
暂停与恢复
当修改的deployment过复杂时,为了避免触发deployment更新,我们可以暂停deploy的更新过程,修改配置之后在进行更新。
命令:
#暂停
kubectl rollout pause deployment/dp-daemon
#修改
kubectl set image deployment/dp-daemon --image=busybox:v1
DeamonSet
Deamonset确保一个node节点上只运行一个pod副本。主要实例为日志系统,集群存储,集群监控。管理机制与rc相同。
示例:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds
namespace: default
labels:
name: ds
spec:
selector:
matchLabels:
app: ds
template:
metadata:
name: ds-pod
labels:
app: ds
spec:
containers:
- name: ds-container
image: busybox
版本升级
DaemonSet的updatestrategy支持两种方式
1,onDelete:更新版本之后,DaemonSet不会创建新的pod,只有当旧的pod删除之后才会创建。
2,rollingUpdate:版本更新之后,旧的pod会立即被删除,新的pod会进行取代。
#deamonset.spec.updateStrategy
spec:
......
updateStrategy:
#默认选择的策略是onDelete
type: [rollingUpdate|onDelete]
rollingUpdate:
maxUnavailable:[数字或者百分比]
......
小结
1,pod资源调度的方式:rc,rs,deployment,daemonSet,还有statefullSet有状态pod,批处理job,cronjob。
2,pod调度清单当中主要的三个属性:replicas,selector, template。
3,版本的更新方式主要是修改yaml文件,或使用命令进行修改。不同的管理器使用的strategy的方式不同,Deployment有:recreate与rollingUpdate,Daemonset有ondelete,rollingUpdate。
4,更新策略当中rollingupdate在Deloyment当中与DaemonSet当中不同,Deployment当中表示:灰度发布,DaemonSet当中表示:立即停用pod,更新到最新版本的pod。其中有两点个参数:maxUnavailable与maxSurge,DamonSET的rollingupdate只有maxUnavailable
pod资源调度优化
定向调度(NodeSeletor)
将pod调度到指定的节点上,可以通过Node的标签与NodeSelector属性进行匹配,达到定向调度的目的。
节点标签设置:
kubectl label nodes node_name key=value
#pod.spec.nodeSelector
....
spec:
....
template:
....
nodeSelector:
diskType: ssd
.....
亲和度(Affinity)
节点亲和度调度(NodeAffinity)
节点亲和调度策略分为两种:
preferredDuringSchedulingIgnoredDuringExecution:必须满足规则才会调度到pod到node节点上
requiredDuringSchedulingIgnoredDuringExecution:强调权重,根据权重调度到节点上。
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- key:
operator: [In|NotIn|Exists|DoesExists|Gt|Lt]
values:
perferredDuringSchedulingIgnoredDuringExection:
weigt:[1-100]
preference:
- key:
operator: [In|NotIn|Exists|DoesExists|Gt|Lt]
values:
-----------------------------
In: label的值在node的label列表中
NotIn:label的值不在node的label列表中
Exists:label的值存在于node的label
DoesNotExist:label的值不存在node的label
Gt:label的值大于node的label列表当中label值(之间做字符串大小比较)
Lt:label的值小于node的label列表label值(之间做字符串大小比较)
requiredDuringSchedulingIgnoredDuringExecution示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: node-affinity-daemon
namespace: default
labels:
name: node-affinity-damon
spec:
replicas: 1
selector:
matchLabels:
app: affinity
template:
metadata:
name: affinity-pod
labels:
app: affinity
spec:
containers:
- name: affinity-continer
image: busybox
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
-----------------
[root@master mainfest]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master Ready master 35d v1.16.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
node01 Ready <none> 35d v1.16.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux
node02 Ready <none> 35d v1.16.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux
[root@master mainfest]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liveness 0/1 CrashLoopBackOff 867 18d 10.244.1.3 node01 <none> <none>
node-affinity-daemon-5c94dc9796-rfsd5 0/1 CrashLoopBackOff 1 87s 10.244.1.8 node01 <none> <none>
#这个pod调度到了含有标签disktype=ssd的node01 上
pod亲和度调度(podAffinity)
pod亲和性在进行判断之前,需要建立pod是否在同一个区域标准。对应参数:topologyKey
#pod更倾向与运行在一起
podAffinity <Object>
preferredDuringSchedulingIgnoredDuringExecution <[]Object>(倾向)
- podAffinityTerm <object>
labelSeletor <object>:
namespace <string>:
#拓扑关键字
topologyKey<string>:
weight:[integer]
requiredDuringSchedulingIgnoredDuringExecution <[]Object>(必须)
- labelSelector:
namespace:
topologyKey:
pod互斥调度(podAntiAffinity)
#pod倾向于与那些pod分开运行(不倾向于)
podAntiAffinity <Object>
- podAffinityTerm <object>
labelSeletor <object>:
namespace <string>
#位置拓扑关键字
topologyKey<string>:
weight:[integer]
requiredDuringSchedulingIgnoredDuringExecution <[]Object>(必须)
- labelSelector:
namespace:
topologyKey:
污点与容忍度(Taints AND Toleration)
污点:定义在node上的键值数据。属于node属性。pod定义对node的污点的容忍度。
污点的管理
kubectl taint NODE NAME KEY_1=VAL_1:TAINT_EFFECT_1 ... KEY_N=VAL_N:TAINT_EFFECT_N [options]
#node创建污点:
kubctl taint node node01 node_production=production:NoSchedule
#node删除污点
kubectl taint node node01 node_production-
node节点污点属性: node.spec.taints
#对pod排斥等级effect
<string>:
1,NoSchedule:不能调度,仅影响调度过程。对现有的pod不影响。
2,PreferNoSchedule:一般不能调度,但是没有其他节点可以调度可以调度到本node,仅影响调度过程。对现有的pod不影响。
3,NoExecute:不能调度,当污点属性改变时,对原有的pod也会产生排斥。
taints<[]object>
- effect <string> --required--:
key <string> --required--:
value <string>:
pod容忍度
pod是否能够容忍node上面存在污点
#pod.spec.tolerations
tolerations <[]object>
- effect: [NoSchedule|PreferNoschedule|NoExcute]
key:<srting>
# operator:{Exists|Equal}
operate:<string>
tolerationSeconds:<integer>
value:<string>
---
Equal: pod容忍的node节点上的污点值与自己的指定的value相同
Exsits:node存在污点即可,无需指定其value值。
pod优先级调度(pod Priority Preemption)
作用:中大规模的集群的集群当中可能会出现超负荷的运作。这个时候需要释放掉一些系统资源。这个时候需要对资源的有限级进行一个设定,有限级不高的资源先释放减轻系统负荷。
#优先级类定义
优先级类不属于任何的namspace,独立的存在,服务可以对其进行调用。
#kubectl explain priorityClass
---
apiVersion: Schedule.k8s.io/v1
kind: PriorityClass
metadata:
name: highPriority
value: 10000
#当一个pod没有有限级时是否将其设置为优先级。
globalDefault:False
description: "this is a high priorityClass"
---
#pod使用优先级策略
apiVersion: v1
kind: Pod
metadata:
name: app
namespace: default
spec:
containers:
- name: app
image: nginx
imagePullPolicy: IfNotPresent
priorityClassName: highPriority