Kubernetes 1.6新特性系列 | 高级调度

简介: 1、简介 Kubernetes的调度器在大多数情况下能过运行的很好,例如:它能够将Pod调度到有充足资源的Node上;它能够将一组Pod(ReplicaSet, StatefulSet,等)均匀的调度到不同的Node上;它尽力平衡各个节点的资源使用率等。

1、简介

Kubernetes的调度器在大多数情况下能过运行的很好,例如:它能够将Pod调度 到有充足资 源的Node上;它能够将一组Pod(ReplicaSet, StatefulSet,等)均匀的调度到不同的Node上;它尽力平衡各个节点的资源使用率等。

但有些时候您会想控制您的Pod如何调度,例如:可能您想让一些Pod被确定调度到某些使用特殊硬件的节点上,或者您想让交互频繁的服务一起调度,或者您想让一些Node只给特定的一些用户提供服务等等。最终,您对于应用程序调度和部署的需求永远要比Kubernetes提供的多。因此,Kubernetes 1.6提供了四个高级高级调度功能:节点亲和性和反亲和性,污点和容忍,Pod亲和性/反亲和性和自定义调度。这四个特性在Kubernetes 1.6版本中都是beta版。

2、Node亲和性/反亲和性

Node亲和性/反亲和性是在Node上设置如何被Scheduler选择的规则一种方式。此功能是自Kubernetes 1.0版本以来在Kubernetes中的nodeSelector的功能的通用化。规则是使用在Pod中指定和选择器上自定义的标签等用户熟悉的概念定义的,并且他们是必需的或者首选的,这取决于您希望调度程序强制执行他们的严格程度。

A必需的规则(Required)

只有满足必需的规则的Pod才会被调度到特定的Node上。如果没有Node匹配条件(加上所有其他所有正常的条件,例如为Pod请求提供足够的可用资源),否则Pod不会被调度。必需满足的规则在nodeAffinity的requiredDuringSchedulingIgnoredDuringExecution字段中指定。

例如,如果我们要求在多可用区域(Multiple Zones)的us-central1-a(GCE)区域中的节点上进行调度,则可以将以下的关联规则指定为Pod规范(Spec)的一部分:

affinity:
 nodeAffinity:
 requiredDuringSchedulingIgnoredDuringExecution:
 nodeSelectorTerms: - matchExpressions: - key: "failure-domain.beta.kubernetes.io/zone" operator: In
 values: ["us-central1-a"]

“IgnoredDuringExecution”意味着如果Node上的标签发生更改,并且亲和性的规则不再满足时选择忽略。这个在未来会计划实现。
“requiredDuringSchedulingRequiredDuringExecution”意味着一旦他们不满足节点亲和性规则,将从Node上驱逐不再匹配规则的Pod。

B首选的规则(Preferred)

首选规则意味着如果节点与规则匹配,则将优先选择它们,并且仅当没有优选节点可用时才选择非优选节点。您可以选择使用首选规则,而不是通过必需规则强制将Pod部署到GCE的us-central1-a区域中的节点上。使用首选规则,则需指定preferredDuringSchedulingIgnoredDuringExecution:

affinity:
 nodeAffinity:
 preferredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "failure-domain.beta.kubernetes.io/zone" operator: In values: ["us-central1-a"]

Node的反亲和性能够使用负操作符(NotIn, DoesNotExist等)来表示。下面的例子说明了如何禁止您的Pod被调度到us-central1-a的区域中:

affinity:
 nodeAffinity:
 requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "failur-domain.beta.kubernetes.io/zone" operator: NotIn values: ["us-central1-a"]

可以使用的操作符有:In, NotIn, Exists, DoesNotExist, Gt, 和Lt。

这个特性还有一些另外的使用场景,比如需要在调度上严格区别Node上的硬件架构,操作系统版本,或者专用的硬件等。

Node的亲和性和反亲和性在Kubernetes 1.6版本中是Beta版。

3、污点和容忍(Taints and Tolerations)

