首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes Pod资源调度之全自动调度和定向调度

Kubernetes Pod资源调度之全自动调度和定向调度

作者头像
仙人技术
发布2020-04-29 12:46:28
1.5K0
发布2020-04-29 12:46:28
举报

1、控制器类型

Kubernetes上,很少会直接创建一个Pod,在大多数情况下,会通过RCDeploymentDaemonSetJob等控制器完成对一组Pod副本的创建、调度和整个生命周期的自动化控制。

在最早的Kubernetes版本里没有这么多Pod副本控制器的,只有一 个Pod副本控制器RC(Replication Controller),这个控制器是这样设计 实现的:RC独立于所控制的Pod,并通过Label标签这个松耦合关联关系 控制目标Pod实例的创建和销毁,随着Kubernetes的发展,RC也出现了新的继任者Deployment,用于更加自动地完成Pod副本的部署、版 本更新、回滚等功能。

严谨地说,RC的继任者其实并不是Deployment,而是ReplicaSet, 因为ReplicaSet进一步增强了RC标签选择器的灵活性。之前RC的标签选择器只能选择一个标签,而ReplicaSet拥有集合式的标签选择器,可以选择多个Pod标签,如下所示

    selector:
      matchLables:
        tier: frontend
      matchExpressions:
        - {key: tier, operator: In, values: [frontend]}

RC不同,ReplicaSet被设计成能控制多个不同标签的Pod副本。 一种常见的应用场景是,应用MyApp目前发布了v1v2两个版本,用户 希望MyAppPod副本数保持为3个,可以同时包含v1v2版本的Pod, 就可以用ReplicaSet来实现这种控制,写法如下

    selector:
      matchLables:
        version: v2
      matchExpressions:
        - {key: version, operator: In, values: [v1,v2]}

Kubernetes的滚动升级就是巧妙运用ReplicaSet的这个特性来实现的,同时,Deployment也是通过ReplicaSet来实现Pod副本自动控制功能的。我们不应该直接使用底层的ReplicaSet来控制Pod副本,而应该 使用管理ReplicaSetDeployment对象来控制副本,这是来自官方的建议。

2、全自动调度

全自动调度的控制器是DeploymentRCDeploymentRC的主要功能之一就是自动部署一个容器应用的 份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。

下面是一个Deployment配置的例子,使用这个配置文件可以创建一个ReplicaSet,这个ReplicaSet会创建3Nginx应用的Pod

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

运行kubectl create命令创建这个Deployment

# kubectl apply -f nginx-deployment.yaml 
deployment.apps/nginx-deployment created

查看DeploymentRSPod的状态

# kubectl get deployment
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment        3/3     3            3           58s
# kubectl get rs
NAME                               DESIRED   CURRENT   READY   AGE
nginx-deployment-7bffc778db        3         3         3       85s
# kubectl get pods
NAME                                     READY   STATUS    RESTARTS   AGE
nginx-deployment-7bffc778db-j5czg        1/1     Running   0          1m34s
nginx-deployment-7bffc778db-lbpjg        1/1     Running   0          1m34s
nginx-deployment-7bffc778db-zcn6m        1/1     Running   0          1m34s

从调度策略上来说,这3Nginx Pod由系统全自动完成调度。它们各自最终运行在哪个节点上,完全由MasterScheduler经过一系列算法计算得出,用户无法干预调度过程和结果。

# kubectl get pods -o wide
NAME                                     READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
nginx-deployment-7bffc778db-j5czg        1/1     Running   0          3m36s   172.20.3.229   k8s-node-1   <none>           <none>
nginx-deployment-7bffc778db-lbpjg        1/1     Running   0          3m36s   172.20.4.27    k8s-node-2   <none>           <none>
nginx-deployment-7bffc778db-zcn6m        1/1     Running   0          3m36s   172.20.5.203   k8s-node-3   <none>           <none>

3、定向调度

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

首先通过kubectl label命令给目标Node打上一些标签

# kubectl label nodes k8s-node-1 zone=north

然后,在Pod的定义中加上nodeSelector的设置,以redismaster-controller.yaml为例

apiVersion: v1
kind: ReplicationController 
metadata:
  name: redis-master
  labels:
    name: redis-master 
spec:
  replicas: 1
  selector:
    name: redis-master
  template:
    metadata:
      labels:
        name: redis-master
    spec:
      containers:
      - name: master
        image: redis
        ports:
        - containerPort: 6379
      nodeSelector:
        zone: north

创建Podscheduler就会将该Pod调度到拥有zone=north标签的Node

如果我们给多个Node都定义了相同的标签(例如zone=north),则scheduler会根据调度算法从这组Node中挑选一个可用的Node进行Pod调度。

通过基于Node标签的调度方式,我们可以把集群中具有不同特点的Node都贴上不同的标签,例 如role=frontendrole=backend``、role=database等标签,在部署应用时就可以根据应用的需求设置NodeSelector来进行指定Node范围的调度。

如果我们指定了PodnodeSelector条件,且在集群中不存在包含相应标签的Node,则即使在集群中还有其他可供使用的Node,这个Pod也无法被成功调度。

除了用户可以自行给Node添加标签,Kubernetes也会给Node预定义 一些标签,包括

  • kubernetes.io/hostname
  • beta.kubernetes.io/os(从1.14版本开始更新为稳定版,到1.18版 本删除)
  • beta.kubernetes.io/arch(从1.14版本开始更新为稳定版,到1.18 版本删除)
  • kubernetes.io/os(从1.14版本开始启用)
  • kubernetes.io/arch(从1.14版本开始启用)

也可以使用这些系统标签进行Pod的定向调度。

NodeSelector通过标签的方式,简单实现了限制Pod所在节点的方法。亲和性调度机制则极大扩展了Pod的调度能力,主要的增强功能如 下。

  • 更具表达力(不仅仅是“符合全部”的简单情况)
  • 可以使用软限制、优先采用等限制方式,代替之前的硬限制, 这样调度器在无法满足优先需求的情况下,会退而求其次,继续运行该Pod
  • 可以依据节点上正在运行的其他Pod的标签来进行限制,而非节点本身的标签。这样就可以定义一种规则来描述Pod之间的亲和或互斥关系

亲和性调度功能包括节点亲和性NodeAffinityPod亲和性PodAffinity两个维度的设置。节点亲和性与NodeSelector类似,增 强了上述前两点优势;Pod的亲和与互斥限制则通过Pod标签而不是节点标签来实现,也就是上面所陈述的方式,同时具有前两点提到的优点。

NodeSelector将会继续使用,随着节点亲和性越来越能够表达nodeSelector的功能,最终NodeSelector会被废弃。

文章参考来源:《kubernetes权威指南-第4版》

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-04-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、控制器类型
    • 2、全自动调度
      • 3、定向调度
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档