本篇内容介绍了“Kubernetes 1.8中的Pod怎么创建和应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
创新互联自2013年创立以来,先为繁昌等服务建站,繁昌等地企业,进行企业商务咨询服务。为繁昌企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
【Alpha】支持定义PriorityClass,并指定给Pod来定义Pod Priority;
【Alpha】支持基于Pod Priority的抢占式调度;
【Alpha】Node Controller支持自动根据Node Condition给Node打上对应的Taints;
什么是抢占式调度?
在Kubernetes 1.8版本之前,当集群资源不足时,用户提交新的Pod创建请求后,该Pod会处于Pending状态,直到集群中有某个Node有足够Available Resources时才会调度成功。 从Kubernetes 1.8版本开始,这种情况下scheduler会根据Pod's Priority进行调度,调度时会选择最合适的Node并把该Node上lower Priority的Pods进行Premmption(Eviction)以释放资源供该higher Priority Pod使用。这种调度时考虑Pod Priority的方式就是Kubernetes中的抢占式调度,简称为Preemption。
在Kubernetes 1.8中,Pod Priority和Preemption作为Alpha特性,默认是disable的,如果你要使用该特性,需要给apiserver和scheduler添加如下参数并重启:
kube-apiserver xxx --feature-gates=PodPriority=true --runtime-config=scheduling.k8s.io/v1alpha1=true
kube-scheduler xxx --feature-gates=PodPriority=true
反过来,把上面的参数删除并重启,即可disable。
有个问题:如果我开启了这个特性,并且创建了一些PriorityClass,然后还给某些Pod使用了,这个时候我再disable掉这个特性,会不会有问题?
答案是否定的!disable后,那些之前设置的Pod Priority field还会继续存在,但是并没什么用处了,Preemption是关闭的。当然,你也不能给新的Pods引用PriorityClass了。
Enable后,接下来就是创建PriorityClass了:
apiVersion: scheduling.k8s.io/v1alpha1 kind: PriorityClass metadata: name: high-priority value: 1000000 globalDefault: false description: "This priority class should be used for XYZ service pods only."
注意:PriorityClass是非namespace隔离的,是global的。因此metadata下面是不能设置namespace field的。
apiVersion: scheduling.k8s.io/v1alpha1 # enable的时候需要配置的runtime-config参数;
metadata.name: 设置PriorityClass的名字;
value: 32-bit 整型值,值越大代表优先级越高,但是必须小于等于 1 billion,大于 1 billion的值是给集群内的critical system Pods保留的,表示该Priority的Pod是不能被抢占的。
globalDefault: true or false,注意只能有一个PriorityClass的这个字段为true,如果没有一个PriorityClass的该字段为true,则那些没有明确引用PriorityClass的Pod的Priority value就为最低值0.
description: String,写给人看的备注,Kubernetes不做处理;
注意:
PriorityClass只会影响那些还没创建的Pod,一旦Pod创建完成,那么admission Controller就已经将Pod Spec中应用的PriorityClassName对应的PriorityClass的value设置到Pod的Priority field了。意味着你再修改PriorityClass的任何field,包括globalDefault,也不会影响已经创建完成的Pod。
如果你删除某个PriorityClass,那么不会影响已经引用它的Pod Priority,但你不能用它来创建新的Pod了。这其实是显而易见的。
接下来,就是创建对应Priority的Pod了:
apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent priorityClassName: high-priority
如果Pod.spec. priorityClassName中指定的PriorityClass不存在,则Pod会创建失败;
前面也提到,创建Pod的时候Priority Admission Controller会根据PriorityClassName找到对应的PriorityClass,并将其value设置给Pod.spec.priority。
因为抢占式调度evict低优先级Pod时,有一个优雅终止时间(默认30s),如果该Node上需要evict多个低优先级的Pod,那么可能会需要很长的时间后,最终Pod才能调度到该Node上并启动运行,那么问题来了,这么长时间的过去了,这个Node是否此时此刻还是最适合这个Pod的呢?不一定!而且在大规模且创建Pod频繁的集群中,这种结果是经常的。意味着,当初合正确的调度决定,在真正落实的时候却一定时正确的了。
还不支持preempted pod时考虑PDB,计划会在beta版中实现;
目前premmpted pod时没考虑Pending pod和victims pod的亲和性:如果该pending pod要调度到的node上需要evict的lower Priority pods和该pending pod是亲和的,目前直接evict lower Priority pods就可能会破坏这种pod亲和性。
不支持跨节点抢占。比如pending Pod M要调度到Node A,而该Pending Pod M又与“同Node A一个zone的Node B上的Pod N”是基于zone topology反亲和性的,目前的Alpha版本就会导致Pod M继续Pending不能成功调度。如果后续支持跨界点抢占,就能将lower Priority的Pod N从Node B上evict掉,从而保证了反亲和性。
在Kubernetes 1.8之前,Node Condition是会直接干预调度的,逻辑是是这样的,并且是无法改变的:
kubelet会定期的将Node Condition传给kube-apiserver并存于etcd。
kube-scheduler watch到Node Condition Pressure之后,会根据以下策略,阻止更多Pods Bind到该Node。
Node Condition | Scheduler Behavior |
---|---|
MemoryPressure | No new BestEffortpods are scheduled to the node. |
DiskPressure | No new pods are scheduled to the node. |
- 当Node Condition包含Memory Pressure时,不再允许BestEffort QoS Pods调度到该节点; - 当Node Condition包含DiskPressure时,不允许任何pods调度到该节点。
从Kubernetes 1.6开始,kubelet和Node Controller支持自动根据Node Condition给Node打上相应的内置Taints,当时这些Taints只是会影响kubelet eviction,而不会影响调度。这有啥不同呢?区别就是,给Node打上Taints对调度来说是软限制,可以通过给pods加上对应的Tolerations就可能强制调度到那个节点。而在1.8之前,Node Condition影响调度是硬限制。
Node Condition和Taints的Map关系如下:
ConditionType | Condition Status | Effect | Key |
---|---|---|---|
Ready | True | - | |
False | NoExecute | node.kubernetes.io/notReady | |
Unknown | NoExecute | node.kubernetes.io/unreachable | |
OutOfDisk | True | NoSchedule | node.kubernetes.io/outOfDisk |
False | - | ||
Unknown | - | ||
MemoryPressure | True | NoSchedule | node.kubernetes.io/memoryPressure |
False | - | ||
Unknown | - | ||
DiskPressure | True | NoSchedule | node.kubernetes.io/diskPressure |
False | - | ||
Unknown | - | ||
NetworkUnavailable | True | NoSchedule | node.kubernetes.io/networkUnavailable |
False | - | ||
Unknown | - |
“Kubernetes 1.8中的Pod怎么创建和应用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!