zoukankan      html  css  js  c++  java
  • kubernetes 亲和性调度详解

    概述:

    默认情况下创建pod调度是根据kubernetes scheduler默认的调度规则去进行调度的,但有些时候,有些应用有一些特殊的需求比如指定部署到对应的节点、多个pod之间需要部署在不同一个节点,需要互斥、pod和pod间相互交流比较频繁需要跑在同一个节点,需要亲和。这时就需要灵活配置scheduler来实现了。

    场景一:调度到一组具有相同特性的主机上(label+nodeSelector)

    比如在整个kubernetes集群内,有一组配置比较好的服务器,然后有一些特殊的应用需要对硬件配置有需求,需要被调度到这些服务器上,这时可以通过kubernetes的label+nodeSelector去实现,实际上在kubernetes里面label是一个非常灵活的概念,kubernetes内不同资源对象之间的关联就是通过label的方式去进行的。

    我们给那些配置高的节点打上个label

    给高配置的host打上一个label Configuration=hight(这里以rke-node2为例)

    kubectl label node rke-node2 Configuration=hight

    在show labels可以看见我们刚刚打上去的label

    创建pod使用nodeSelector调度到指定label的节点上

    mysql-deployment.yaml
    
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
     name: mysql-2
    spec:
     selector:
       matchLabels:
         app: mysql
     template:
       metadata:
         labels:
           app: mysql
       spec:
         containers:
         - image: mysql:5.6
           name: mysql
           env:
           - name: MYSQL_ROOT_PASSWORD
             value: password
           ports:
           - containerPort: 3306
             name: mysql
         nodeSelector:
           Configuration: hight

    配置nodeSelector调度到Configuration:hight的host上
    创建deployment

    kubectl apply -f mysql-deployment.yaml

    查看pod被调度到label为 Configuration: hight的host上了

    场景二:部署的应用不想调度到某些节点上(nodeaffinity)

    比如在一个kubernetes集群内,需要将应用部署到指定标签的机器上,但如果没有的话这类机器的话,就按正常调度规则进行调度。这时通过nodeSelector就无法实现这个需求了,在kubernetes内可以通过nodeaffinity的方式的去实现。

    nodeaffinitynodeSelecotr非常类似,都是node层面的调度策略的配置,但区别是nodeSelect功能比较单一,只能根据label选择对应的主机,而nodeaffinity更加灵活,nodeaffinity有两种调度类型requiredDuringSchedulingIgnoredDuringExecution(硬要求)和preferredDuringSchedulingIgnoredDuringExecution(软要求),两种类型区别在于,硬要求要求调度时必须满足设置的调度规则,否则抛异常调度失败,而软要求,只是调度时优先考虑设置的调度规则,当达不到设置的规则时,则按kube-scheduler默认的调度策略进行调度。nodeaffinity还支持多种规则匹配条件的配置如
    In:label 的值在列表内
    NotIn:label 的值不在列表内
    Gt:label 的值大于设置的值
    Lt:label 的值小于设置的值
    Exists:设置的label 存在
    DoesNotExist:设置的 label 不存在

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
     name: mysql-2
    spec:
     selector:
       matchLabels:
         app: mysql
     template:
       metadata:
         labels:
           app: mysql
       spec:
         containers:
         - image: mysql:5.6
           name: mysql
           env:
           - name: MYSQL_ROOT_PASSWORD
             value: password
           ports:
           - containerPort: 3306
             name: mysql
         affinity:
           nodeAffinity:
             requiredDuringSchedulingIgnoredDuringExecution:
               nodeSelectorTerms:
               - matchExpressions:
                 - key: kubernetes.io/hostname
                   operator: NotIn
                   values:
                   - rke-node3
                   - rke-node4
             preferredDuringSchedulingIgnoredDuringExecution:
             - weight: 1
               preference:
                 matchExpressions:
                 - key: disk_type
                   operator: In
                   values:
                   - ssd
    
    

    如上所例,要求pod不能被调度到rke-node3和rke-node4上,但如果有满足dis_type=ssd的label的节点则优先选择。
    如果在 nodeAffinity 类型中指定了多个 nodeSelectorTerms,那么 pod 将会被调度到只要满足其中一个 nodeSelectorTerms 的 node 上。
    如果在 nodeSelectorTerms 中指定了多个 matchExpressions,那么 pod 将会被调度到 满足所有 matchExpressions 的 node 上。

    场景三:部署的应用关联性很强,需要尽量在一个节点上

    比如在kubernetes集群,有些pod和pod之间的交互很频繁,这时就需要将它们尽可能的调度到一台主机上,通过pod与pod之间的关系来选择调度,这时候我们就可以使用podaffinity。根nodeaffinity一样,podaffinity也有两种调度类型requiredDuringSchedulingIgnoredDuringExecution(硬要求)和preferredDuringSchedulingIgnoredDuringExecution(软要求),多种规则匹配条件配置。
    例 部署一个nginx和mysql因为nginx和mysql之间的交互很频繁,所以尽量将他们部署在一个host上。
    先启动一个nginx。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

    启动mysql

    apiVersion: v1
    kind: Pod
    metadata:
      name: mysql
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: nginx
        env:
         - name: "MYSQL_ROOT_PASSWORD"
           value: "123456"
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx
            topologyKey: kubernetes.io/hostname

    topologyKey可以设置成如下几种类型
    kubernetes.io/hostname  #Node
    failure-domain.beta.kubernetes.io/zone #Zone
    failure-domain.beta.kubernetes.io/region #Region
    可以设置node上的label的值来表示node的name,zone,region等信息,pod的规则中指定topologykey的值表示指定topology范围内的node上运行的pod满足指定规则

    这里我们配置podaffinity,mysql会调度到有app:nginx这个label的pod的host上,所以你部署出来的mysql会调度到有nginx的pod上,因为默认部署出来的nginx就自带app:nginx这个label。

    场景四:部署应用需要互斥,不能同时运行在一台主机上,会冲突

    我们继续以我们刚刚的nginx+mysql这个应用组合为例,现在我们修改mysql的podaffinitypodAntiAffinity

    apiVersion: v1
    kind: Pod
    metadata:
      name: mysql
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: nginx
        env:
         - name: "MYSQL_ROOT_PASSWORD"
           value: "123456"
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx
            topologyKey: kubernetes.io/hostname

    podaffinity改为podAntiAffinity这样调度mysql这个pod时会避开有label为app:nginx的pod的主机

    高级特性Taints and tolerations

    Taints其实根nodeaffinity正好相反,nodeaffinity是将设置策略的pod调度到期望的节点上,而taints正好相反,如果一个节点被标记为taints,除非pod配置了tolerations,否则是不会被允许调度过来在生产环境中我们一般会将master节点配置Taints,因为master只跑kubernetes 系统组件,如果跑了用户应用pod容易把资源耗尽,造成master节点崩溃,当然后期如果要添加额外的系统组件,这时就可以通过给对应的pod配置toleration。

    设置rke-node2不能被调度

    kubectl taint nodes rke-node2 key=value:NoSchedule

    value可以配置多个值如
    NoSchedule:不能调度,当之前调度的不管。
    PreferNoSchedule:尽量不调度上去,其实就是Noschedule软策略版。
    NoExecute:不能调度,但之前已经调度上去的也会自动迁移走。

    NoSchedule更像执行kubectl cordon xxx
    NoExecute更想执行kubectl cordon xxx+kubectl drain

    取消taints

    kubectl taint nodes rke-node2 key-

    如何让pod调度到配置了taints主机上?
    通过配置tolerations,可以让pod调度到配置了taints的机器上

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
     name: mysql-2
    spec:
     selector:
       matchLabels:
         app: mysql
     template:
       metadata:
         labels:
           app: mysql
       spec:
         containers:
         - image: mysql:5.6
           name: mysql
           env:
           - name: MYSQL_ROOT_PASSWORD
             value: password
           ports:
           - containerPort: 3306
             name: mysql
         tolerations:
         - key: "key"
           operator: "Equal"
           value: "value"
           effect: "NoSchedule"
  • 相关阅读:
    植物大战僵尸 辅助 总结
    C# 操作地址 从内存中读取写入数据(初级)
    c# math
    c# 获取屏幕图片
    从客户端(editorValue="<p>xxxx</p>")中检测到有潜在危险的 Request.Form 值。
    三种常见的SQL分页语句
    Windows Installer 服务无法启动!
    无法访问windows installer服务
    mssql2000数据库执行SQL语句来创建数据库以及数据表还有索引
    如何安装aspjpeg
  • 原文地址:https://www.cnblogs.com/cheyunhua/p/11309784.html
Copyright © 2011-2022 走看看