此功能允许您标记一个Node(“受污染”,“有污点”),以便没有Pod可以被调度到此节点上,除非Pod明确地“容忍”污点。标记的是Node而不是Pod(如节点的亲和性和反亲和性),对于集群中大多数Pod应该避免调度到特定的节点上的功能特别有用,例如,您可能希望主节点(Master)标记为仅可调度Kubernetes系统组件,或将一组节点专用于特定的用户组,或者让常规的Pod远离具有特殊硬件的Node,以便为有特殊硬件需求的Pod留出空间。

使用kubectl命令可以设置节点的“污点”,例如:

kubectl taint nodes node1 key=value:NoSchedule

创建一个污点并标记到Node,那些没有设置容忍的Pod(通过key-value方式设置NoSchedule,这是其中一个选项)不能调度到该Node上。其他污点的选项是PerferredNoSchedule,这是NoSchedule首选版本;还有NoExecute,这个选项意味着在当Node被标记有污点时,该Node上运行的任何没有设置容忍的Pod都将被驱逐。容忍将被添加到PodSpec中,看起来像这样:

tolerations: - key: "key" operator: "Equal" value: "value"
 effect: "NoSchedule"

除了将污点和容忍(Taints and Tolerations)特性在Kubernetes 1.6中移至Beta版外,我们还引入了一个使用污点和容忍的Alpha的特性:允许用户自定义一个Pod被绑定到Node上后遇到了诸如网络分区的问题时的行为(可能Pod希望长时间允许在这个Node上,或者网络分区会很快恢复),而不是现在默认的等待五分钟超时。更详细的信息,请参阅文档。

4、Pod的亲和性和反亲和性

Node的亲和性和反亲和性允许您基于节点的标签来限制Pod的调度行为。但是,如果您想要指定Pod的亲和关系时这种方法就无法奏效了。例如,如何实现在一个服务或者相关的服务中聚合Pod或将Pod均匀分布?为此,您可以使用Pod的亲和性和反亲和性特性,它在Kubernetes 1.6中也是Beta版。

我们来看一个例子。假设您在服务S1中有个前端应用,它经常与服务S2的后端应用进行通信。因此,您希望这两个服务共同位于同一个云提供商的区域中,但您不需要手动选择区域(如果有些区域暂时不可用),希望将Pod重新调度到另一个(单个的)区域。您可以像这样指定Pod的亲和性和反亲和性规则(假设您将该服务的Pod命名为*”service=S2″,另外一个服务的Pod为”service=S1″):

affinity:
 podAffinity:
 requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: service operator: In values: [“S1”]
 topologyKey: failure-domain.beta.kubernetes.io/zone

如同Node的亲和性和反亲和性,也有一个preferredDuringSchedulingIgnoredDuringExecution变量。

Pod的亲和性和反亲和性非常灵活。想象一下,您已经分析了您的服务的性能,发现来自服务S1的容器会干扰运行在同一Node上的服务S2的容器,这可能是由于缓存干扰效应或者网络连接饱和引起,或者也许是由于安全性问题,您不会想要S1和S2的容器共享一个Node。要实现这些规则,只需对上述代码段进行两次更改即可将podAffinity更改为podAntiAffinity”,并将topologyKey更改为kubernetes.io/hostname*即可。

5、自定义调度器

如果Kubernetes Scheduler的这些特性没能足够满足您控制负载的需求,您可以在将任意子集的Pod的调度任务交给您自己的自定义调度器,自定义的调度器可以跟默认的调度器(Kubernetes Scheduler)一起运行,或者替代默认的调度器。多调度器(Multiple schedulers)在Kubernetes 1.6中是Beta版。

在默认的情况下,每个新的Pod都使用默认的调度器进行调度。但是如果您提供了自定义调度器的名称,默认的调度器会忽略Pod的调度请求,允许您的自定义调度器对Pod进行调度。看看下面的例子:
在Pod的规范(Spec)中制定调度器的名字:

apiVersion: v1
kind: Pod
metadata: 
 name: nginx 
 labels: app: nginx
spec:
 schedulerName: my-scheduler
 containers: - name: nginx image: nginx:1.10

