Kubernetes 實(shí)戰(zhàn) —— 04. 副本機(jī)制和其他控制器:部署托管的 pod

保持 pod 健康 P84

只要 pod 調(diào)度到某個節(jié)點(diǎn),該節(jié)點(diǎn)上的 Kubelet 就會運(yùn)行 pod 的容器障斋,從此只要該 pod 存在,就會保持運(yùn)行徐鹤。如果容器的主進(jìn)程奔潰垃环, Kubelet 就會自動重啟容器;如果應(yīng)用程序奔潰返敬, Kubelet 就會自動重啟應(yīng)用程序晴裹。 P84

應(yīng)用程序也可能因?yàn)闊o限循環(huán)或死鎖等情況而停止響應(yīng)。為確保應(yīng)用在這種情況下可以重新啟動救赐,必須從外部檢查應(yīng)用程序的運(yùn)行狀況涧团,而不是依賴于應(yīng)用的內(nèi)部檢測。 P84

介紹存活探測器 P84

Kubernetes 可以通過存活探測器 (liveness probe) 檢查容器是否還在運(yùn)行经磅∶谛澹可以為 pod 中的每個容器單獨(dú)指定存活探測器。 Kubernetes 將定期執(zhí)行探測器预厌,如果探測失敗阿迈,就會自動重啟容器。 P84

注意:Kubernetes 還支持就緒探測器 (readiness probe) 轧叽,兩者適用于兩種不同的場景苗沧。 P84

Kubernetes 有三種探測容器的機(jī)制: P84

  • HTTP GET 探測器:對容器的 IP 地址(指定的端口和路徑)執(zhí)行 HTTP GET 請求。如果探測器收到響應(yīng)炭晒,并且響應(yīng)狀態(tài)碼不代表錯誤(狀態(tài)碼為 2xx 或 3xx )待逞,則認(rèn)為探測成功。如果服務(wù)器返回錯誤響應(yīng)狀態(tài)碼或者沒有響應(yīng)网严,那么探測就被認(rèn)為是失敗的识樱,容器將被重啟。
  • TCP Socket探測器:嘗試與容器指定端口建立 TCP 連接。如果連接成功建立怜庸,則探測成功当犯。否則,容器將被重啟割疾。
  • Exec 探測器:在容器內(nèi)執(zhí)行任意命令嚎卫,并檢查命令的退出狀態(tài)碼。如果狀態(tài)碼是 0 宏榕,則探測成功拓诸。所有其他狀態(tài)碼都被認(rèn)為失敗,容器將被重啟担扑。
創(chuàng)建基于 HTTP 的存活探測器 P85

為了讓 HTTP GET 探測器探測失敗,我們需要修改 kubia 源碼趣钱,使得其從第五次訪問之后開始一直返回 500 狀態(tài)碼 (Internal Server Error) 涌献。 P85

然后我們可以通過以下描述文件 kubia-liveness-probe.yaml 創(chuàng)建一個包含 HTTP GET 存活探測器的 pod 。 P85

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 資源類型為 Pod
kind: Pod
metadata:
  # pod 的名稱
  name: kubia-liveness
spec:
  containers:
    # 創(chuàng)建容器所使用的鏡像
    - image: idealism/kubia-unhealthy
      # 容器的名稱
      name: kubia
      ports:
        # 應(yīng)用監(jiān)聽的端口
        - containerPort: 8080
          protocol: TCP
      # 開啟一個存活探測器
      livenessProbe:
        # 存活探測器的類型為 HTTP GET
        httpGet:
          # 探測器連接的網(wǎng)絡(luò)端口
          port: 8080
          # 探測器請求的路徑
          path: /
使用存活探測器 P86

使用 kubectl create -f kubia-liveness-probe.yaml 創(chuàng)建完 pod 后首有,等待一段時間后燕垃,容器將會重啟【可以通過 kubectl get pod kubia-liveness 看到容器會重啟卜壕,并且無限循環(huán)下去: 86

NAME             READY   STATUS    RESTARTS   AGE
kubia-liveness   1/1     Running   2          4m9s

kubectl logs kubia-liveness --previous: 查看前一個容器的日志,可以了解前一個容器停止的原因烙常。 P86

kubectl describe pod kubia-liveness: 查看 pod 詳情轴捎。可以發(fā)現(xiàn)在 Containers 和 Events 里面有終止的相關(guān)信息蚕脏。 P86

...
Containers:
  kubia:
    ...
    State:          Running  # 容器目前正常運(yùn)行
      Started:      Sun, 07 Jun 2020 17:59:35 +0800
    Last State:     Terminated  # 前一個容器由于錯誤被終止侦副,錯誤碼是 137
      Reason:       Error
      Exit Code:    137
      Started:      Sun, 07 Jun 2020 17:57:44 +0800
      Finished:     Sun, 07 Jun 2020 17:59:27 +0800
    Ready:          True
    Restart Count:  2  # 該容器已被重啟 2 次
    Liveness:       http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
    ...
