1. 程式人生 > 實用技巧 >讀書筆記 | Kubernetes in Action

讀書筆記 | Kubernetes in Action

1 Kubernetes介紹

Kubernetes(以下簡稱K8s) 是一個部署和管理容器化應用的軟體系統。它將底層基礎設施抽象,簡化了應用的開發、部署,以及對開發和運維團隊的管理。

K8s由一個主節點和若干工作節點組成。開發者把應用描述提交到主節點,K8s會將描述中包含的容器映象部署到叢集的工作節點,開發者可以指定某些應用必須在一個工作節點一起執行(例如上圖五邊形和三角形應用),否則將被分散部署到叢集中。

2 在K8s中執行應用

2.1 執行容器

pod

K8s處理應用描述時,會指示容器執行時(例如Docker)拉取所需的映象並執行容器。但是,K8s並不直接處理單個容器,它的基本構建模組稱為pod。

一個pod是一組緊密相關的容器,總是一起執行在同一個工作節點上。使用這種方式,可以讓每個應用程序執行與自己的容器中,不相關的應用互相隔離,而密切相關的程序又可以作為一個單元進行管理。

pod的YAML描述檔案類似如下:

可以使用命令 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描述檔案類似如下:

下面是一些常用描述:

  • restartPolicy——需要明確設定重啟策略為OnFailure或Never(預設為Alwayse);
  • completions——需要一個Job執行的次數;
  • parallelism——同一Job並行執行的pod數量;
  • activeDeadlineSeconds——限制pod執行時間,超過將嘗試終止pod,並將pod標記為失敗;
  • backoffLimit——標記為失敗前可重試次數,預設為6;

下面是一些常用命令:

kubectl get jobs 	#列出Job

CronJob

CronJob是一種特殊的Job,用於在特定時間執行任務,或者在指定的時間間隔內重複執行。

CronJob的YAML描述檔案類似如下:

下面是一些常用描述:

  • restartPolicy——cron表示式;
  • jobTemplate——建立任務資源;
  • startingDeadlineSeconds——指定最遲必須在預定時間多少秒後開始執行,如未執行,任務將不會執行,並將顯示為Failed;

2.2 保持容器執行

Probe

一旦程式執行起來,K8s定期對pod進行狀態診斷,監控應用是否停止了工作,這種機制稱為探針(Probe)。

有三種探針:

  • livenessProbe——指示容器是否正在執行。如果失敗則終止容器,容器將遵循其重新啟動策略。需要使用initialDelaySeconds屬性設定初始延遲,保證容器已完成啟動再探測;
  • readinessProbe——指示容器是否準備好響應請求。如果失敗將刪除該pod的IP地址;
  • startupProb——指示容器中的應用程式是否啟動。如果提供了啟動探測,所有其他探測都將被禁用,直到它成功為止。如果失敗則終止容器,容器將遵循其重新啟動策略;

livenessProbe的YAML描述檔案類似如下:

每種探針有三種探測機制:

  • httpGet——對指定的埠和路徑執行HTTP GET 請求,如果響應狀態碼不是2xx和3xx則探測失敗;
  • tcpSocket——與指定埠建立TCP連線,如果連線失敗則探測失敗;
  • exec——在容器內執行任意命令,如果命令的退出狀態碼不是0則探測失敗;

ReplicaSet

如果pod停止工作,K8s會重新啟動它們,但是如果工作節點故障,那麼節點上的pod將會丟失。

ReplicaSet通常用來保證給定數量的、完全相同的 pod 的可用性,K8s會持續監控由ReplicaSet建立的正在執行的pod列表,並保證相應型別的pod的數目與期望相符。

ReplicaSet的YAML描述檔案類似如下:

下面是一些常用描述:

  • 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描述檔案類似如下:

升級需要做的就是在pod模板中修改映象的tag,K8s會收斂系統,匹配期望的狀態。

下面是一些常用描述:

  • maxSurge——期望的副本數之外,最多允許超出的pod例項數量;
  • maxUnavailable——相對於期望副本數,能夠允許有多少pod例項處於不可用狀態;
  • minReadySeconds——指定新建立的pod至少要執行多久之後,才能將其視為可用;
  • progressDeadlineSeconds——判定滾動升級失敗的超時時間;

2.3 遷移容器

Service

容器可能會重啟,或者增加、停止pod副本,如果容器需要給叢集中的其他容器或外部客戶端提供使用,如何讓客戶端發現正確的pod並與之通訊?

K8s服務是一種為一組功能相同的pod提供單一不變的接入點的資源。當服務存在時,它的IP地址和埠不會改變。

客戶端不需要知道單獨pod的地址,始終通過服務的IP地址和埠號建立連線。

Service的YAML描述檔案類似如下:

下面是一些常用描述:

  • 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描述檔案類似如下:

排程器只關注節點上部署的所有pod的資源requests之和,並不關注實際使用量。另外,CPU requests不僅僅在排程時起作用,也決定了未使用的CPU時間在容器之間會按照CPU requests比例分配。

limits的YAML描述檔案類似如下:

所有limits的總和可以超過節點資源的總量的100%——即超賣。如果節點使用量超過100%,一些容器將被殺掉。

在一個超賣的系統,QoS等級決定了哪個容器第一個被殺掉(BestEffort->Burstable->Guaranteed)。

HPA

指望靠人工干預來處理不可預測的流量增長不太現實,K8s可以檢測CPU使用率或其他度量增長時自動對它擴容。

HorizontalpodAutoscaler (HPA)資源啟用和配置Horizontal控制器,該控制器週期性檢查pod度量, 計算滿足HPA資源所配置的目標數值所需的副本數量, 進而調整目標資源的replicas欄位。

HPA的YAML描述檔案類似如下: