Kubernetes調度之親和性和反親和性

原文出處:http://ju.outofmemory.cn/entry/278349

背景

Kubernetes中的調度策略可以大致分爲兩種,一種是全局的調度策略,要在啓動調度器時配置,包括kubernetes調度器自帶的各種predicates和priorities算法,具體可以參看文章《Kubernetes調度詳解》;另一種是運行時調度策略,包括nodeAffinity(主機親和性),podAffinity(POD親和性)以及podAntiAffinity(POD反親和性)。

nodeAffinity 主要解決POD要部署在哪些主機,以及POD不能部署在哪些主機上的問題,處理的是POD和主機之間的關係。

podAffinity 主要解決POD可以和哪些POD部署在同一個拓撲域中的問題(拓撲域用主機標籤實現,可以是單個主機,也可以是多個主機組成的cluster、zone等。),podAntiAffinity主要解決POD不能和哪些POD部署在同一個拓撲域中的問題。它們處理的是Kubernetes集羣內部POD和POD之間的關係。

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

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

本文主要介紹如何使用親和性和反親和性做資源調度。

使用場景

nodeAffinity使用場景 

  • 將S1服務的所有Pod部署到指定的符合標籤規則的主機上。

  • 將S1服務的所有Pod部署到除部分主機外的其他主機上。

podAffinity使用場景 

  • 將某一特定服務的pod部署在同一拓撲域中,不用指定具體的拓撲域。

  • 如果S1服務使用S2服務,爲了減少它們之間的網絡延遲(或其它原因),把S1服務的POD和S2服務的pod部署在同一拓撲域中。

podAntiAffinity使用場 景:

  • 將一個服務的POD分散在不同的主機或者拓撲域中,提高服務本身的穩定性。

  • 給POD對於一個節點的獨佔訪問權限來保證資源隔離,保證不會有其它pod來分享節點資源。

  • 把可能會相互影響的服務的POD分散在不同的主機上。

對於親和性和反親和性,每種都有三種規則可以設置:

RequiredDuringSchedulingRequiredDuringExecution :在調度期間要求滿足親和性或者反親和性規則,如果不能滿足規則,則POD不能被調度到對應的主機上。在之後的運行過程中,如果因爲某些原因(比如修改label)導致規則不能滿足,系統會嘗試把POD從主機上刪除(現在版本還不支持)。

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

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

使用示例

使用POD親和性調度時要先開啓Kubernetes調度器的MatchInterPodAffinity篩選功能,具體的操作方式是修改調度器的配置文件,在predicates中增加如下內容:


1

{"name": "MatchInterPodAffinity"}


測試環境的主機信息如下:

qinhe01

其中每個主機上都有 beta.kubernetes.io/arch、beta.kubernetes.io/os、kubernetes.io/hostname這幾個標籤,在測試過程中把這些標籤當做拓撲域使用。

nodeAffinity 使用示例:

使用nodeAffinity把POD部署到主機mesos-slave1和mesos-slave2上,yaml定義如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

{

  "nodeAffinity": {

    "requiredDuringSchedulingIgnoredDuringExecution": {

      "nodeSelectorTerms": [

        {

          "matchExpressions": [

            {

              "key": "kubernetes.io/hostname",

              "operator": "In",

              "values": [

                "mesos-slave1",

                "mesos-slave2"

              ]

            }

          ]

        }

      ]

    }

  }

}


創建一個有6個POD的RC,結果如下:

qinhe02

從結果可以看出POD被部署到了mesos-slave1和mesos-slave2上,mesos-slave3上沒有部署POD。

podAffinity使用示例 

使用kubernetes.io/hostname作爲拓撲域,把pod創建在同一主機上。其中matchExpressions中填寫內容對應到RC中POD自身的標籤。可以通過修改需要匹配的標籤內容來控制把一個服務中的POD和其它服務的POD部署在同一主機上。

yaml中的定義如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

{

  "podAffinity": {

    "requiredDuringSchedulingIgnoredDuringExecution": [

      {

        "labelSelector": {

          "matchExpressions": [

            {

              "key": "name",

              "operator": "In",

              "values": [

                "node-rc"

              ]

            }

          ]

        },

        "topologyKey": "kubernetes.io/hostname"

      }

    ]

  }

}


創建一個有3個POD的RC,結果如下:

qinhe03

所有創建的POD集中在同一個主機上,具體的主機是哪個不需要指定。

podAntiAffinity 使用示例:

使用kubernetes.io/hostname作爲拓撲域,把pod創建在不同主機上,每個主機上最多隻有一個同類型的POD(同類型用標籤區分)。其中matchExpressions中填寫內容對應到RC中POD自身的標籤。可以通過修改需要匹配的標籤內容來控制把一個服務中的POD和其它服務的POD部署在不同主機上。

yaml中的定義如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

{

  "podAntiAffinity": {

    "requiredDuringSchedulingIgnoredDuringExecution": [

      {

        "labelSelector": {

          "matchExpressions": [

            {

              "key": "name",

              "operator": "In",

              "values": [

                "node-rc"

              ]

            }

          ]

        },

        "topologyKey": "kubernetes.io/hostname"

      }

    ]

  }

}


創建一個有4個POD的RC,結果如下:

qinhe04

三個主機上都有一個POD運行,因爲每個主機上最多隻能運行一個這種類型的POD,所以有一個POD一直處於Pending狀態,不能調度到任何節點。

上邊的例子中可以通過修改topologyKey來限制拓撲域的範圍,實現把相關服務部署在不同的容災域等其它功能。

總結

Kubernetes提供了豐富的調度策略,包括靜態的全局調度策略,以及動態的運行時調度策略,用戶可以根據需要自由組合使用這些策略來實現自己的需求。在調度過程中,使用nodeAffnity決定資源可以部署在哪些主機上,使用podAffinity和podAntiAffinity決定哪些資源需要部署在同一主機(拓撲域)或者不能部署在同一主機。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章