Events:
  Type     Reason     Age                  From                   Message
  ----     ------     ----                 ----                   -------
  Normal   Scheduled  <unknown>            default-scheduler      Successfully assigned default/kubia-liveness to minikube-m02
  Warning  Unhealthy  48s (x6 over 2m58s)  kubelet, minikube-m02  Liveness probe failed: HTTP probe failed with statuscode: 500  # 發(fā)現(xiàn)容器不健康
  Normal   Killing    48s (x2 over 2m38s)  kubelet, minikube-m02  Container kubia failed liveness probe, will be restarted  # 終止該容器
  ...

錯誤碼 137 是兩個數(shù)字的總和: 128 + x , x 是終止進(jìn)程的信號編號驼鞭。 P86

  • x=9 表示是 SIGKILL 的信號編號秦驯,意味著這個進(jìn)程被強(qiáng)行終止,這個信號不能被捕獲或忽略挣棕,并且在接收過程中不能執(zhí)行任何清理在接收到該信號
  • x=15 表示是 SIGTERM 的信號編號译隘,意味著這個進(jìn)程被終止,先進(jìn)行詢問進(jìn)程終止洛心,讓其清理文件和關(guān)閉固耘,可以被捕獲和解釋或忽略

底部列出的事件顯示了 Kubernetes 發(fā)現(xiàn)容器不健康,所以終止并重新創(chuàng)建词身。 P86

注意:當(dāng)容器被強(qiáng)行終止時玻驻,會創(chuàng)建一個全新的容器,而不是重啟原來的容器。 P86

配置存活探測器的附加屬性 P87

可以使用 kubectl explain pod.spec.containers.livenessProbe 查看存活探測器能使用的自定義附加參數(shù)璧瞬。

基于 kubia-liveness-probe.yaml 創(chuàng)建一個新的描述文件 kubia-liveness-probe-initial-delay.yaml 户辫,并添加 pod.spec.containers.livenessProbe.initialDelaySeconds 屬性,值為 15 嗤锉,表示在第一次探測器等待 15 秒渔欢。

...
spec:
  containers:
    # 創(chuàng)建容器所使用的鏡像
    - image: idealism/kubia-unhealthy
      ...
      # 開啟一個存活探測器
      livenessProbe:
        ...
        # 第一次探測前等待 15 秒
        initialDelaySeconds: 15

這樣可以在應(yīng)用程序準(zhǔn)備好之后再進(jìn)行探測,以免應(yīng)用程序啟動時間過長導(dǎo)致一直探測失敗而無限重啟瘟忱。

創(chuàng)建有效的存活探測器 P88
  • 存活探測器應(yīng)該檢查什么:簡易的存活探測器可以僅檢查服務(wù)器是否響應(yīng)奥额,但為了更好地進(jìn)行存活檢查,需要將探測器配置為請求特定的 URL 路徑(如 /health )访诱,并讓應(yīng)用從內(nèi)部對內(nèi)部運(yùn)行的所有重要組件執(zhí)行狀態(tài)檢查垫挨,以確保它們都沒有終止或停止響應(yīng)。 P88
    • 確保 /health 不需要認(rèn)證触菜,否則探測會一直失敗九榔,導(dǎo)致容器無限重啟
    • 檢查應(yīng)用的內(nèi)部,檢查結(jié)果不能受任何外部因素的影響涡相。例如數(shù)據(jù)庫連不上時哲泊,存活探測器不應(yīng)該返回失敗,如果問題在數(shù)據(jù)庫催蝗,那么重啟容器不會解決問題切威。
  • 保持探測器輕量 P89
    • 不應(yīng)消耗太多計(jì)算資源
    • 運(yùn)行不應(yīng)花太長時間。默認(rèn)情況下丙号,探測器執(zhí)行的頻率相對較高先朦,必須在一秒之內(nèi)執(zhí)行完畢
  • 無須在探測器中實(shí)現(xiàn)重試:探測器的失敗閾值是可配置的,并且通常在容器被終止之前探測器必須失敗多次 P89
  • 存活探測器小結(jié):存活探測由 pod 上的 Kubelet 執(zhí)行犬缨, Kubernetes 控制面板不會參與烙无。因此節(jié)點(diǎn)奔潰時,控制面板會為所有隨節(jié)點(diǎn)停止運(yùn)行的 pod 創(chuàng)建替代者遍尺,但不會為直接創(chuàng)建的 pod 創(chuàng)建替代者截酷,因?yàn)檫@些 pod 只被節(jié)點(diǎn)上的 Kubelet 管理。為了避免這種情況發(fā)生乾戏,我們應(yīng)該使用控制器或類似機(jī)制管理 pod 迂苛。 P89

了解 Deployment P89

:本節(jié)中提到的 pod 受 Deployment 管理等說法為簡化說法,實(shí)際上 pod 由受 Deployment 管理創(chuàng)建的 ReplicaSet 進(jìn)行管理創(chuàng)建鼓择。

Deployment 是一種 Kubernetes 資源三幻,可確保它的 pod 始終保持運(yùn)行狀態(tài)。如果 pod 因?yàn)槿魏卧蛳Вɡ绻?jié)點(diǎn)從集群中消失或由于該 pod 已從節(jié)點(diǎn)中逐出)呐能,則 Deployment 會注意到缺少了 pod 并創(chuàng)建替代者念搬。 P89

