1. 程式人生 > >讀書筆記 | Kubernetes in Action

讀書筆記 | Kubernetes in Action

# 1 Kubernetes介紹 Kubernetes(以下簡稱K8s) 是一個部署和管理容器化應用的軟體系統。它將底層基礎設施抽象,簡化了應用的開發、部署,以及對開發和運維團隊的管理。 ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913231945150-2100385522.png) K8s由一個主節點和若干工作節點組成。開發者把應用描述提交到主節點,K8s會將描述中包含的容器映象部署到叢集的工作節點,開發者可以指定某些應用必須在一個工作節點一起執行(例如上圖五邊形和三角形應用),否則將被分散部署到叢集中。 # 2 在K8s中執行應用 ## 2.1 執行容器 ### pod K8s處理應用描述時,會指示容器執行時(例如Docker)拉取所需的映象並執行容器。但是,K8s並不直接處理單個容器,它的基本構建模組稱為pod。 一個pod是一組緊密相關的容器,總是一起執行在同一個工作節點上。使用這種方式,可以讓每個應用程序執行與自己的容器中,不相關的應用互相隔離,而密切相關的程序又可以作為一個單元進行管理。 pod的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232026374-631313978.png) 可以使用命令 `kubectl create -f kubia-manual.yaml` 建立一個pod。 下面是一些常用命令: ``` kubectl get po kubia-manual –o yaml #檢視描述 kubectl get pods #列出pod kubectl logs kubia-manual #檢視日誌 kubectl delete po kubia-manual #刪除pod ``` ### Job 一般pod都是持續執行的,即使容器內的程序執行結束,也會被排程重啟,永遠沒有完成狀態。而Job用於執行完成工作後就終止的情況。 Job會建立一種pod,該pod在內部程序成功結束時,不重啟容器,pod將處於完成狀態。由Job管理的pod,如果在節點上異常退出,會一直被重新安排,直到它完成任務。因此,需要保證任務是冪等的。 Job的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232108657-1891107037.png) 下面是一些常用描述: - restartPolicy——需要明確設定重啟策略為OnFailure或Never(預設為Alwayse); - completions——需要一個Job執行的次數; - parallelism——同一Job並行執行的pod數量; - activeDeadlineSeconds——限制pod執行時間,超過將嘗試終止pod,並將pod標記為失敗; - backoffLimit——標記為失敗前可重試次數,預設為6; 下面是一些常用命令: ``` kubectl get jobs #列出Job ``` ### CronJob CronJob是一種特殊的Job,用於在特定時間執行任務,或者在指定的時間間隔內重複執行。 CronJob的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232148786-1017450268.png) 下面是一些常用描述: - restartPolicy——cron表示式; - jobTemplate——建立任務資源; - startingDeadlineSeconds——指定最遲必須在預定時間多少秒後開始執行,如未執行,任務將不會執行,並將顯示為Failed; ## 2.2 保持容器執行 ### Probe 一旦程式執行起來,K8s定期對pod進行狀態診斷,監控應用是否停止了工作,這種機制稱為探針(Probe)。 有三種探針: - livenessProbe——指示容器是否正在執行。如果失敗則終止容器,容器將遵循其重新啟動策略。需要使用`initialDelaySeconds`屬性設定初始延遲,保證容器已完成啟動再探測; - readinessProbe——指示容器是否準備好響應請求。如果失敗將刪除該pod的IP地址; - startupProb——指示容器中的應用程式是否啟動。如果提供了啟動探測,所有其他探測都將被禁用,直到它成功為止。如果失敗則終止容器,容器將遵循其重新啟動策略; livenessProbe的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232241748-404708101.png) 每種探針有三種探測機制: - httpGet——對指定的埠和路徑執行HTTP GET 請求,如果響應狀態碼不是2xx和3xx則探測失敗; - tcpSocket——與指定埠建立TCP連線,如果連線失敗則探測失敗; - exec——在容器內執行任意命令,如果命令的退出狀態碼不是0則探測失敗; ### ReplicaSet 如果pod停止工作,K8s會重新啟動它們,但是如果工作節點故障,那麼節點上的pod將會丟失。 ReplicaSet通常用來保證給定數量的、完全相同的 pod 的可用性,K8s會持續監控由ReplicaSet建立的正在執行的pod列表,並保證相應型別的pod的數目與期望相符。 ReplicaSet的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232319463-308976928.png) 下面是一些常用描述: - replicas——指定pod例項的目標數目; - selector.matchLabels——匹配pod的標籤,還可以用matchExpressions屬性重寫選擇器; 下面是一些常用命令: ``` kubectl get rs #列出ReplicaSet kubectl describe rs #描述ReplicaSet ``` ### Deployment 當需要更新執行在pod的應用程式時,如何保證一組pod的例項正常執行?答案就是Deployment。 Deployment用於部署應用程式並以宣告的方式升級應用。Deployment由ReplicaSet組成,並由它接管Deployment的pod。使用Deployment可以直接定義單個Deployment資源需要達到的狀態,並讓K8s處理中間的狀態。 Deployment的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232354040-749764027.png) 升級需要做的就是在pod模板中修改映象的tag,K8s會收斂系統,匹配期望的狀態。 下面是一些常用描述: - maxSurge——期望的副本數之外,最多允許超出的pod例項數量; - maxUnavailable——相對於期望副本數,能夠允許有多少pod例項處於不可用狀態; - minReadySeconds——指定新建立的pod至少要執行多久之後,才能將其視為可用; - progressDeadlineSeconds——判定滾動升級失敗的超時時間; ## 2.3 遷移容器 ### Service 容器可能會重啟,或者增加、停止pod副本,如果容器需要給叢集中的其他容器或外部客戶端提供使用,如何讓客戶端發現正確的pod並與之通訊? K8s服務是一種為一組功能相同的pod提供單一不變的接入點的資源。當服務存在時,它的IP地址和埠不會改變。 客戶端不需要知道單獨pod的地址,始終通過服務的IP地址和埠號建立連線。 ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232432226-496525397.png) Service的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232503626-753680654.png) 下面是一些常用描述: - sessionAffinity——設定成ClientIP讓特定客戶端產生的請求每次都指向同一個pod; K8s為客戶端提供了多種服務發現方式: - 環境變數——建立了kubia服務,環境變數中有KUBIA_SERVICE_HOST和 KUBIA_SERVICE_PORT ,分別代表了 kubia 服務的 IP 地址和埠號; - 將服務型別設為NodePort——每個叢集節點都會開啟一個埠; - 將服務型別設為LoadBalance——通過一個專用的負載均衡器訪問; - 建立Ingress資源——它執行在HTTP層,可以將不同的服務對映到相同主機的不同路徑; ### requests和limits 開發人員通常不關心應用程式執行在哪臺伺服器上,只要伺服器能夠為應用程式提供足夠的系統資源。 可以指定容器對CPU和記憶體的資源請求量(requests)和資源限制量(limits),確保pod公平地使用K8s叢集資源,同時也影響著整個叢集pod的排程方式。 requests的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232535875-291713354.png) 排程器只關注節點上部署的所有pod的資源requests之和,並不關注實際使用量。另外,CPU requests不僅僅在排程時起作用,也決定了未使用的CPU時間在容器之間會按照CPU requests比例分配。 limits的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232614609-453716894.png) 所有limits的總和可以超過節點資源的總量的100%——即超賣。如果節點使用量超過100%,一些容器將被殺掉。 在一個超賣的系統,QoS等級決定了哪個容器第一個被殺掉(BestEffort->Burstable->Guaranteed)。 ### HPA 指望靠人工干預來處理不可預測的流量增長不太現實,K8s可以檢測CPU使用率或其他度量增長時自動對它擴容。 HorizontalpodAutoscaler (HPA)資源啟用和配置Horizontal控制器,該控制器週期性檢查pod度量, 計算滿足HPA資源所配置的目標數值所需的副本數量, 進而調整目標資源的replicas欄位。 HPA的YAML描述檔案類似如下: ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232651801-1984748775.png) ![](https://img2020.cnblogs.com/blog/9718/202009/9718-20200913232702152-515600984.p