操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    前言

    1.Jenkins架構原理回顧

    在前面一篇《CI&CD落地實踐2-Jenkins環(huán)境搭建&常見使用技巧》中,我們介紹了Jenkins的架構原理:

    Jenkins是一種典型的Master-Slave主從架構。該架構包括一個Master(主)節(jié)點和多個Slave(從)節(jié)點。Jenkins的Master-Slave架構提供了可擴展性和靈活性,允許用戶添加更多節(jié)點來提高Jenkins的處理能力,同時保持構建和管理過程的可靠性。

    1. Master節(jié)點:Jenkins的核心是Master節(jié)點,包含Jenkins的核心功能和管理界面,并與所有Slave節(jié)點通信,調度和分配作業(yè)。主要的作業(yè)配置信息,如構建工作流程、觸發(fā)器和構建器、節(jié)點和視圖信息,以及連接外部系統的應用程序都存儲在Jenkins Master節(jié)點中。
    2. Agent節(jié)點:也稱slave節(jié)點,是通過Jenkins Agent(代理)連接到Master節(jié)點的計算機,它們執(zhí)行來自Master節(jié)點的作業(yè)并將結果返回給Master節(jié)點。

    2.為什么要部署分布式環(huán)境?

    在Jenkins的分布式環(huán)境中,有以下幾個好處:

    1. 增加伸縮性:Jenkins的分布式環(huán)境中可以添加多個節(jié)點,將負載分散到不同的節(jié)點上,從而增加伸縮性。如果對Jenkins的使用量有要求,可以先添加一些節(jié)點,然后在需要的時候再添加更多節(jié)點。
    2. 提高性能:在集中式環(huán)境中,Jenkins會變得擁擠,當多個任務同時運行時,會導致性能下降。在分布式環(huán)境中,任務可以在不同的節(jié)點上運行,因此可以大大提高性能。
    3. 支持多種操作系統:Jenkins分布式環(huán)境可以在多種操作系統上運行,如Windows,Linux等,在不同的操作系統上運行構建可以更好的測試、驗證和分發(fā)。
    4. 更好的可靠性:在一個節(jié)點發(fā)生故障時,其他節(jié)點可以繼續(xù)運行任務,從而保證每個任務都能成功運行,增加了整個系統的可靠性。
    5. 更好的安全性:在分布式環(huán)境中,不同的節(jié)點可以采用不同的方式進行認證和授權,從而大大提高了Jenkins的安全性。

    總之,Jenkins分布式環(huán)境可以提供更好的性能、伸縮性、可靠性和安全性,使得整個系統更加高效、穩(wěn)定和安全。

    3.分布式環(huán)境建設計劃

    其實驅使我搭建分布式環(huán)境倒不是因為伸縮性不足、性能低下等方面的原因,而是我在一次Jenkins配置Maven項目、編譯后端springboot項目時,老是報Maven依賴庫錯誤的問題,最終導致編譯不過,嘗試了很多方法都沒有解決。但該項目在我本地的IDEA中是可以正常編譯通過的,于是我想了一個曲線救國的方案,就是在另一臺Windows機器上,搭建一套和我本機一模一樣的環(huán)境,將我本機的Maven倉庫整體打包復制過去,然后再安裝一個Jenkins,作為從節(jié)點使用。

    當前我只在一個單節(jié)點服務器上安裝了Jenkins,計劃在一臺Linux系統機器上安裝Jenkins作為從節(jié)點1,在另一臺Windows系統機器上安裝Jenkins作為從節(jié)點2。

    節(jié)點

    主機

    系統

    用途

    Master 主節(jié)點

    192.168.1.20

    CentOS 7

    分配、調度任務

    Slave 從節(jié)點1

    192.168.1.122

    CentOS 7

    編譯前端項目

    Slave 從節(jié)點2

    192.168.1.188

    Win 10

    編譯后端項目

    一、添加Linux從節(jié)點

    1.從節(jié)點環(huán)境配置

    ① 從節(jié)點安裝Jenkins

    所在服務器需要安裝Jenkins,版本最好與主節(jié)點Jenkins版本保持一致,安裝步驟參考前面的《Jenkins環(huán)境搭建&常見使用技巧》

    ② 從節(jié)點環(huán)境配置

    需要安裝Git以及相關插件,如果是編譯前端項目,需要配置nodejs,如果是編譯后端項目,還需要安裝maven等。前端環(huán)境配置可以參考前面的一篇《Jenkins實現前端項目自動化構建》

    2.添加從節(jié)點

    ① 創(chuàng)建從節(jié)點

    入口:系統管理-節(jié)點管理-添加節(jié)點,填寫從節(jié)點名稱,選擇固定節(jié)點

    ② 填寫從節(jié)點信息

    • Number of executors:執(zhí)行器數量,支持的最大job并發(fā)數,一般配置建議不超過當前節(jié)點電腦的CPU數量
    • 遠程工作目錄
    • 標簽:做調度策略時會用到
    • 用法:一般選擇第一個“Use this node as much as possible”(盡可能的使用這個節(jié)點)
    • 啟動方式:通過Java Web啟動代理

    注意最后“節(jié)點屬性”,可以勾選“工具位置”提前指定該機器中的如JDK等工具的路徑。

    剛添加好后的從節(jié)點處于不可用狀態(tài),還需要進行一堆的配置:

    ③ 主節(jié)點配置代理

    主節(jié)點:系統管理-全局安全配置-代理,指定一個代理端口(注意:從節(jié)點服務器防火墻一定要開放此端口

    ④ 從節(jié)點連接主節(jié)點

    在管理節(jié)點點擊查看新增的從節(jié)點詳情,會給出從節(jié)點如何連接主節(jié)點的提示:

    在從節(jié)點上執(zhí)行:

    # 下載agent.jar
    curl -sO http://192.168.1.20:8080/jenkins/jnlpJars/agent.jar
    # 連接主節(jié)點
    java -jar agent.jar -jnlpUrl http://192.168.1.20:8080/jenkins/manage/computer/h122/jenkins-agent.jnlp -secret 5d40fefd1148aa3e1461eb53a7764f655c030a7859cfa648b2340ba019146a3d -workDir "/home/jenkins/workspace"

    此時我的報錯了,提示42730端口不可用,也就是前面提到的從節(jié)點服務器防火墻一定要開放主節(jié)點中配置的代理端口

    防火墻開通端口號

    firewall-cmd --permanent --add-port 42730/tcp
    firewall-cmd --reload

    再次執(zhí)行連接命令后,連接成功

    但是這種啟動方式會一直處于前臺運行,此時終端窗口無法再進行其他操作。因此,可以給它創(chuàng)建一個啟動腳本,使其后臺運行。

    ⑤ 創(chuàng)建啟動腳本

    腳本內容如下:

    nohup java -jar agent.jar -jnlpUrl http://192.168.1.20:8080/jenkins/manage/computer/h122/jenkins-agent.jnlp -secret 5d40fefd1148aa3e1461eb53a7764f655c030a7859cfa648b2340ba019146a3d -workDir "/home/jenkins/workspace" 2>&1 >nohup.out  &

    運行腳本

    chmod +x start_agent.sh
    ./start_agent.sh

    3.測試構建項目

    在前面一篇《Jenkins實現前端項目自動化構建》中,已經在主節(jié)點成功構建運行了前端項目,此時我們再次構建該項目,看看它會不會在從節(jié)點運行。

    當我點擊構建時,該項目確實是通過我新建的從節(jié)點"h122"執(zhí)行構建的

    但出現了報錯"No such file or directory",提示項目路徑不存在:

    項目構建報錯問題排查

    • 項目的配置:

    • 控制臺輸出日志:

    • 原本在master節(jié)點上運行時生成的工作目錄路徑:

    • 轉到slave從節(jié)點上運行時生成的工作目錄路徑:

    經過一番排查,終于找到了原因:

    • 此項目原本是在主節(jié)點運行,我在主節(jié)點配置這個任務時,項目的路徑是寫死的:/home/jenkins/workspace/開普勒-前端,在主節(jié)點運行時確實有這個路徑,也能夠正常運行;
    • 但是我在配置從節(jié)點時設置的遠程工作目錄是:/home/jenkins/workspace,當從節(jié)點首次構建項目時,也會生成一個workspace目錄,并在這個workspace目錄下創(chuàng)建以項目名稱“開普勒-前端”為名字的工作目錄,最后疊加在一起,從節(jié)點上該項目真正的工作目錄就是 /home/jenkins/workspace/workspace/開普勒-前端。而此時從節(jié)點匹配不到原本的"/home/jenkins/workspace/開普勒-前端"這個目錄,所以運行失敗。

    項目構建報錯問題解決

    解決方式有兩種:

    1. 一種是修改從節(jié)點配置,將遠程工作目錄路徑去掉一層workspace目錄;
    2. 第二種是通過全局變量$WORKSPACE來聲明工作目錄;

    全局變量

    我用的是第二種,將構建步驟中原本的"cd /home/jenkins/workspace/開普勒-前端"改為"cd $WORKSPACE"

    再次構建,構建成功!

    企微群也收到了構建成功的消息通知:

    二、添加Windows從節(jié)點

    1.從節(jié)點環(huán)境配置

    ① 從節(jié)點安裝Jenkins

    同樣是需要先在Windows電腦上提前安裝好Jenkins。

    ② 從節(jié)點環(huán)境配置

    同樣需要安裝JDK、Git以及相關插件,如果是編譯前端項目,需要配置nodejs,如果是編譯后端項目,還需要安裝maven等。

    2.添加從節(jié)點

    ① 創(chuàng)建從節(jié)點

    入口:系統管理-節(jié)點管理-添加節(jié)點,填寫從節(jié)點名稱,選擇固定節(jié)點

    ② 填寫從節(jié)點信息

    同樣選擇“通過Java Web啟動代理

    在管理節(jié)點點擊查看新增的從節(jié)點詳情,會給出從節(jié)點如何連接主節(jié)點的提示:

    ③ 從節(jié)點連接主節(jié)點

    在從節(jié)點上執(zhí)行:

    curl -sO http://192.168.1.20:8080/jenkins/jnlpJars/agent.jar
    java -jar agent.jar -jnlpUrl http://192.168.1.20:8080/jenkins/manage/computer/win188/jenkins-agent.jnlp -secret ed74e189c3cf7012fac65f0c9af7e091a1159d36ebbef8c581491fccff40a1b5 -workDir "C:\Users\chenjigang\.jenkins"

    連接成功:

    此時會在我們配置的自定義工作目錄下自動創(chuàng)建生成remoting內部數據目錄

    創(chuàng)建完成,從節(jié)點win188處于在線狀態(tài):

    3.指定項目運行節(jié)點

    配置Jenkins項目

    比如我想為某個項目指定用這個從節(jié)點win188來運行,那么則可以在該項目配置-General中勾選“限制項目的運行節(jié)點”,并填寫標簽表達式,也就是前面我們填寫從節(jié)點時設置的標簽名稱“win188”

    構建該項目,可以看到,已經通過win188這個從節(jié)點來運行:

    報錯問題解決

    但是在運行的時候報錯了,提示maven路徑不存在,原因是此項目原本是在主節(jié)點(Linux)上運行的,該臺機器上的maven目錄是/home/apache-maven-3.6.3,而換到了從節(jié)點(Windows)系統運行以后,maven路徑不一致。

    需要在win188從節(jié)點配置中指定相關工具位置:

    再次運行,構建成功:

    小結

    以上就是Jenkins分別添加Linux從節(jié)點、Windows從節(jié)點以及構建過程中出現報錯問題排查解決的全部過程。總體來說,不管Linux從節(jié)點還是Windows從節(jié)點,步驟基本一致。關鍵的是如何合理利用好這些節(jié)點,從而物盡其用,使其發(fā)揮出更大價值!

    前面一篇文章理解 Kubernetes 的親和性調度,現在仔細回頭去看看,發(fā)現有很多地方沒有理解透徹,不夠深入,今天我們重新來理解下親和性調度這一塊知識。

    一般情況下我們部署的 Pod 是通過集群的自動調度策略來選擇節(jié)點的,默認情況下調度器考慮的是資源足夠,并且負載盡量平均,但是有的時候我們需要能夠更加細粒度的去控制 Pod 的調度,比如我們內部的一些服務 gitlab 之類的也是跑在Kubernetes集群上的,我們就不希望對外的一些服務和內部的服務跑在同一個節(jié)點上了,害怕內部服務對外部的服務產生影響;但是有的時候我們的服務之間交流比較頻繁,又希望能夠將這兩個服務的 Pod 調度到同一個的節(jié)點上。這就需要用到 Kubernetes 里面的一個概念:親和性和反親和性。

    親和性有分成節(jié)點親和性(nodeAffinity)和 Pod 親和性(podAffinity)。

    nodeSelector

    在了解親和性之前,我們先來了解一個非常常用的調度方式:nodeSelector。我們知道label是kubernetes中一個非常重要的概念,用戶可以非常靈活的利用 label 來管理集群中的資源,比如最常見的一個就是 service 通過匹配 label 去匹配 Pod 資源,而 Pod 的調度也可以根據節(jié)點的 label 來進行調度。

    我們可以通過下面的命令查看我們的 node 的 label:

    $ kubectl get nodes --show-labels
    NAME STATUS ROLES AGE VERSION LABELS
    master Ready master 147d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=master,node-role.kubernetes.io/master=node02 Ready <none> 67d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,course=k8s,kubernetes.io/hostname=node02
    node03 Ready <none> 127d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,jnlp=haimaxy,kubernetes.io/hostname=node03
    

    現在我們先給節(jié)點node02增加一個com=youdianzhishi的標簽,命令如下:

    $ kubectl label nodes node02 com=youdianzhishi
    node "node02" labeled
    

    我們可以通過上面的--show-labels參數可以查看上述標簽是否生效。當 node 被打上了相關標簽后,在調度的時候就可以使用這些標簽了,只需要在 Pod 的spec字段中添加nodeSelector字段,里面是我們需要被調度的節(jié)點的 label 即可。比如,下面的 Pod 我們要強制調度到 node02 這個節(jié)點上去,我們就可以使用 nodeSelector 來表示了:(node-selector-demo.yaml)

    apiVersion: v1
    kind: Pod
    metadata:
     labels:
     app: busybox-pod
     name: test-busybox
    spec:
     containers:
     - command:
     - sleep
     - "3600"
     image: busybox
     imagePullPolicy: Always
     name: test-busybox
     nodeSelector:
     com: youdianzhishi
    

    然后我們可以通過 describe 命令查看調度結果:

    $ kubectl create -f node-selector-demo.yaml
    pod "test-busybox" created
    $ kubectl describe pod test-busybox
    Name: test-busybox
    Namespace: default
    Node: node02/10.151.30.63
    ......
    QoS Class: BestEffort
    Node-Selectors: com=youdianzhishi
    Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
     node.kubernetes.io/unreachable:NoExecute for 300s
    Events:
     Type Reason Age From Message
     ---- ------ ---- ---- -------
     Normal SuccessfulMountVolume 55s kubelet, node02 MountVolume.SetUp succeeded for volume "default-token-n9w2d"
     Normal Scheduled 54s default-scheduler Successfully assigned test-busybox to node02
     Normal Pulling 54s kubelet, node02 pulling image "busybox"
     Normal Pulled 40s kubelet, node02 Successfully pulled image "busybox"
     Normal Created 40s kubelet, node02 Created container
     Normal Started 40s kubelet, node02 Started container
    

    我們可以看到 Events 下面的信息,我們的 Pod 通過默認的 default-scheduler 調度器被綁定到了node02節(jié)點。不過需要注意的是nodeSelector屬于強制性的,如果我們的目標節(jié)點沒有可用的資源,我們的 Pod 就會一直處于 Pending 狀態(tài),這就是nodeSelector的用法。

    通過上面的例子我們可以感受到nodeSelector的方式比較直觀,但是還夠靈活,控制粒度偏大,接下來我們再和大家了解下更加靈活的方式:節(jié)點親和性(nodeAffinity)。

    親和性和反親和性調度

    上節(jié)課我們了解了 kubernetes 調度器的一個調度流程,我們知道默認的調度器在使用的時候,經過了 predicates 和 priorities 兩個階段,但是在實際的生產環(huán)境中,往往我們需要根據自己的一些實際需求來控制 pod 的調度,這就需要用到 nodeAffinity(節(jié)點親和性)、podAffinity(pod 親和性) 以及 podAntiAffinity(pod 反親和性)。

    親和性調度可以分成軟策略硬策略兩種方式:

    • 軟策略就是如果你沒有滿足調度要求的節(jié)點的話,pod 就會忽略這條規(guī)則,繼續(xù)完成調度過程,說白了就是滿足條件最好了,沒有的話也無所謂了的策略
    • 硬策略就比較強硬了,如果沒有滿足條件的節(jié)點的話,就不斷重試直到滿足條件為止,簡單說就是你必須滿足我的要求,不然我就不干的策略。

    對于親和性和反親和性都有這兩種規(guī)則可以設置: preferredDuringSchedulingIgnoredDuringExecution和requiredDuringSchedulingIgnoredDuringExecution,前面的就是軟策略,后面的就是硬策略。

    這命名不覺得有點反人類嗎?有點無語……

    nodeAffinity

    節(jié)點親和性主要是用來控制 pod 要部署在哪些主機上,以及不能部署在哪些主機上的。它可以進行一些簡單的邏輯組合了,不只是簡單的相等匹配。

    比如現在我們用一個 Deployment 來管理3個 pod 副本,現在我們來控制下這些 pod 的調度,如下例子:(node-affinity-demo.yaml

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
     name: affinity
     labels:
     app: affinity
    spec:
     replicas: 3
     revisionHistoryLimit: 15
     template:
     metadata:
     labels:
     app: affinity
     role: test
     spec:
     containers:
     - name: nginx
     image: nginx:1.7.9
     ports:
     - containerPort: 80
     name: nginxweb
     affinity:
     nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
     nodeSelectorTerms:
     - matchExpressions:
     - key: kubernetes.io/hostname
     operator: NotIn
     values:
     - node03
     preferredDuringSchedulingIgnoredDuringExecution: # 軟策略
     - weight: 1
     preference:
     matchExpressions:
     - key: com
     operator: In
     values:
     - youdianzhishi
    

    上面這個 pod 首先是要求不能運行在 node03 這個節(jié)點上,如果有個節(jié)點滿足com=youdianzhishi的話就優(yōu)先調度到這個節(jié)點上。

    下面是我們測試的節(jié)點列表信息:

    $ kubectl get nodes --show-labels
    NAME STATUS ROLES AGE VERSION LABELS
    master Ready master 154d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=master,node-role.kubernetes.io/master=node02 Ready <none> 74d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,com=youdianzhishi,course=k8s,kubernetes.io/hostname=node02
    node03 Ready <none> 134d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,jnlp=haimaxy,kubernetes.io/hostname=node03
    

    可以看到 node02 節(jié)點有com=youdianzhishi這樣的 label,按要求會優(yōu)先調度到這個節(jié)點來的,現在我們來創(chuàng)建這個 pod,然后使用descirbe命令查看具體的調度情況是否滿足我們的要求。

    $ kubectl create -f node-affinity-demo.yaml
    deployment.apps "affinity" created
    $ kubectl get pods -l app=affinity -o wide
    NAME READY STATUS RESTARTS AGE IP NODE
    affinity-7b4c946854-5gfln 1/1 Running 0 47s 10.244.4.214 node02
    affinity-7b4c946854-l8b47 1/1 Running 0 47s 10.244.4.215 node02
    affinity-7b4c946854-r86p5 1/1 Running 0 47s 10.244.4.213 node02
    

    從結果可以看出 pod 都被部署到了 node02,其他節(jié)點上沒有部署 pod,這里的匹配邏輯是 label 的值在某個列表中,現在Kubernetes提供的操作符有下面的幾種:

    • In:label 的值在某個列表中
    • NotIn:label 的值不在某個列表中
    • Gt:label 的值大于某個值
    • Lt:label 的值小于某個值
    • Exists:某個 label 存在
    • DoesNotExist:某個 label 不存在

    如果nodeSelectorTerms下面有多個選項的話,滿足任何一個條件就可以了;如果matchExpressions有多個選項的話,則必須同時滿足這些條件才能正常調度 POD。

    podAffinity

    pod 親和性主要解決 pod 可以和哪些 pod 部署在同一個拓撲域中的問題(其中拓撲域用主機標簽實現,可以是單個主機,也可以是多個主機組成的 cluster、zone 等等),而 pod 反親和性主要是解決 pod 不能和哪些 pod 部署在同一個拓撲域中的問題,它們都是處理的 pod 與 pod 之間的關系,比如一個 pod 在一個節(jié)點上了,那么我這個也得在這個節(jié)點,或者你這個 pod 在節(jié)點上了,那么我就不想和你待在同一個節(jié)點上。

    由于我們這里只有一個集群,并沒有區(qū)域或者機房的概念,所以我們這里直接使用主機名來作為拓撲域,把 pod 創(chuàng)建在同一個主機上面。

    $ kubectl get nodes --show-labels
    NAME STATUS ROLES AGE VERSION LABELS
    master Ready master 154d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=master,node-role.kubernetes.io/master=node02 Ready <none> 74d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,com=youdianzhishi,course=k8s,kubernetes.io/hostname=node02
    node03 Ready <none> 134d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,jnlp=haimaxy,kubernetes.io/hostname=node03
    

    同樣,還是針對上面的資源對象,我們來測試下 pod 的親和性:(pod-affinity-demo.yaml)

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
     name: affinity
     labels:
     app: affinity
    spec:
     replicas: 3
     revisionHistoryLimit: 15
     template:
     metadata:
     labels:
     app: affinity
     role: test
     spec:
     containers:
     - name: nginx
     image: nginx:1.7.9
     ports:
     - containerPort: 80
     name: nginxweb
     affinity:
     podAffinity:
     requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
     - labelSelector:
     matchExpressions:
     - key: app
     operator: In
     values:
     - busybox-pod
     topologyKey: kubernetes.io/hostname
    

    上面這個例子中的 pod 需要調度到某個指定的主機上,至少有一個節(jié)點上運行了這樣的 pod:這個 pod 有一個app=busybox-pod的 label。

    我們查看有標簽app=busybox-pod的 pod 列表:

    $ kubectl get pods -o wide -l app=busybox-pod
    NAME READY STATUS RESTARTS AGE IP NODE
    test-busybox 1/1 Running 164 7d 10.244.4.205 node02
    

    我們看到這個 pod 運行在了 node02 的節(jié)點上面,所以按照上面的親和性來說,上面我們部署的3個 pod 副本也應該運行在 node02 節(jié)點上:

    $ kubectl get pods -o wide -l app=affinity
    NAME READY STATUS RESTARTS AGE IP NODE
    affinity-564f9d7db9-lzzvq 1/1 Running 0 3m 10.244.4.216 node02
    affinity-564f9d7db9-p79cq 1/1 Running 0 3m 10.244.4.217 node02
    affinity-564f9d7db9-spfzs 1/1 Running 0 3m 10.244.4.218 node02
    

    如果我們把上面的 test-busybox 和 affinity 這個 Deployment 都刪除,然后重新創(chuàng)建 affinity 這個資源,看看能不能正常調度呢:

    $ kubectl delete -f node-selector-demo.yaml
    pod "test-busybox" deleted
    $ kubectl delete -f pod-affinity-demo.yaml
    deployment.apps "affinity" deleted
    $ kubectl create -f pod-affinity-demo.yaml
    deployment.apps "affinity" created
    $ kubectl get pods -o wide -l app=affinity
    NAME READY STATUS RESTARTS AGE IP NODE
    affinity-564f9d7db9-fbc8w 0/1 Pending 0 2m <none> <none>
    affinity-564f9d7db9-n8gcf 0/1 Pending 0 2m <none> <none>
    affinity-564f9d7db9-qc7x6 0/1 Pending 0 2m <none> <none>
    

    我們可以看到處于Pending狀態(tài)了,這是因為現在沒有一個節(jié)點上面擁有busybox-pod這個 label 的 pod,而上面我們的調度使用的是硬策略,所以就沒辦法進行調度了,大家可以去嘗試下重新將 test-busybox 這個 pod 調度到 node03 這個節(jié)點上,看看上面的 affinity 的3個副本會不會也被調度到 node03 這個節(jié)點上去?

    我們這個地方使用的是kubernetes.io/hostname這個拓撲域,意思就是我們當前調度的 pod 要和目標的 pod 處于同一個主機上面,因為要處于同一個拓撲域下面,為了說明這個問題,我們把拓撲域改成beta.kubernetes.io/os,同樣的我們當前調度的 pod 要和目標的 pod 處于同一個拓撲域中,目標的 pod 是不是擁有beta.kubernetes.io/os=linux的標簽,而我們這里3個節(jié)點都有這樣的標簽,這也就意味著我們3個節(jié)點都在同一個拓撲域中,所以我們這里的 pod 可能會被調度到任何一個節(jié)點:

    $ kubectl get pods -o wide
    NAME READY STATUS RESTARTS AGE IP NODE
    affinity-7d86749984-glkhz 1/1 Running 0 3m 10.244.2.16 node03
    affinity-7d86749984-h4fb9 1/1 Running 0 3m 10.244.4.219 node02
    affinity-7d86749984-tj7k2 1/1 Running 0 3m 10.244.2.14 node03
    

    podAntiAffinity

    這就是 pod 親和性的用法,而 pod 反親和性則是反著來的,比如一個節(jié)點上運行了某個 pod,那么我們的 pod 則希望被調度到其他節(jié)點上去,同樣我們把上面的 podAffinity 直接改成 podAntiAffinity,(pod-antiaffinity-demo.yaml)

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
     name: affinity
     labels:
     app: affinity
    spec:
     replicas: 3
     revisionHistoryLimit: 15
     template:
     metadata:
     labels:
     app: affinity
     role: test
     spec:
     containers:
     - name: nginx
     image: nginx:1.7.9
     ports:
     - containerPort: 80
     name: nginxweb
     affinity:
     podAntiAffinity:
     requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
     - labelSelector:
     matchExpressions:
     - key: app
     operator: In
     values:
     - busybox-pod
     topologyKey: kubernetes.io/hostname
    

    這里的意思就是如果一個節(jié)點上面有一個app=busybox-pod這樣的 pod 的話,那么我們的 pod 就別調度到這個節(jié)點上面來,上面我們把app=busybox-pod這個 pod 固定到了 node03 這個節(jié)點上面來,所以正常來說我們這里的 pod 不會出現在 node03 節(jié)點上:

    $ kubectl create -f pod-antiaffinity-demo.yaml
    deployment.apps "affinity" created
    $ kubectl get pods -o wide
    NAME READY STATUS RESTARTS AGE IP NODE
    affinity-bcbd8854f-br8z8 1/1 Running 0 5s 10.244.4.222 node02
    affinity-bcbd8854f-cdffh 1/1 Running 0 5s 10.244.4.223 node02
    affinity-bcbd8854f-htb52 1/1 Running 0 5s 10.244.4.224 node02
    test-busybox 1/1 Running 0 23m 10.244.2.10 node03
    

    這就是 pod 反親和性的用法。

    污點(taints)與容忍(tolerations)

    對于nodeAffinity無論是硬策略還是軟策略方式,都是調度 pod 到預期節(jié)點上,而Taints恰好與之相反,如果一個節(jié)點標記為 Taints ,除非 pod 也被標識為可以容忍污點節(jié)點,否則該 Taints 節(jié)點不會被調度 pod。

    比如用戶希望把 Master 節(jié)點保留給 Kubernetes 系統組件使用,或者把一組具有特殊資源預留給某些 pod,則污點就很有用了,pod 不會再被調度到 taint 標記過的節(jié)點。我們使用kubeadm搭建的集群默認就給 master 節(jié)點添加了一個污點標記,所以我們看到我們平時的 pod 都沒有被調度到 master 上去:

    $ kubectl describe node master
    Name: master
    Roles: master
    Labels: beta.kubernetes.io/arch=amd64
     beta.kubernetes.io/os=linux
     kubernetes.io/hostname=master
     node-role.kubernetes.io/master=......
    Taints: node-role.kubernetes.io/master:NoSchedule
    Unschedulable: false
    ......
    

    我們可以使用上面的命令查看 master 節(jié)點的信息,其中有一條關于 Taints 的信息:node-role.kubernetes.io/master:NoSchedule,就表示給 master 節(jié)點打了一個污點的標記,其中影響的參數是NoSchedule,表示 pod 不會被調度到標記為 taints 的節(jié)點,除了 NoSchedule 外,還有另外兩個選項:

    • PreferNoSchedule:NoSchedule 的軟策略版本,表示盡量不調度到污點節(jié)點上去
    • NoExecute:該選項意味著一旦 Taint 生效,如該節(jié)點內正在運行的 pod 沒有對應 Tolerate 設置,會直接被逐出

    污點 taint 標記節(jié)點的命令如下:

    $ kubectl taint nodes node02 test=node02:NoSchedule
    node "node02" tainted
    

    上面的命名將 node02 節(jié)點標記為了污點,影響策略是 NoSchedule,只會影響新的 pod 調度,如果仍然希望某個 pod 調度到 taint 節(jié)點上,則必須在 Spec 中做出Toleration定義,才能調度到該節(jié)點,比如現在我們想要將一個 pod 調度到 master 節(jié)點:(taint-demo.yaml)

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
     name: taint
     labels:
     app: taint
    spec:
     replicas: 3
     revisionHistoryLimit: 10
     template:
     metadata:
     labels:
     app: taint
     spec:
     containers:
     - name: nginx
     image: nginx:1.7.9
     ports:
     - name: http
     containerPort: 80
     tolerations:
     - key: "node-role.kubernetes.io/master"
     operator: "Exists"
     effect: "NoSchedule"
    

    由于 master 節(jié)點被標記為了污點節(jié)點,所以我們這里要想 pod 能夠調度到 master 節(jié)點去,就需要增加容忍的聲明:

    tolerations:
    - key: "node-role.kubernetes.io/master"
     operator: "Exists"
     effect: "NoSchedule"
    

    然后創(chuàng)建上面的資源,查看結果:

    $ kubectl create -f taint-demo.yaml
    deployment.apps "taint" created
    $ kubectl get pods -o wide
    NAME READY STATUS RESTARTS AGE IP NODE
    ......
    taint-845d8bb4fb-57mhm 1/1 Running 0 1m 10.244.4.247 node02
    taint-845d8bb4fb-bbvmp 1/1 Running 0 1m 10.244.0.33 master
    taint-845d8bb4fb-zb78x 1/1 Running 0 1m 10.244.4.246 node02
    ......
    

    我們可以看到有一個 pod 副本被調度到了 master 節(jié)點,這就是容忍的使用方法。

    對于 tolerations 屬性的寫法,其中的 key、value、effect 與 Node 的 Taint 設置需保持一致, 還有以下幾點說明:

    • 1. 如果 operator 的值是 Exists,則 value 屬性可省略
    • 2. 如果 operator 的值是 Equal,則表示其 key 與 value 之間的關系是 equal(等于)
    • 3. 如果不指定 operator 屬性,則默認值為 Equal

    另外,還有兩個特殊值:

    • 1. 空的 key 如果再配合 Exists 就能匹配所有的 key 與 value,也是是能容忍所有 node 的所有 Taints
    • 2. 空的 effect 匹配所有的 effect

    最后,如果我們要取消節(jié)點的污點標記,可以使用下面的命令:

    $ kubectl taint nodes node02 test-
    node "node02" untainted
    

    這就是污點和容忍的使用方法。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有