圖 4.1 節(jié)點(diǎn)故障時抑堡,只有 Deployment 管理的 pod 被重新創(chuàng)建.png

上圖的節(jié)點(diǎn) 1 有兩個節(jié)點(diǎn), Pod A 是被直接創(chuàng)建的朗徊,而 Pod B 由 Deployment 管理首妖。節(jié)點(diǎn)異常退出后, Deployment 會創(chuàng)建一個新的 Pod B2 來替換減少的 Pod B 爷恳,而 Pod A 由于沒有東西負(fù)責(zé)重建而完全丟失有缆。 P89

Deployment 的操作 P90

Deployment 會持續(xù)監(jiān)控正在運(yùn)行的 pod 列表,并保證匹配標(biāo)簽選擇器(03. pod: 運(yùn)行于 Kubernetes 中的容器 中介紹過標(biāo)簽選擇器及使用方式)的 pod 數(shù)目與期望相符温亲。 P90

介紹控制器的協(xié)調(diào)流程 P91

Deployment 的工作是確保 pod 數(shù)量始終與其標(biāo)簽選擇器匹配棚壁。 P91

圖 4.2 一個 Deployment 的協(xié)調(diào)流程.png

了解 Deployment 的三部分 P91

  • 標(biāo)簽選擇器 (label selector) :用于確定 Deployment 作用域中有哪些 pod
  • 副本個數(shù) (replica count) :指定應(yīng)運(yùn)行的 pod 數(shù)量
  • pod 模版 (pod template) :用于創(chuàng)建新的 pod 副本
圖 4.3 Deployment 的三個關(guān)鍵部分.png

Deployment 的副本個數(shù)、標(biāo)簽選擇器和 pod 模版都可以隨時修改栈虚,但只有副本數(shù)目但變更會影響現(xiàn)有的 pod 袖外。 P92

更改控制器的標(biāo)簽選擇器或 pod 模版的效果 P92

更改標(biāo)簽選擇器和 pod 模版對現(xiàn)有的 pod 沒有影響。更改標(biāo)簽選擇器會使現(xiàn)有的 pod 脫離 Deployment 的范圍魂务,因此控制器會停止關(guān)注它們曼验。更改模版僅影響由此 Deployment 創(chuàng)建的新 pod 。 P92

使用 Deployment 的好處 P92

  • 確保 pod 持續(xù)運(yùn)行:在現(xiàn)有 pod 丟失時啟動一個新 pod
  • 集群節(jié)點(diǎn)發(fā)生故障時头镊,為故障節(jié)點(diǎn)上運(yùn)行的受 Deployment 管理的所有 pod 創(chuàng)建替代副本
  • 輕松實(shí)現(xiàn) pod 水平伸縮——手動和自動都可以

注意: pod 實(shí)例永遠(yuǎn)不會重新安置到另一個節(jié)點(diǎn)蚣驼。 Deployment 會創(chuàng)建一個全新的 pod 實(shí)例魄幕,它與正在替換的實(shí)例無關(guān)相艇。 P92

創(chuàng)建一個 Deployment P92

我們可以通過以下描述文件 kubia-deployment.yaml 創(chuàng)建一個 Deployment ,它確保符合標(biāo)簽選擇器 app=kubia 的 pod 實(shí)例始終是三個纯陨。

# 遵循 v1 版本的 Kubernetes API
apiVersion: apps/v1
# 資源類型為 Deployment
kind: Deployment
metadata:
  # Deployment 的名稱
  name: kubia
spec:
  # 指定與標(biāo)簽選擇器匹配的 pod 數(shù)目為 3
  replicas: 3
  # 指定 Deployment 操作對象
  selector:
    # 需要匹配以下指定的標(biāo)簽
    matchLabels:
      app: kubia
  # 啟動 pod 使用的模版(可以發(fā)現(xiàn)模版內(nèi)容與 kubia-manual.yaml 對應(yīng)部分一致)
  template:
    metadata:
      # 指定標(biāo)簽為 app=kubia
      labels:
        app: kubia
    spec:
      containers:
        # 容器的名稱
        - name: kubia
          # 創(chuàng)建容器所使用的鏡像
          image: idealism/kubia
          # 應(yīng)用監(jiān)聽的端口
          ports:
            - containerPort: 8080
              protocol: TCP

模版中的 pod 標(biāo)簽必須和 Deployment 的標(biāo)簽選擇器匹配坛芽, API 服務(wù)器會校驗(yàn) Deployment 的定義,不會接受錯誤配置翼抠。 P93

若不指定選擇器咙轩,它會自動根據(jù) pod 模版中的標(biāo)簽自動配置,這樣可以讓描述文件更簡潔阴颖。 P93

使用 Deployment P94

kubectl create -f kubia-deployment.yaml 會創(chuàng)建一個名為 kubia 的 Deployment 活喊,它會根據(jù) pod 模版啟動三個新 pod 。 P94

kubectl get pods 可以查看當(dāng)前創(chuàng)建的所有 pod :

