k8s 调度器

Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:

  • 公平:如何保证每个节点都能被分配资源
  • 资源高效利用:集群所有资源最大化被使用
  • 效率:调度的性能要好,能够尽快地对大批量的 pod 完成调度工作
  • 灵活:允许用户根据自己的需求控制调度的逻辑
    Sheduler 是作为单独的程序运行的,启动之后会一直监听 API Server,获取 PodSpec.NodeName 为空的 pod,对每个 pod 都会创建一个 binding,表明该 pod 应该放到哪个节点上

K8s调度策略

deployment:全自动调度

Deployment的主要功能之一就是自动部署一个容器应用的多份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。从调度策略上来说,Pod由系统全自动完成调度。它们各自最终运行在哪个节点上,完全由Master的Scheduler经过一系列算法计算得出,用户无法干预调度过程和结果。除了使用系统自动调度算法完成一组Pod的部署,Kubernetes也提供了多种丰富的调度策略,用户只需在Pod的定义中使用NodeSelector、NodeAffinity、PodAffinity、Pod驱逐等更加细粒度的调度策略设置,就能完成对Pod的精准调度。

NodeSelector:定向调度

Kubernetes Master上的Scheduler服务(kube-scheduler进程)负责实现Pod的调度,整个调度过程通过执行一系列复杂的算法,最终为每个Pod都计算出一个最佳的目标节点,这一过程是自动完成的,通常我们无法知道Pod最终会被调度到哪个节点上。在实际情况下,也可能需要将Pod调度到指定的一些Node上,可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,也可以直接在Pod.spec.NodeName直接指定node名称来达到上述目的。

首先查看node的标签

[root@master ~]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master Ready control-plane,master 46h v1.21.0 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/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
node1 Ready <none> 46h v1.21.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node1,kubernetes.io/os=linux
node2 Ready <none> 46h v1.21.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux

给node2打上一个标签

[root@master ~]# kubectl label node node2 app=nginx
node/node2 labeled
[root@master ~]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master Ready control-plane,master 46h v1.21.0 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/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
node1 Ready <none> 46h v1.21.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node1,kubernetes.io/os=linux
node2 Ready <none> 46h v1.21.0 app=nginx,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux

创建一个yaml,定义selector让5个pod都运行在标签为app=nginx的node2之上

[root@master ~]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
namespace: default
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
name: mypod
namespace: default
labels:
app: nginx
spec:
nodeSelector: #node标签选择
app: nginx
containers:
- name: nginx
image: nginx
ports:
- name: http
containerPort: 80

执行yaml,查看pod发现,5个pod都运行在node2节点上,这是因为只有node2有app=nginx的标签,所以pod都创建到node2上面了。