如果我们在没有部署自定义调度器的情况下创建了这个Pod,结果会是默认的调度器将忽略这个Pod,它将处于Pending状态。因此,我们需要一个自定义调度程序来查找和调度其schedulerName字段为my-scheduler的Pod。

自定义调度语言可以用任何语言编写,调度策略根据需要可以简单也可以复杂。这是一个非常简单的例子,它使用Bash编写,它可以为Pod随机分配一个Node。请注意,您需要让它与kubectl proxy一起运行:

#!/bin/bash
SERVER='localhost:8001' # Proxy address for apiServer while true; do # Get all pods, and pod's properties for PODNAME in $(kubectl --server $SERVER get pods -o json 
 | jq '.items[] 
 | select(.spec.schedulerName == "my-scheduler") 
 | select(.spec.nodeName == null) 
 | .metadata.name' | tr -d '"'); do # Get all nodes
 NODES=($(kubectl --server $SERVER get nodes -o json 
 | jq '.items[].metadata.name' | tr -d '"'))
 NUMNODES=${#NODES[@]} # Choose a node randomly
 CHOSEN=${NODES[$[ $RANDOM % $NUMNODES ]]} # Bind a pod($PODNAME) to a node($CHOSEN)
 curl --header "Content-Type:application/json" --request POST 
 --data  '{
 "apiVersion":"v1",
 "kind": "Binding",
 "metadata": {
 "name": "'$PODNAME'"
 }, 
 "target": {
 "apiVersion": "v1", 
 "kind": "Node", 
 "name": "'$CHOSEN'"
 }
 }'
 http://$SERVER/api/v1/namespaces/default/pods/$PODNAME/binding/ echo "Assigned $PODNAME to $CHOSEN" done
 sleep 1 done

Kubernetes 1.6的release notes关于这个特性有更多的介绍,包括您已经使用了这些(其中一个或者多个)特性的Alpha版本改如何进行配置的细节(这些事必需的,因为对于这些特性,从Alpha到Beta的转变是突破性的)。

6、致谢

这里描述的功能,包括Alpha和Beta版本,都是真正的社区努力,涉及Google,华为,IBM,Red Hat等的工程师。

本文转自中文社区-Kubernetes 1.6新特性系列 | 高级调度

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
3月前
|
Kubernetes 监控 调度
Kubernetes Pod调度:从基础到高级实战技巧
Kubernetes Pod调度:从基础到高级实战技巧
186 0
|
4月前
|
Kubernetes 应用服务中间件 调度
k8s教程(pod篇)-全自动调度
k8s教程(pod篇)-全自动调度
46 0
|
4月前
|
存储 Kubernetes 调度
k8s教程(pod篇)-DaemonSet(每个node上只调度一个pod)
k8s教程(pod篇)-DaemonSet(每个node上只调度一个pod)
67 0
|
1月前
|
Kubernetes 网络安全 调度
容器服务ACK常见问题之容器服务ACK的eci调度卡住如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
4月前
|
消息中间件 Kubernetes 调度
k8s教程(pod篇)-批处理调度
k8s教程(pod篇)-批处理调度
70 0
|
1月前
|
Kubernetes 应用服务中间件 nginx
Kubernetes服务网络Ingress网络模型分析、安装和高级用法
Kubernetes服务网络Ingress网络模型分析、安装和高级用法
36 5
|
6月前
|
Kubernetes 算法 调度
【K8S系列】深入解析K8S调度
【K8S系列】深入解析K8S调度
455 0
|
3月前
|
存储 Kubernetes 安全
Kubernetes Pod配置:从基础到高级实战技巧
Kubernetes Pod配置:从基础到高级实战技巧
147 0
|
4月前
|
Kubernetes Cloud Native 调度
云原生|kubernetes |一文带你搞懂pod调度策略,驱逐策略,污点、容忍调度
云原生|kubernetes |一文带你搞懂pod调度策略,驱逐策略,污点、容忍调度
230 0
|
4月前
|
Kubernetes 容灾 调度
k8s教程(pod篇)-容灾调度
k8s教程(pod篇)-容灾调度
79 0

推荐镜像

更多