NAME                    READY   STATUS             RESTARTS   AGE
kubia-9495d9bf5-5dwj7   1/1     Running            0          3m53s
kubia-9495d9bf5-5j6zr   1/1     Running            0          3m53s
kubia-9495d9bf5-w98f6   1/1     Running            0          3m53s

查看 Deployment 對已刪除的 pod 的響應(yīng) P94

kubectl delete pod kubia-9495d9bf5-5dwj7 會刪除一個 pod 量愧,然后再次查看當(dāng)前所有 pod 钾菊,可以發(fā)現(xiàn)會有 4 個 pod ,因?yàn)閯h除的 pod 正在終止偎肃,并且正在創(chuàng)建一個新的 pod : P94

NAME                    READY   STATUS              RESTARTS   AGE
kubia-9495d9bf5-5dwj7   1/1     Terminating         0          24m
kubia-9495d9bf5-5j6zr   1/1     Running             0          24m
kubia-9495d9bf5-kxcw5   0/1     ContainerCreating   0          9s
kubia-9495d9bf5-w98f6   1/1     Running             0          24m

控制器如何創(chuàng)建新的 pod P95

控制器通過創(chuàng)建一個新的替代 pod 來響應(yīng) pod 的刪除操作煞烫。但它并沒有對刪除本身作出反應(yīng),而是針對由此產(chǎn)生對狀態(tài)—— pod 數(shù)量不足作出反應(yīng)累颂。 P95

圖 4.4 如果一個 pod 消失滞详, Deployment 將發(fā)現(xiàn) pod 數(shù)目就更少并創(chuàng)建一個新的替代 pod.png

應(yīng)對節(jié)點(diǎn)故障 P96

接下來我們將關(guān)閉一個節(jié)點(diǎn)的網(wǎng)絡(luò)接口來模擬節(jié)點(diǎn)故障。 P96

  1. minikube ssh --node='m02': 進(jìn)入節(jié)點(diǎn)內(nèi)部
  2. sudo ifconfig eth0 down: 關(guān)閉該節(jié)點(diǎn)的網(wǎng)絡(luò)接口
  3. kubectl get nodes: 發(fā)現(xiàn)節(jié)點(diǎn) minikube-m02 的狀態(tài)為未就緒 (NotReady)
  4. kubectl get pods: 可能仍然會看到與之前相同的三個 pod ,因?yàn)?Kubernetes 在重新調(diào)度 pod 之前會等待一段時間(如果節(jié)點(diǎn)因臨時網(wǎng)絡(luò)故障或 Kubelet 重啟而無法訪問)料饥。如果節(jié)點(diǎn)在幾分鐘內(nèi)無法訪問蒲犬, Deployment 會立即啟動一個新的 pod 。

將 pod 移入/移出 Deployment 的作用域 P97

Deployment 創(chuàng)建的 pod 并不是綁定到 Deployment 稀火。在任何時刻暖哨, Deployment 管理與標(biāo)簽選擇器匹配的 pod 。通過更改 pod 的標(biāo)簽凰狞,可以將它從 Deployment 的作用域中添加或刪除篇裁。 P97

盡管一個 pod 沒有綁定到一個 Deployment 擁有的 ReplicaSet ,但該 pod 在 metadata.ownerReferences 中存儲它屬于哪一個 ReplicaSet 赡若。 P98

Deployment 管理的 pod 加標(biāo)簽 P98

kubectl label pod kubia-9495d9bf5-5mmhb type=special: 給 pod 添加其他標(biāo)簽不會影響 Deployment 的管理范圍达布,它只關(guān)心該 pod 是否具有標(biāo)簽選擇器中引用的所有標(biāo)簽。 P98

更改已托管的 pod 的標(biāo)簽 P98

kubectl label pod kubia-9495d9bf5-5mmhb app=foo --overwrite: 更改其中一個 pod 的標(biāo)簽將使其不再與 Deployment 的標(biāo)簽選擇器相匹配逾冬,并不再由 Deployment 管理黍聂,只剩下兩個匹配的 pod 。因此身腻, Deployment 會啟動一個新的 pod 产还,將數(shù)目恢復(fù)為三。 P98

圖 4.5 通過更改標(biāo)簽從 Deployment 的作用域中刪除一個 pod.png

更改 Deployment 的標(biāo)簽選擇器 P100

更改 Deployment 的標(biāo)簽選擇器會讓所有的 pod 脫離 Deployment 的管理嘀趟,導(dǎo)致它創(chuàng)建三個新的 pod 脐区。你永遠(yuǎn)不會修改控制器的標(biāo)簽選擇器,但會時不時地更改它的 pod 模版她按。 P100

修改 pod 模版 P100

Deployment 的 pod 模版可以隨時修改牛隅,可以使用 kubectl edit deployment kubia 編輯 Deployment 。更改后會重新創(chuàng)建一個新的 ReplocaSet 酌泰,并使原有的 ReplocaSet 的副本數(shù)變?yōu)?0 媒佣。因此,使用 kubectl get pods 將發(fā)現(xiàn)有 6 個 pod 陵刹,pod 的前綴是對應(yīng)的 ReplocaSet 的名稱默伍。

