k8s nodeSelector和affinity 調度親和性

nodeSelector

1.分配pod到node的方法node

經過node label selector實現約束pod運行到指定節點,有兩種方法 nodeSelector 以及affinitymysql

2.nodeSelector 是k8s早起提供的節點選擇器實現linux

1)首先爲nodes打對應的label
kubectl label nodes master disktype=ssd
2)建立yaml文件,nginx-pod.yamlnginx

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

建立podgit

kubectl create -f nginx-pod.yaml
節點默認的label
kubectl get nodes -o yaml 能夠看到默認節點的label,也可使用這些label進行約束github

alpha.kubernetes.io/fluentd-ds-ready: "true"
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
disktype: ssd
kubeadm.alpha.kubernetes.io/role: master
kubernetes.io/hostname: master

親和性和反親和性

根據類型有sql

nodeAffinity(主機親和性),
podAffinity(POD親和性)
podAntiAffinity(POD反親和性)。api

三種親和性和反親和性策略的比較以下表所示:網絡

策略名稱 匹配目標 支持的操做符 支持拓撲域 設計目標
nodeAffinity 主機標籤 In,NotIn,Exists,DoesNotExist,Gt,Lt 不支持 決定Pod能夠部署在哪些主機上
podAffinity Pod標籤 In,NotIn,Exists,DoesNotExist 支持 決定Pod能夠和哪些Pod部署在同一拓撲域
PodAntiAffinity Pod標籤 In,NotIn,Exists,DoesNotExist 支持 決定Pod不能夠和哪些Pod部署在同一拓撲域

對於親和性和反親和性,每種都有三種規則能夠設置:dom

RequiredDuringSchedulingRequiredDuringExecution :在調度期間要求知足親和性或者反親和性規則,若是不能知足規則,則POD不能被調度到對應的主機上。在以後的運行過程當中,若是由於某些緣由(好比修改label)致使規則不能知足,系統會嘗試把POD從主機上刪除(如今版本還不支持)。

RequiredDuringSchedulingIgnoredDuringExecution :在調度期間要求知足親和性或者反親和性規則,若是不能知足規則,則POD不能被調度到對應的主機上。在以後的運行過程當中,系統不會再檢查這些規則是否知足。

PreferredDuringSchedulingIgnoredDuringExecution :在調度期間儘可能知足親和性或者反親和性規則,若是不能知足規則,POD也有可能被調度到對應的主機上。在以後的運行過程當中,系統不會再檢查這些規則是否知足。

使用場景介紹

nodeAffinity使用場景 :

  • 將S1服務的全部Pod部署到指定的符合標籤規則的主機上。
  • 將S1服務的全部Pod部署到除部分主機外的其餘主機上。

podAffinity使用場景 :

  • 將某一特定服務的pod部署在同一拓撲域中,不用指定具體的拓撲域。
  • 若是S1服務使用S2服務,爲了減小它們之間的網絡延遲(或其它緣由),把S1服務的POD和S2服務的pod部署在同一拓撲域中。

podAntiAffinity使用場 景:

  • 將一個服務的POD分散在不一樣的主機或者拓撲域中,提升服務自己的穩定性。
  • 給POD對於一個節點的獨佔訪問權限來保證資源隔離,保證不會有其它pod來分享節點資源。
  • 把可能會相互影響的服務的POD分散在不一樣的主機上。

NodeAffinity

參考:https://k8smeetup.github.io/docs/concepts/configuration/assign-pod-node/#node-親和性beta-特性

requiredDuringSchedulingIgnoredDuringExecution的示例

下面這個例子使用nodeAffinity把POD部署到主機mesos-slave1和mesos-slave2上面

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
  annotations:
    scheduler.alpha.kubernetes.io/affinity: >
      {
        "nodeAffinity": {
          "requiredDuringSchedulingIgnoredDuringExecution": {
            "nodeSelectorTerms": [
              {
                "matchExpressions": [
                  {
                    "key": "kubernetes.io/hostname",
                    "operator": "In",
                    "values": [「mesos-slave1″,」mesos-slave2」]
                  }
                ]
              }
            ]
          }
        }
      }
    another-annotation-key: another-annotation-value
