乐趣区

关于后端:Kubernetes亲和性学习笔记

欢送拜访我的 GitHub

这里分类和汇总了欣宸的全副原创 (含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本文是欣宸在学习 Kubernetes 调度器的过程中,对亲和性相干知识点的整顿和总结,这是一篇笔记性质的博客

    kubernetes 默认调度器的调度过程:

  • 调度过程如下:
  • 预选(Predicates)
  • 优选(Priorities)
  • 选定(Select)

亲和性一览

  • 这里将亲和性先分类,便于了解

    graph LR
    
    A(亲和性)-->B1(节点亲和性);
    A-->B2(Pod 亲和性);
    B1-->C1(硬亲和性 -required);
    B1-->C2(软亲和性 -preferred);
    B2-->C3(硬亲和性 -required);
    B2-->C4(软亲和性 -preferred);
    B2-->C5(反亲和性);

    节点亲和性和 pod 亲和性的区别

  • 举个例子,假如给小明调配班级(小明是 pod,班级是节点)
  1. 节点亲和性:间接通知小明,你去一年级
  2. pod 亲和性:从小朋友中找出和小明同年的,找到了小张,发现小张是一年级的,于是让小明去一年级

节点亲和性:硬亲和性

  • requiredDuringSchedulinglgnoredDuringExecution:用于定义节点硬亲和性
  • nodeSelectorTerm:节点选择器,能够有多个,之间的关系是 <font color=”red”> 逻辑或 </font>,即一个 nodeSelectorTerm 满足即可
  • matchExpressions:匹配规定定义,多个之间的关系是 <font color=”red”> 逻辑与 </font>,即同一个 nodeSelectorTerm 下所有 matchExpressions 定义的规定都匹配,才算匹配胜利
  • 示例:

    apiVersion: v1
    kind: Pod
    metadata:
    name: with-required-nodeaffinity
    spec:
    affinity:
      nodeAffinity: 
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - {key: zone, operator: In, values: ["foo"]}
    containers:
    - name: nginx
      image: nginx
  • 性能与 <font color=”blue”>nodeSelector</font> 相似,用的是匹配表达式,能够被了解为 <font color=”red”> 新一代节点选择器 </font>
  • 不满足硬亲和性条件时,pod 为 Pending 状态
  • 在预选阶段,节点硬亲和性被用于预选策略 <font color=”blue”>MatchNodeSelector</font>

节点亲和性:软亲和性

  • 特点:条件不满足时也能被调度
  • 示例:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: myapp-deploy-with-node-affinity
    spec:
    replicas: 3
    selector:
      matchLabels:
        app: nginx
    template:
      metadata:
        name: nginx
        labels:
          app: nginx
      spec:
        affinity:
          nodeAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 60
              preference:
                matchExpressions:
                - {key: zone, operator: In, values: ["foo"]}
            - weight: 30
              preference:
                matchExpressions:
                - {key: ssd, operator: Exists, values: []}
        containers:
        - name: nginx
          image: nginx
  • 集群中的节点,因为标签不同,导致的优先级后果如下:
  • 在优选阶段,节点软亲和性被用于优选函数 <font color=”blue”>NodeAffinityPriority</font>
  • 留神:NodeAffinityPriority<font color=”red”> 并非决定性因素 </font>,因为优选阶段还会调用其余优选函数,例如 <font color=”blue”>SelectorSpreadPriority</font>(将 pod 扩散到不同节点以扩散节点故障导致的危险)
  • pod 正本数减少时,散布的比率会参考节点亲和性的权重

Pod 亲和性(podAffinity)

  • 如果需要是:新增的 pod 要和曾经存在 pod(假如是 A) 在同一 node 上,此时用节点亲和性是无奈实现的,因为 A 可能和节点没啥关系 (可能是随机调度的),此时只能用 pod 亲和性来实现
  • pod 亲和性:一个 pod 与曾经存在的某个 pod 的亲和关系,须要通过举例来说明
  1. 创立一个 deployment,这个 pod 有标签 <font color=”blue”>app=tomcat</font>:
kubectl run tomcat -l app=tomcat --image tomcat:alpine
  1. 创立 pod,需要是 <font color=”blue”> 和后面的 pod 在一起 </font>,应用 pod 亲和性来实现:
apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity-1
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: app, operator: In, values: ["tomcat"]}
        topologyKey: kubernetes.io/hostname
  containers:
  - name: nginx
    image: nginx
  1. 调度逻辑:

graph TD

A[1. 用 matchExpressions 的规定 app=tomcat 搜寻] -->B(2. 找到 tomcat 的 pod, 也就确定了该 pod 的节点, 假如是 A 节点)
B --> C(3. topologyKey 是 kubernetes.io/hostname, 所以去找 A 节点 kubernetes.io/hostname 标签的值, 假如是 xxx)
C --> D(4. 将新的 pod 调度到 kubernetes.io/hostname=xxx 的节点)
  1. 外表上看,最终只是依据 hostname 去调度的,但如果 topologyKey 的值是多个节点所领有的,就更有通用性了,如下图,topologyKey 等于 filure-domain.beta.kubernetes.io/zone:
  • 硬亲和:requiredDuringSchedulingIgnoredDuringExecution
  • 软亲和:preferredDuringSchedulingIgnoredDuringExecution

    Pod 反亲和(podAntiAffinity)

  • 与亲和性相同,将以后 pod 调度到满足匹配条件之外的节点上
  • 实用场景:
  • 扩散同一类利用
  • 将不同安全级别的 pod 调度至不同节点
  • 示例如下,匹配表达式和本身标签统一,作用是扩散同一类利用,让雷同 pod 不要调度到同一个节点:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-with-pod-anti-affinity
spec:
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp
      labels:
        app: myapp
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - {key: app, operator: In, values: ["myapp"]}
            topologyKey: kubernetes.io/hostname
      containers:
      - name: nginx
        image: nginx
  • 如果集群中只有三个节点,那么执行上述 yaml 的后果就是最多创立三个 pod,另一个始终处于 pending 状态

    参考

  • 本篇笔记参考了以下文章,两张图片也来自该文章,致敬作者 <font color=”blue”> 山山仙人博客 </font>
  • https://www.ssgeek.com/post/kubernetes-pod-diao-du-zhi-qin-he…

欢送关注思否:程序员欣宸

学习路上,你不孤独,欣宸原创一路相伴 …

退出移动版