NAME                    READY   STATUS        RESTARTS   AGE
kubia-9495d9bf5-kxcw5   1/1     Terminating   0          78m
kubia-9495d9bf5-w98f6   1/1     Terminating   0          102m
kubia-9495d9bf5-xn67d   1/1     Terminating   0          29m
kubia-bc974964b-bp4l2   1/1     Running       0          22s
kubia-bc974964b-r29j2   1/1     Running       0          39s
kubia-bc974964b-xl677   1/1     Running       0          14s

若通過 kubectl edit replicaset kubia-bc974964b 直接修改 Deployment 擁有的 ReplicaSet 實(shí)例。這樣效果和直接修改 Deployment 類似衰琐,也會創(chuàng)建一個新的 ReplicaSet 也糊,并使原有的 ReplocaSet 的副本數(shù)變?yōu)?0 。這樣修改不會將新的 pod 模版同步回原有的 Deployment 碘耳,但刪除 Deployment 時仍然會刪除所有相關(guān)的 ReplocaSet 及其管理的 pod 显设。

水平縮放 pod P101

kubectl scale deployment kubia --replicas=10: 可以修改 Deployment 需要保持的 pod 實(shí)例的數(shù)量(02. 開始使用 Kubernetes 和 Docker中介紹過使用該命令進(jìn)行伸縮)。 P101

也可以通過 kubectl edit deployment kubia 修改 spec.replicas 的數(shù)量辛辨,從而更改需要保持的 pod 實(shí)例的數(shù)量捕捂。 P102

刪除一個 Deployment

當(dāng)通過 kubectl delete deployment kubia 刪除 Deployment 時瑟枫,對應(yīng)的 ReplicaSet 和 pod 都會被刪除。

而通過 kubectl delete replicaset kubia-bc974964b 刪除 ReplicaSet 時指攒,對應(yīng)的 pod 會被刪除慷妙,但由于 Deployment 會重新創(chuàng)建一個 Replicaset ,所以又會自動創(chuàng)建對應(yīng)數(shù)量的 pod 允悦。

圖 4.7 使用 --cascade=false 刪除 ReplicaSet 使 pod 不受管理.png

當(dāng)通過 kubectl delete deployment kubia --cascade=false 刪除 Deployment 時膝擂,會保留對應(yīng)的 ReplicaSet 和 pod ,這樣ReplicaSet 不再受管理隙弛,但是 pod 仍然受 ReplicaSet 管理架馋。當(dāng)重新創(chuàng)建符合要求的 Deployment 時, ReplicaSet 又會受到管理全闷。

同樣地叉寂,通過 kubectl delete replicaset kubia-bc974964b --cascade=false 刪除 ReplicaSet 時,也會保留對應(yīng)的 pod 总珠。這樣 pod 不再受管理屏鳍。當(dāng)創(chuàng)建符合要求的 ReplicaSet 時,這些 pod 又會受到管理局服。

使用 ReplicaSet P104

:書中原本上一節(jié)講得是 ReplicationController 钓瞭,但我直接使用 Deployment 進(jìn)行實(shí)踐,并依照現(xiàn)在的結(jié)果進(jìn)行了修改淫奔。目前推薦使用 Deployment 山涡,并且 ReplicaSet 是受 Deployment 管理的,所以不再詳細(xì)實(shí)踐本節(jié)內(nèi)容搏讶。

使用更富有表達(dá)力的標(biāo)簽選擇器 P106

基于 kubia-deployment.yaml 創(chuàng)建一個新的描述文件 kubia-deployment-matchexpressions.yaml 佳鳖,并將 spec.selector.matchLabels 屬性替換為 spec.selector.matchExpressionsP107

...
spec:
  ...
  # 指定 Deployment 操作對象
  selector:
    # 需要匹配滿足以下要求的標(biāo)簽
    matchExpressions:
      # 標(biāo)簽名為 app 的值在 ["kubia"] 中
      - app: app
        operator: In
        values:
          - kubia
  ...

matchExpressions 運(yùn)行給選擇器添加額外的表達(dá)式霍殴。每個表達(dá)式都必須包含一個 key 媒惕、一個 operator ,并且可能還有一個 values 的列表(取決于 operator )来庭。共有四個有效的運(yùn)算符: P107

  • In: 標(biāo)簽的值必須與其中一個指定的 values 匹配
  • NotIn: 標(biāo)簽的值與任何指定的 values 都不匹配
  • Exists: pod 必須包含一個指定名稱的標(biāo)簽(不關(guān)心值)妒蔚。使用此運(yùn)算符時,不應(yīng)指定 values 字段
  • DoesNotExist: pod 不得包含指定名稱的標(biāo)簽月弛。使用此運(yùn)算符時肴盏,不應(yīng)指定 values 字段

如果指定了多個表達(dá)式,則所有這些表達(dá)式都必須為 true 才能使選擇器與 pod 匹配帽衙。如果同時指定 matchLabelsmatchExpressions 菜皂,則所有標(biāo)簽都必須匹配,且所有表達(dá)式都必須為 true 才能使選擇器與 pod 匹配厉萝。 P107