spec:
  containers:
  - name: with-node-affinity
    image: gcr.io/google_containers/pause:2.0

咱們能夠看到NodeSelectorTerms能夠有多個,之間是或的關係,知足任意一個既知足,,MatchExpressions也能夠有多個,他們之間是且的關係 必須都知足。

preferredDuringSchedulingIgnoredDuringExecution 例子

apiVersion: v1
kind: Pod
metadata:
  name: with-labels
  annotations:
    scheduler.alpha.kubernetes.io/affinity: >
    {
       "nodeAffinity": {
          "preferredDuringSchedulingIgnoredDuringExecution": [
                {
                    "weight" : 1,
                    "preference": {
                        "matchExpressions": [
                            {
                                "key": "disktype",
                                "operator": "In",
                                "values": ["ssd"]
                            }
                        ]
                    }
                }
            ]
        }
    }
    another-annotation-key: another-annotation-value
spec:
  containers:
  - name: test-affinity
    env:
      - name: MYSQL_ROOT_PASSWORD
        value: pass
    image: mysql
  •  

preferredDuringSchedulingIgnoredDuringExecution值爲列表,根據權重決定順序
MatchExpressions 值爲列表 關係爲且,必須都知足

Inter-pod affinity and anti-affinity

Inter-pod affinity 是根據經過已運行在節點上的pod的標籤而不是node的標籤來決定被調度pod的運行節點,由於pod運行在指定的namespace因此須要本身指定運行pod的namesapce

anti-affinity 和Inter-pod affinity相反

在下面這個例子中,定義了一個Pod親和性和一個Pod反親和性規則。其中Pod親和性規則是必定要知足的,Pod反親和性規則是參考知足的。

Pod親和性規則的含義是:Pod必須部署在一個節點上,這個節點上至少有一個正在運行的Pod,這個Pod的security屬性取值是「S1」,而且要求部署的節點同正在運行的Pod所在節點都在相同的雲服務區域中,也就是「topologyKey:failure-domain.beta.kubernetes.io/zone」。換言之,一旦某個區域出了問題,咱們但願這些 Pod 可以再次遷移到同一個區域。

Pod反親和性規則的含義是,Pod不能部署在一個節點上,這個節點上正在運行的Pod中security屬性取值是「S2」,而且新部署的Pod不能同security屬性取值是「S2」的Pod在相同的主機上,也就是「topologyKey: kubernetes.io/hostname」。

matchExpressions中operator的取值包括In、NotIn、Exists、DoesNotExist、Gt和Lt。topologyKey的取值包括:

  1. kubernetes.io/hostname       同一個主機
    • 1
  2. failure-domain.beta.kubernetes.io/zone      同一個雲服務區
    • 1
  3. failure-domain.beta.kubernetes.io/region    同一個區域
    • 1
apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
  annotations:
    scheduler.alpha.kubernetes.io/affinity: >
        {
          "podAffinity": {
            "requiredDuringSchedulingIgnoredDuringExecution": [
              {
                "labelSelector": {
                  "matchExpressions": [
                    {
                      "key": "security",
                      "operator": "In",
                      "values": ["S1"]
                    }
                  ]
                },
                "topologyKey": "failure-domain.beta.kubernetes.io/zone"
             }
            ]
           },
          "podAntiAffinity": {
            "requiredDuringSchedulingIgnoredDuringExecution": [
              {
                "labelSelector": {
                  "matchExpressions": [
                    {
                      "key": "security",
                      "operator": "In",
                      "values": ["S2"]
                    }
                  ]
                },
                "topologyKey": "kubernetes.io/hostname"
             }
            ]
           }
         }
spec:
  containers:
  - name: with-pod-affinity
    image: gcr.io/google_containers/pause:2.0
相關文章
相關標籤/搜索