[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-nginx-6c5ccc4cb9-c2htc 1/1 Running 0 26s 10.244.104.13 node2 <none> <none>
deployment-nginx-6c5ccc4cb9-f8hln 1/1 Running 0 26s 10.244.104.11 node2 <none> <none>
deployment-nginx-6c5ccc4cb9-jdh5z 1/1 Running 0 26s 10.244.104.15 node2 <none> <none>
deployment-nginx-6c5ccc4cb9-qwlmx 1/1 Running 0 26s 10.244.104.12 node2 <none> <none>
deployment-nginx-6c5ccc4cb9-xnqhx 1/1 Running 0 26s 10.244.104.14 node2 <none> <none>

也可以直接指定NodeName来完成定向调度,比如通过指定Node Name我们定向调度到node1上

[root@master ~]# cat deployment2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
namespace: default
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
name: mypod
namespace: default
labels:
app: nginx
spec:
nodeName: node1
containers:
- name: nginx
image: nginx

执行yaml,并查看pod

[root@master ~]# kubectl apply -f deployment2.yaml
deployment.apps/deployment-nginx created
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-nginx-8c459867c-4fw9q 0/1 ContainerCreating 0 5s <none> node1 <none> <none>
deployment-nginx-8c459867c-ccbkz 0/1 ContainerCreating 0 5s <none> node1 <none> <none>
deployment-nginx-8c459867c-cksqd 0/1 ContainerCreating 0 5s <none> node1 <none> <none>
deployment-nginx-8c459867c-mrdz4 0/1 ContainerCreating 0 5s <none> node1 <none> <none>
deployment-nginx-8c459867c-zt8n8 0/1 ContainerCreating 0 5s <none> node1 <none> <none>

NodeAffinity:Node亲和性调度

NodeAffinity意为Node亲和性的调度策略,是用于替换NodeSelector的全新调度策略。目前有两种节点亲和性表达。

  • RequiredDuringSchedulingIgnoredDuringExecution:必须满足指定的规则才可以调度Pod到Node上(功能与nodeSelector很像,但是使用的是不同的语法),相当于硬限制。
  • PreferredDuringSchedulingIgnoredDuringExecution:强调优先满足指定规则,调度器会尝试调度Pod到Node上,但并不强求,相当于软限制。多个优先级规则还可以设置权重(weight)值,以定义执行的先后顺序。

我们定义一个affinity.yaml文件,里面定义一个5个pod,定义requiredDuringSchedulingIgnoredDuringExecution让pod调度至node2上

[root@master ~]# cat affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-affinity
namespace: default
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
name: mypod
namespace: default
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
affinity: #调度策略
nodeAffinity: #node亲和性调度
requiredDuringSchedulingIgnoredDuringExecution: #硬限制,必须满足条件
nodeSelectorTerms:
- matchExpressions:
- key: app #node标签的键名
operator: In #In表示,必须在含有定义的标签的node上创建,NotIn表示不能在含有定义标签的node上创建pod
values:
- nginx #node标签键值

执行yaml,查看pod

[root@master ~]# kubectl apply -f affinity.yaml
deployment.apps/deployment-affinity created
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-affinity-5787c89c6b-crpwk 1/1 Running 0 23s 10.244.104.18 node2 <none> <none>
deployment-affinity-5787c89c6b-dpq45 1/1 Running 0 23s 10.244.104.20 node2 <none> <none>
deployment-affinity-5787c89c6b-g9zvg 1/1 Running 0 23s 10.244.104.16 node2 <none> <none>
deployment-affinity-5787c89c6b-kbjsh 1/1 Running 0 23s 10.244.104.17 node2 <none> <none>
deployment-affinity-5787c89c6b-n4d92 1/1 Running 0 23s 10.244.104.19 node2 <none> <none>

可以查看到pod都创建在node2上面,如果将yaml文件中的operator改为NoteIN,则不会在node2上面创建,再定义一下软限制,软限制会有权重值,pod创建时会优先满足软限制,当软限制不满足的时候也能被创建,是非必须满足项。软限制可以和硬限制配合使用,首先要满足应策略,在尽可能满足软策略。

[root@master ~]# cat affinity1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-affinity
namespace: default
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
name: mypod
namespace: default
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: app
operator: NotIn
values:
- nginx

执行yaml,查看pod

[root@master ~]# kubectl apply -f affinity1.yaml
deployment.apps/deployment-affinity created
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-affinity-d495775f4-8sft6 1/1 Running 0 20s 10.244.166.144 node1 <none> <none>
deployment-affinity-d495775f4-dkt8z 1/1 Running 0 20s 10.244.166.143 node1 <none> <none>
deployment-affinity-d495775f4-lfppv 1/1 Running 0 20s 10.244.166.145 node1 <none> <none>
deployment-affinity-d495775f4-nmgz5 1/1 Running 0 20s 10.244.104.21 node2 <none> <none>
deployment-affinity-d495775f4-pzf2p 1/1 Running 0 20s 10.244.166.146 node1 <none> <none>

因为是非必须满足条件,所以也会在node2上创建pod。

yaml中的operator值运算关系有以下几种:

  • In:必须满足这个标签
  • NotIn:必须不满足这个标签
  • Exists:标签必须存在
  • DoesNotExist:标签必须不存在
  • Gt:标签的值大于定义的值,比如定义的值为4,那么必须在标签大于4的node上创建pod
  • Lt:标签的值小于定义的值,比如定义的值为4,那么必须在标签小于4的node上创建pod

NodeAffinity规则设置的注意事:

  • 如果同时定义了nodeSelector和nodeAffinity,那么必须两个条件都得到满足,Pod才能最终运行在指定的Node上。
  • 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个能够匹配成功即可。
  • 如果在nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有matchExpressions才能运行该Pod。

PodAffinity:pod亲和性和反亲和性

pod亲和性根据在node上正在运行的Pod的标签而不是node的标签进行判断和调度,要求对node和Pod两个条件进行匹配。这种规则可以描述为:如果在具有标签X的Node上运行了一个或者多个符合条件Y的Pod,那么Pod应该运行在这个Node上。(如果是互斥的情况,那么就变成拒绝)

和节点亲和相同,Pod亲和与互斥的条件设置也是

  • requiredDuringSchedulingIgnoredDuringExecution:硬限制
  • preferredDuringSchedulingIgnoredDuringExecution:软限制

首先创建一个pod,给pod打上标签,version=V1,app=nginx

[root@master ~]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
version: V1
app: nginx
name: nginx-pod1
spec:
containers:
- image: nginx
name: nginx
restartPolicy: Always

创建pod并查看pod以及labels

[root@master ~]# vim pod1.yaml
[root@master ~]# kubectl apply -f pod1.yaml
pod/nginx-pod1 created
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod1 1/1 Running 0 13s 10.244.166.147 node1 <none> <none>
[root@master ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-pod1 1/1 Running 0 9m7s app=nginx,version=V1

下面创建第2个Pod来说明Pod的亲和性调度,这里定义的亲和标签是version=V1,对应上面的nginx-pod1,topologyKey的值被设置为“kubernetes.io/hostname” (node1的标签值)

[root@master ~]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod2
spec:
containers:
- image: nginx
name: nginx
restartPolicy: Always
affinity: #调度策略
podAffinity: #pod亲和性调度
requiredDuringSchedulingIgnoredDuringExecution: #硬限制,必须满足条件
- labelSelector: #pod标签
matchExpressions:
- key: app #pod标签的键名
operator: In #In表示,必须跟已创建pod相同标签的node上创建
values:
- nginx #node标签键值
topologyKey: kubernetes.io/hostname #node标签的键名

执行yaml,查看pod

[root@master ~]# kubectl apply -f pod2.yaml
pod/nginx-pod2 created
[root@master ~]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod1 1/1 Running 0 29m 10.244.166.147 node1 <none> <none>
nginx-pod2 1/1 Running 0 75s 10.244.166.148 node1 <none> <none>

此时nginx-pod2也被创建到node1上面,下面创建nginx-pod3,演示反亲和调度。

[root@master ~]# cat pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod3
spec:
containers:
- image: nginx
name: nginx
restartPolicy: Always
affinity:
podAntiAffinity: #pod非亲和性调度
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: version
operator: In
values:
- V1
topologyKey: kubernetes.io/hostname

执行yaml,查看pod,发现nginx-pod3被创建到了node2上。

[root@master ~]# kubectl delete -f pod3.yaml
pod "nginx-pod3" deleted
[root@master ~]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod1 1/1 Running 0 56m 10.244.166.147 node1 <none> <none>
nginx-pod2 1/1 Running 0 27m 10.244.166.148 node1 <none> <none>
nginx-pod3 1/1 Running 0 6s 10.244.104.22 node2 <none> <none>

Taints和Tolerations:污点和容忍

前面介绍了NodeAffinity节点亲和性,是在pod上定义的一种属性,使得Pod能够被调度到某些Node节点上运行(优先选择或强制要求)Taint则正好相反,它让Node拒绝Pod运行。

Taint要与Toleration配合使用,让Pod避开那些不适合的Node,在Node上设置一个或者多个Taint之后,除非Pod明确生命能够容忍这些污点,否则无法在这写Node节点上运行,Tolerations是Pod属性,让Pod能够(注意,只是能够,而非必须)运行标注了Taint的Node上

使用kubectl taint命令可以给某个node打上污点,node被打上污点后与pod之间存在一种相斥的关系,可以让node拒绝pod的调度执行,甚至将node上已存在的pod驱逐出去。

污点的组成如下:

key=value:effect

每个污点有一个key和value作为污点的标签,其中value可以为空,effect描述 污点的作用。当前Taints的effect支持如下三个选项:

  • NoSchedule:表示K8s不会将pod调度到具有该污点的node上
  • PreferNoSchedule:表示K8s尽量避免将pod调度到具有该污点的node上
  • NoExecute:表示K8s不会将pod调度到具有该污点的node上,同时会将node上已经存在的pod驱逐出去

我们在node2上面打上污点

[root@master ~]# kubectl taint node node2 node=nginx:NoSchedule
node/node2 tainted

我们可以通过describe查看node2的污点信息

[root@master ~]# kubectl describe node node2 | grep Taints
Taints: node=nginx:NoSchedule

当我们再创建pod时,将不会在node2上面创建了

[root@master ~]# cat deployment1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
namespace: default
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
name: mypod
namespace: default
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx

执行yaml创建pod看一下

[root@master ~]# kubectl apply -f deployment1.yaml
deployment.apps/deployment-nginx created
[root@master ~]# kubectl get pod -o wide
deployment-nginx-5b45c89ccd-gmw9h 1/1 Running 0 29s 10.244.166.149 node1 <none> <none>
deployment-nginx-5b45c89ccd-gs6f2 1/1 Running 0 29s 10.244.166.153 node1 <none> <none>
deployment-nginx-5b45c89ccd-nqvnh 1/1 Running 0 29s 10.244.166.151 node1 <none> <none>
deployment-nginx-5b45c89ccd-nwss7 1/1 Running 0 29s 10.244.166.150 node1 <none> <none>
deployment-nginx-5b45c89ccd-p8wc2 1/1 Running 0 29s 10.244.166.152 node1 <none> <none>

此时我们看到pod全部创建在node1上,我们再将容忍Tolerations加到yaml里看一下

[root@master ~]# cat deployment1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
namespace: default
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
name: mypod
namespace: default
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
tolerations: #容忍
- key: "node" #匹配的污点键名,必须与node设置的保持一致
operator: "Equal" #容忍的关系,Equal表示必须与Taine的value保持一致,Exists可以不指定value。
value: "nginx" #匹配的污点键值,必须与node设置保持一致
effect: "NoSchedule" #匹配的污点属性,必须与node设置保持一致
说明:
当operator不设置时默认值为Equal,当operator设置为Exists时,空的key能匹配所有的键和值表示容忍所有的污点key值,空的effect能匹配所有的规则,表示容忍所有的污点规则。

执行yaml查看pod

[root@master ~]# kubectl apply -f deployment1.yaml
deployment.apps/deployment-nginx created
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-nginx-5db6cb544c-49fvf 1/1 Running 0 27s 10.244.166.154 node1 <none> <none>
deployment-nginx-5db6cb544c-4z82r 1/1 Running 0 27s 10.244.166.156 node1 <none> <none>
deployment-nginx-5db6cb544c-m57w8 1/1 Running 0 27s 10.244.104.24 node2 <none> <none>
deployment-nginx-5db6cb544c-mswfk 1/1 Running 0 27s 10.244.104.23 node2 <none> <none>
deployment-nginx-5db6cb544c-xfsnm 1/1 Running 0 27s 10.244.166.155 node1 <none> <none>

查看pod发现仍然会有pod调度到node2节点,是因为虽然node2上有污点,但是我们设置了容忍,允许有pod创建到有污点的node2上面。

当运行的K8s集群中需要维护单独的node时,我们可以将这个node打上一个NoExecute污点,这样没有设置容忍的pod就会被驱离,便于我们的维护。

以上面的yaml为例,我们在node1上面打一个NoExecute污点:

[root@master ~]# kubectl taint node node1 pod=status:NoExecute
node/node1 tainted
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-nginx-5db6cb544c-jxsqc 0/1 ContainerCreating 0 18s <none> node2 <none> <none>
deployment-nginx-5db6cb544c-m57w8 1/1 Running 0 24m 10.244.104.24 node2 <none> <none>
deployment-nginx-5db6cb544c-m9rm9 0/1 ContainerCreating 0 18s <none> node2 <none> <none>
deployment-nginx-5db6cb544c-mswfk 1/1 Running 0 24m 10.244.104.23 node2 <none> <none>
deployment-nginx-5db6cb544c-ztl2h 0/1 ContainerCreating 0 18s <none> node2 <none> <none>

当我们在node1打上NoExecute污点后,可以看到之前在node1的pod全部被驱离,由于pod类型时deployment,所以又在node2节点创建了新的pod,保证了副本数的完整性。

如果要删除taint,只需要在后面加上“-”符号就可以了

[root@master ~]# kubectl taint node node1 pod=status:NoExecute-
node/node1 untainted

Pod Priority Preemption:Pod优先级调度

对于运行各种负载(如Service、Job)的中等规模或者大规模的集群来说,出于各种原因,我们需要尽可能提高集群的资源利用率。而提高资源利用率的常规做法是采用优先级方案,即不同类型的负载对应不同的优先级,同时允许集群中的所有负载所需的资源总量超过集群可提供的资源,在这种情况下,当发生资源不足的情况时,系统可以选择释放一些不重要的负载(优先级最低的),保障最重要的负载能够获取足够的资源稳定运行。

优先级抢占调度策略的核心行为分别是驱逐(Eviction)与抢占(Preemption),这两种行为的使用场景不同,效果相同。Eviction是kubelet进程的行为,即当一个Node发生资源不足(under resource pressure)的情况时,该节点上的kubelet进程会执行驱逐动作,此时Kubelet会综合考虑Pod的优先级、资源申请量与实际使用量等信息来计算哪些Pod需要被驱逐;当同样优先级的Pod需要被驱逐时,实际使用的资源量超过申请量最大倍数的高耗能Pod会被首先驱逐。对于QoS等级为“Best Effort”的Pod来说,由于没有定义资源申请(CPU/Memory Request),所以它们实际使用的资源可能非常大。Preemption则是Scheduler执行的行为,当一个新的Pod因为资源无法满足而不能被调度时,Scheduler可能(有权决定)选择驱逐部分低优先级的Pod实例来满足此Pod的调度目标,这就是Preemption机制。

Pod优先级调度示例如下。

首先,由集群管理员创建PriorityClasses,PriorityClass不属于任何命名空间:

apiVersion: scheduling.k8s.io/v1beta1
kind: PriorityClass
metadata:
name: high-priority
value: 100000
globaDefault: false
description: "This priority class should be used for XYZ service pods only"

上述YAML文件定义了一个名为high-priority的优先级类别,优先级为100000,数字越大,优先级越高,超过一亿的数字被系统保留,用于指派给系统组件。

我们可以在任意Pod中引用上述Pod优先级类别:

apiVersion: v1
kind: Pod
metadata:
name: nginx
lables:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
priorityClasses: high-priority

如果发生了需要抢占的调度,高优先级Pod就可能抢占节点N,并将其低优先级Pod驱逐出节点N,高优先级Pod的status信息中的nominatedNodeName字段会记录目标节点N的名称。需要注意,高优先级Pod仍然无法保证最终被调度到节点N上,在节点N上低优先级Pod被驱逐的过程中,如果有新的节点满足高优先级Pod的需求,就会把它调度到新的Node上。而如果在等待低优先级的Pod退出的过程中,又出现了优先级更高的Pod,调度器将会调度这个更高优先级的Pod到节点N上,并重新调度之前等待的高优先级Pod。

最后要指出一点:使用优先级抢占的调度策略可能会导致某些Pod永远无法被成功调度。因此优先级调度不但增加了系统的复杂性,还可能带来额外不稳定的因素。因此,一旦发生资源紧张的局面,首先要考虑的是集群扩容,如果无法扩容,则再考虑有监管的优先级调度特性,比如结合基于Namespace的资源配额限制来约束任意优先级抢占行为。

K8s集群调度的更多相关文章

  1. k8s集群调度方案

    Scheduler是k8s集群的调度器,主要的任务是把定义好的pod分配到集群节点上 有以下特征: 1  公平   保证每一个节点都能被合理分配资源或者能被分配资源 2  资源高效利用   集群所有资 ...

  2. 十五,K8S集群调度原理及调度策略

    目录 k8s调度器Scheduler Scheduler工作原理 请求及Scheduler调度步骤: k8s的调用工作方式 常用预选策略 常用优先函数 节点亲和性调度 节点硬亲和性 节点软亲和性 Po ...

  3. k8s学习-集群调度

    4.7.集群调度 4.7.1.说明 简介 Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上.听起来非常简单,但有很多要考虑的问题: 公平:如何保 ...

  4. k8s集群StatefulSets的Pod调度查询丢失问题?

    k8s集群StatefulSets的Pod调度查询丢失问题? 考点之简单介绍下StatefulSets 和 Deployment 之间有什么本质区别?特定场景该如何做出选择呢? 考点之你能辩证的说说看 ...

  5. k8s重要概念及部署k8s集群(一)--技术流ken

    重要概念 1. cluster cluster是 计算.存储和网络资源的集合,k8s利用这些资源运行各种基于容器的应用. 2.master master是cluster的大脑,他的主要职责是调度,即决 ...

  6. Kubernetes集群调度器原理剖析及思考

    简述 云环境或者计算仓库级别(将整个数据中心当做单个计算池)的集群管理系统通常会定义出工作负载的规范,并使用调度器将工作负载放置到集群恰当的位置.好的调度器可以让集群的工作处理更高效,同时提高资源利用 ...

  7. K8S集群 NOT READY的解决办法 1.13 错误信息:cni config uninitialized

    今天给同事 一个k8s 集群 出现not ready了 花了 40min 才搞定 这里记录一下 避免下载 再遇到了 不清楚. 错误现象:untime network not ready: Networ ...

  8. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之集群部署环境规划(一)

    0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.环境规划 软件 版本 ...

  9. 关于使用rancher部署k8s集群的一些小问题的解决

    问题一: 在rancher的ui上,不能创建k8s的master节点的高可用集群.创建k8s集群,添加节点的时候,可以添加多个master,但是多个master又没有高可用,只要其中一个出问题了,那么 ...

  10. K8s集群部署(二)------ Master节点部署

    Master节点要部署三个服务:API Server.Scheduler.Controller Manager. apiserver提供集群管理的REST API接口,包括认证授权.数据校验以 及集群 ...

随机推荐

  1. Kagol:2022年最值得推荐的前端开源文章

    大家好,我是 Kagol,Vue DevUI 作者,从2020年开始一直专注于前端开源组件库的建设,在前端开源组件库.开源社区运营方面积累了一些经验,2020年主要的创作也是围绕前端组件库和开源两个主 ...

  2. python从公众号文章中获取二维码

    在做一个公众号采集的项目中,客户有个要求,想把二维码的url保存到数据库中,如图. 原本以为要各种骚操作各种逆向才能获取得到,没想到竟然很简单. 第一步 观察二维码url的规范 https://mp. ...

  3. 【转载】EXCEL VBA 同时选择多个工作表的方法

    如果要用VBA同时选择多个工作表,可以利用数组或设置"Select"方法的参数为"False"来扩展所选择的内容,如下面的一些代码:   1.用工作表名称:   ...

  4. Web初级——数组对象常用api

    js数组常用api 连接函数:join("连接符") var array = [1,2,3,4,5] console.log(array.join("+")) ...

  5. Java学习记录:2022年1月13日(其二)

    Java学习记录:2022年1月13日(其二) ​ 摘要:本篇笔记主要记录了在设计类时的一些注意事项,类加载时类中各个部分的加载顺序以及继承和多态的知识. 目录 Java学习记录:2022年1月13日 ...

  6. Java List集合排序

    二维 List 自定义排序 使用lambda表达式 import java.util.*; public class Main { public static void main(String[] a ...

  7. MQ系列11:如何保证消息可靠性传输(除夕奉上)

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...

  8. windows11 彻底修改c盘中文用户名

    windows11 彻底修改c盘用户名 由于一开始注册的时候没有注意使用了中文名导致后来再使用一些应用的时候出现问题浪费了大量的时间找不出原因(例如:安装cuda 的时候在使用nvcc编译.cu文件的 ...

  9. MAC实用操作记录---使用命令执行文件上传下载解压打包与解包

    1.使用命令执行文件上传下载 https://www.cnblogs.com/sugartang/p/12743470.html 2.提示:打不开xx软件,在 OS X 安装软件打不开提示" ...

  10. 动力节点——day03

    接收键盘的输入:1.创建一个键盘扫描器对象 java.util.Scanner s=new Scanner(System.in); 2.接收用户输入s.nextInt(); 静态变量在类加载的时候就分 ...