使用 DaemonSet 在每個節(jié)點(diǎn)上運(yùn)行一個 pod P107

DaemonSet 可以讓 pod 在集群中的每個節(jié)點(diǎn)上運(yùn)行恍飘,并且每個節(jié)點(diǎn)正好有一個運(yùn)行的 pod 實(shí)例榨崩。 P107

圖 4.8 DaemonSet 在每個節(jié)點(diǎn)上只運(yùn)行一個 pod 副本.png
使用 DaemonSet 在每個節(jié)點(diǎn)上運(yùn)行一個 pod P108

DaemonSet 沒有副本數(shù)的概念,它確保創(chuàng)建足夠的 pod 章母,并在每一個節(jié)點(diǎn)上部署一個 pod 母蛛。如果節(jié)點(diǎn)下線, DaemonSet 不會重新創(chuàng)建 pod 乳怎;但新節(jié)點(diǎn)添加到集群中彩郊,它會立刻部署一個新的 pod 實(shí)例到該節(jié)點(diǎn)。 P108

使用 DaemonSet 只在特定的節(jié)點(diǎn)上運(yùn)行 pod P109

DaemonSet 將 pod 部署到集群的所有節(jié)點(diǎn)上蚪缀,除非通過 pod 模版中的 spec.nodeSelector 屬性指定這些 pod 只在部分節(jié)點(diǎn)上運(yùn)行秫逝。 P109

注意:節(jié)點(diǎn)可以被設(shè)置為不可調(diào)度,防止 pod 被部署到節(jié)點(diǎn)上询枚。但 DaemonSet 會將 pod 部署到這些節(jié)點(diǎn)上筷登,因?yàn)闊o法調(diào)度但屬性只會被調(diào)度器使用,而 DaemonSet 的目的是運(yùn)行系統(tǒng)服務(wù)哩盲,即使在不可調(diào)度的節(jié)點(diǎn)上前方,系統(tǒng)服務(wù)通常也需要運(yùn)行。 P109

用一個例子來解釋 DaemonSet P109

假設(shè)有一個名為 ssd-monitor 的守護(hù)進(jìn)程廉油,它需要在包含 SSD 的所有節(jié)點(diǎn)上運(yùn)行惠险。包含 SSD 的節(jié)點(diǎn)已被添加了 disk=ssd 標(biāo)簽,所以我們需要創(chuàng)建一個 DaemonSet 抒线,它只在擁有上述標(biāo)簽的節(jié)點(diǎn)上運(yùn)行守護(hù)進(jìn)程班巩。 P109

圖 4.9 使用含有節(jié)點(diǎn)選擇器的 DaemonSet 在特定的節(jié)點(diǎn)上部署 pod.png

創(chuàng)建一個 DaemonSet 描述文件 P110

為了模擬 ssd-monitor 的監(jiān)控程序,我們將使用以下 Dockerfile 創(chuàng)建一個每 5 秒中打印 SSD OK 的鏡像嘶炭。

FROM busybox
ENTRYPOINT while true; do echo 'SSD OK'; sleep 5; done

為了將 ssd-monitor 部署到符合要求的每個節(jié)點(diǎn)上抱慌,我們還需要使用以下 ssd-monitor-daemonset.yaml 描述文件進(jìn)行部署。

# 遵循 apps/v1 版本的 Kubernetes API
apiVersion: apps/v1
# 資源類型為 DaemonSet
kind: DaemonSet
metadata:
  # DaemonSet 的名稱
  name: ssd-monitor
spec:
  # 指定 DaemonSet 操作對象
  selector:
    # 需要匹配以下指定的標(biāo)簽
    matchLabels:
      app: ssd-monitor
  # 啟動 pod 使用的模版
  template:
    metadata:
      # 指定標(biāo)簽為 app=ssd-monitor
      labels:
        app: ssd-monitor
    spec:
      # 指定選擇具有 disk=ssd 標(biāo)簽的節(jié)點(diǎn)部署
      nodeSelector:
        disk: ssd
      containers:
        # 容器的名稱
        - name: main
          # 創(chuàng)建容器所使用的鏡像
          image: idealism/ssd-monitor

實(shí)踐 P110

  1. kubectl create -f ssd-monitor-daemonset.yaml: 按照指定的描述文件創(chuàng)建一個 DaemonSet
  2. kubectl get daemonsets: 可以發(fā)現(xiàn)所有的值都是 0 眨猎,因?yàn)槟壳斑€沒有節(jié)點(diǎn)擁有 disk=ssd 標(biāo)簽
  3. kubectl get pods: 可以發(fā)現(xiàn)目前還沒有 pod
  4. kubectl label node minikube-m03 disk=ssd: 給節(jié)點(diǎn) minikube-m03 打上標(biāo)簽 disk=ssd
  5. kubectl get pods: 可以發(fā)現(xiàn)剛剛啟動了一個 pod
    NAME                    READY   STATUS              RESTARTS   AGE
    ssd-monitor-bbqbp       0/1     ContainerCreating   0          2s
    
  6. kubectl label node minikube-m03 disk=hdd --overwrite: 將節(jié)點(diǎn) minikube-m03 的標(biāo)簽 disk=ssd 修改為 disk=hdd
  7. kubectl get pods: 可以發(fā)現(xiàn)剛剛啟動的 pod 正在終止
    NAME                    READY   STATUS        RESTARTS   AGE
    ssd-monitor-bbqbp       1/1     Terminating   0          2m37s
    

運(yùn)行執(zhí)行單個任務(wù)的 pod P112

介紹 Job 資源 P112

Kubernetes 通過 Job 資源支持運(yùn)行一種 pod 抑进,該 pod 子啊內(nèi)部進(jìn)程成功結(jié)束時,不重啟容器睡陪。一旦任務(wù)完成寺渗, pod 就被認(rèn)為處于完成狀態(tài)。 P112

在節(jié)點(diǎn)發(fā)生故障時兰迫,該節(jié)點(diǎn)上由 Job 管理的 pod 將被重新安排到其他節(jié)點(diǎn)信殊。如果進(jìn)程本身異常退出(進(jìn)程返回錯誤退出碼時),可以將 Job 配置為重新啟動容器汁果。 P112

圖 4.10 由 Job 管理的 pod 會一直被重新安排涡拘,知道它們成功完成任務(wù).png
定義 Job 資源 P113

為了模擬耗時的任務(wù),我們將使用以下 Dockerfile 創(chuàng)建一個調(diào)用 sleep 120 命令的鏡像据德。

FROM busybox
ENTRYPOINT echo "$(date) Batch job starting"; sleep 120; echo "$(date) Finished succesfully"

為了管理部署 batch-job 鳄乏,我們還需要使用以下 batch-job.yaml 描述文件進(jìn)行部署府蔗。

# 遵循 batch/v1 版本的 Kubernetes API
apiVersion: batch/v1
# 資源類型為 Job
kind: Job
metadata:
  # Job 的名稱
  name: batch-job
spec:
  # 啟動 pod 使用的模版
  template:
    metadata:
      # 指定標(biāo)簽為 app=batch-job
      labels:
        app: batch-job
    spec:
      # Job 不能使用 Always 為默認(rèn)的重啟策略
      restartPolicy: OnFailure
      containers:
        # 容器的名稱
        - name: main
          # 創(chuàng)建容器所使用的鏡像
          image: idealism/batch-job

設(shè)置 Job 的重啟策略為 OnFailureNever 可以防止容器在完成任務(wù)時重新啟動。 P114

Job 運(yùn)行一個 pod P114
  1. kubectl create -f batch-job.yaml: 根據(jù)描述文件創(chuàng)建指定的 Job
  2. kubectl get jobs: 查看 job 汞窗,可以發(fā)現(xiàn)剛剛創(chuàng)建的 Job
    NAME        COMPLETIONS   DURATION   AGE
    batch-job   0/1           5s         5s
    
  3. kubectl get pods: 查看 pod 姓赤,可以發(fā)現(xiàn) Job 創(chuàng)建的 pod 正在運(yùn)行
    NAME                    READY   STATUS        RESTARTS   AGE
    batch-job-d59js         1/1     Running       0          10s
    
  4. kubectl get pods: 等兩分鐘后再查看 pod ,可以發(fā)現(xiàn) Job 創(chuàng)建的 pod 狀態(tài)已經(jīng)變?yōu)?Completed 仲吏,即任務(wù)已經(jīng)完成不铆。 pod 未被刪除,所以我們可以查看 pod 的日志
    NAME                    READY   STATUS        RESTARTS   AGE
    batch-job-d59js         0/1     Completed     0          2m56s
    
  5. kubectl logs pod batch-job-d59js: 查看 pod 的日志
    Sun Jun  7 22:36:04 UTC 2020 Batch job starting
    Sun Jun  7 22:38:04 UTC 2020 Finished succesfully
    
  6. kubectl get jobs: 再次查看 job 裹唆,可以發(fā)現(xiàn)需要運(yùn)行的 1 個 pod 已經(jīng)完成
    NAME        COMPLETIONS   DURATION   AGE
    batch-job   1/1           2m45s      6m25s
    
Job 中運(yùn)行多個 pod 實(shí)例 P114

Job 配置中設(shè)置 spec.completionsspec.parallelism 可以讓 Job 創(chuàng)建多個 pod 實(shí)例誓斥,并允許以并行的方式運(yùn)行它們。 P114

基于 batch-job.yaml 創(chuàng)建一個新的描述文件 multi-completion-parallel-batch-job.yaml 许帐,并添加 spec.completionsspec.parallelism 屬性劳坑,指定需要成功運(yùn)行完成 5 個 pod ,最多 2 個 pod 并行運(yùn)行 : P115

...
spec:
  # 必須確保 5 個 pod 運(yùn)行完成
  completions: 5
  # 最多 2 個 pod 可以并行運(yùn)行
  parallelism: 2
  ...
  1. kubectl create -f multi-completion-parallel-batch-job.yaml: 根據(jù)描述文件創(chuàng)建指定的 Job

  2. kubectl get pods: 查看運(yùn)行的 pod 成畦,可以發(fā)現(xiàn)共有兩個 pod 正在運(yùn)行距芬。只要一個 pod 運(yùn)行完成, Job 將運(yùn)行下一個 pod 循帐,直至 5 個 pod 都成功完成

    NAME                                        READY   STATUS        RESTARTS   AGE
    multi-completion-parallel-batch-job-fpwv5   1/1     Running       0          37s
    multi-completion-parallel-batch-job-m4cqw   1/1     Running       0          37s
    
限制 Job pod 完成任務(wù)的時間 P116
  • Pod.spec.activeDeadlineSeconds: 可以指定一個 pod 最長存活時間框仔,超時則終止 pod 并標(biāo)記 Job 失敗,可以用來限制 pod 完成任務(wù)的時間
  • Job.spec.backoffLimit: 可以配置一個 Job 在被標(biāo)記為失敗前最多嘗試的次數(shù)拄养,默認(rèn)為 6 次

安排 Job 定期運(yùn)行或在將來運(yùn)行一次 P116

創(chuàng)建一個 CronJob P116

為了每 15 分鐘運(yùn)行一次前面的任務(wù)离斩,我們需要創(chuàng)建以下 cronjob.yaml 描述文件:

# 遵循 batch/v1beta1 版本的 Kubernetes API
apiVersion: batch/v1beta1
# 資源類型為 CronJob
kind: CronJob
metadata:
  # Job 的名稱
  name: batch-job-every-fifteen-minutes
spec:
  # Cron 表達(dá)式表明當(dāng)前任務(wù)在每天每小時的 0, 15, 30, 45 分運(yùn)行
  schedule: "0,15,30,45 * * * *"
  # 指定最遲必須在預(yù)定時間后 15 秒內(nèi)開始運(yùn)行,否則就標(biāo)記為一次失敗的 `Job`
  startingDeadlineSeconds: 15
  # 創(chuàng)建 Job 使用的模版(可以發(fā)現(xiàn)和 batch-job.yaml 的 spec 部分基本一致)
  jobTemplate:
    spec:
      # 啟動 pod 使用的模版
      template:
        metadata:
          # 指定標(biāo)簽為 app=periodic-batch-job
          labels:
            app: periodic-batch-job
        spec:
          # Job 不能使用 Always 為默認(rèn)的重啟策略
          restartPolicy: OnFailure
          containers:
            # 容器的名稱
            - name: main
              # 創(chuàng)建容器所使用的鏡像
              image: idealism/batch-job

kubectl get cronjobs: 可以查看所有的 CronJob

NAME                              SCHEDULE             SUSPEND   ACTIVE   LAST SCHEDULE   AGE
batch-job-every-fifteen-minutes   0,15,30,45 * * * *   False     0        <none>          8s

CronJob 總是為計(jì)劃中配置的每個執(zhí)行創(chuàng)建一個 Job 瘪匿,但可能會有以下兩種問題:

  • 同時創(chuàng)建兩個 Job :保證任務(wù)是冪等的
  • 沒有創(chuàng)建 Job :保證下一個任務(wù)能運(yùn)行完成錯過的任何工作
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末跛梗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子棋弥,更是在濱河造成了極大的恐慌核偿,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘁锯,死亡現(xiàn)場離奇詭異宪祥,居然都是意外死亡聂薪,警方通過查閱死者的電腦和手機(jī)家乘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來藏澳,“玉大人仁锯,你說我怎么就攤上這事∠栌疲” “怎么了业崖?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵野芒,是天一觀的道長。 經(jīng)常有香客問我双炕,道長狞悲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任妇斤,我火速辦了婚禮摇锋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘站超。我一直安慰自己荸恕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布死相。 她就那樣靜靜地躺著融求,像睡著了一般。 火紅的嫁衣襯著肌膚如雪算撮。 梳的紋絲不亂的頭發(fā)上吃度,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天,我揣著相機(jī)與錄音庇勃,去河邊找鬼橄杨。 笑死,一個胖子當(dāng)著我的面吹牛素挽,可吹牛的內(nèi)容都是我干的蔑赘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼预明,長吁一口氣:“原來是場噩夢啊……” “哼缩赛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撰糠,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酥馍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后阅酪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旨袒,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年术辐,在試婚紗的時候發(fā)現(xiàn)自己被綠了砚尽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡辉词,死狀恐怖必孤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瑞躺,我是刑警寧澤敷搪,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布兴想,位于F島的核電站,受9級特大地震影響赡勘,放射性物質(zhì)發(fā)生泄漏嫂便。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一闸与、第九天 我趴在偏房一處隱蔽的房頂上張望顽悼。 院中可真熱鬧,春花似錦几迄、人聲如沸蔚龙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽木羹。三九已至,卻和暖如春解孙,著一層夾襖步出監(jiān)牢的瞬間坑填,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工弛姜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脐瑰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓廷臼,卻偏偏與公主長得像苍在,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子荠商,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評論 2 359

推薦閱讀更多精彩內(nèi)容