-
Pod詳解
作為Kubernetes調度的最小單位,學習Pod的細節有助於理解Kubernetes整個系統的工作流程,這里將深入理解Pod的相關原理,學習Pod的主要操作。
-
Pod配置詳解
下面以一份完整的Pod配置文件來了解Pod的定義,使用<>表示該位置一般來說必須填寫相應的內容,使用[]表示該位置的值可以為空或者不寫該標簽。
首先是Pod定義的元數據部分,apiVersion表示使用的api版本,kind 表示資源類型是Pod; metadata定義了這個Pod的元數據, 包括名稱、名字空間、標簽以及注釋。
下面來看Pod的容器規則,依舊截斷文件來看。imagePullPolicy表示鏡像啟動時是否拉取最新版本的鏡像,有三個值可以選擇:Always表示總是拉取最新版本鏡像,Never表示不自動拉取最新鏡像,默認是IfNotPresent。默認表示本地不存在鏡像就拉取鏡像,但如果在鏡像定義中特別指定了:latest標簽則同Always一樣每次啟動都拉取鏡像。
command與args有點像Dockerfile中的ENTRYPOINT和CMD命令,例如下面這個例子,command指定了entrypoint, args指定了entrypoint的執行參數:
workingDir就是工作目錄,和Dockerfile中的WORKDIR是一樣的意思, volumeMounts表示數據卷的定義,此處數據卷定義與Docker中的定義無差異。但是別忘了數據卷定義在Kubernetes中是可以指定類型的,也就是說,在containers標簽之外,還有數據卷類型的定義,具體可以看第五段程序的內容。
接下來看容器的端口、環境變量與硬件資源分配的定義。在這部分配置文件中,有大家熟悉的 ports標簽,與Docker不同的是,此處的端口是一個列表,也就是說,ports下一級可以列出幾個端口定義,containerPort表示Pod里面的容器要監昕的端口,hostPort表示容器所在主機需要監聽的端口號(默認與containerport相同),除非必要,否則不要使用hostPort(例如,作為節點Daemon程序時需要用到),設置 hostPort。此時,同一台宿主機只能啟動一個容器實例。
env環境變量大家已經很熟悉,沒有什么特別需要指出的地方,resources資源限制與Docker run 類似,limits表示最大使用值,requests表示請求使用值。
下面配置文件中的標簽想必讀者有些陌生,livenessProbe 定義了對Pod內部容器健康檢查的設置,當監測異常之后,系統將自動重啟該容器。可以設置的方法有exec、httpGet和tcpSocket。一般而言,一個容器僅需設置一種健康檢查方法。
initialDelaySeconds表示容器啟動成功后到第一次監測的時間間隔(單位是秒)。
timeoutSeconds表示超時秒數,超過就表示容器不正常(默認為l秒)。
periodSeconds表示多少秒監測一次(默認為10秒)。
successThreshold表示探針監測失敗之后要連續監測多少次成功才算正常(默認為l次,最小為l次)。
failureThreshold表示連續多少次監測失敗才判定容器異常(默認為3次,最小為l次)。
最后,是關於重啟策略與網絡、數據持久化的配置定義。
restartPolicy表示Pod的重啟策略,默認值為Always。
Always: Pod一旦終止運行,則無論容器是如何終止的都將自動重啟容器。
Onfailure:當Pod以非零退出碼終止時自動重啟容器。退出碼為0則不重啟(正常退出)。
Never: Pod終止后不重啟容器。
nodeSelector表示將該Pod調度到包含這些label的Node上,以鍵值對格式指定,在后面的調度實戰中會使用到。
拉取鏡像時使用的secret名稱,以name:secretkey格式指定。例如給節點打一個標簽:
kubectl label nodes ops-node1 disktype=ssd
然后在配置中寫
nodeSelector:
dicktype: ssd
調度時會把這個Pod調度到有這個標簽的節點上。
hostNetwork表示是否使用主機網絡模式,默認為false。如果設置為true,則表示容器使用宿主機網絡,不再使用Docker網橋,這樣的話,這個Pod只能在宿主機上啟動一個實例。
- Pod生命周期
- 創建Pod
使用kubectl create即可創建,大部分資源對象都是通過這個命令創建的。 如果創建失敗,它會提示你哪里出錯了。
快速使用run命令創建:
kubectl run my-nginx --image=nginx --replicas=2 --port=80
手動暴露一個服務
kubectl expose deployment my-nginx --port=8080 --target-port=80 --externalip=x.x.x.x
external-ip必須是安裝了Kubernetes的機器的IP,隨便一個集群外部的IP是不能訪問的。
多容器Pod的創建一般是使用kubectl create -f FILE命令
- 查看Pod
查看Pod幾乎是kubectl中最常用的命令了,使用kubectl get pods,相關參數在第8章已經全部介紹過了。使用kubectl describe pods <pod-name>可以查看指定Pod的生命周期事件,使用相關參數可以過濾出你要的信息。
查看Pod更多信息:
- 刪除Pod
使用kubectl delete pod <pod-name>可以刪除指定Pod,或者使用-f選項指定配置文件刪除該Pod,如果要刪除所有的Pods,可以使用-all選項。
kubectl delete pod 容器NAME
kubectl delete pod/容器NAME
如果你刪除Deployment或者RC、RS等資源,也會刪除它們關聯的Pod。
- 升級Pod
使用kubectl replace -f /path/nginx.yml可以更新個Pod。但Pod的很多屬性是無法修改的,所以更新Pod時修改配置文件后往往沒有改變Pod的屬性,可以使用-force強制更新,這種操作等同於重建一個Pod。
這種替換Pod的方式並不適用於大規模集群,為了實現一個服務的滾動升級,往往有大量的Pods需要升級,而且還要保證服務不間斷,因此滾動升級可以通過執行kubectl rolling-update命令完成, 該命令會創建一個新的RC, 然后自動控制舊的RC定義中的Pod副本的數量逐漸減少到0,同時新的RC中的Pod副本的數量從0 逐步增加到期望值,最終實現整個服務所有Pod的升級。不過,新RC與舊RC需要在相同的命名空間(Namespace)內才能執行這個命令。
例如,現有Pod正在運行java-web容器,Pod的版本是l.0,現在需要升級到2.0版本。
創建java-web-v2.yaml
保存文件,然后更新:
kubectl rolling-update java-web -f java-web-v2.yaml
注意,RC的名稱(name)不能和舊的RC名稱相同,因為在selector中至少要有一個Label與舊的Label不同,才能標識其為新的RC。
另外,使用不同的鏡像標簽表示Pod鏡像有變化,也可以實現Pod升級(RC不變)。第一種方法需要改變RC定義文件,可控性強。第二種方法可以使用 rolling-update的選項--image指定,使用--rollback可以回滾。
-
共享Volum
在Pod中定義容器的時候可以為單個容器配置volume,然后也可以為一個Pod中的多個容器定義一個共享Pod級別的Volume。比如一個pod里定義了一個Nginx容器,訪問日志放在一個文件夾內。此外還定義了一個收集日志的容器,那么在這個時候你就可以把存放日志的文件配置為Pod級別共享Volume,這樣一個容器寫、另一個容器讀,相互共享一個Volume。
這里設置的Volume名為nginx-logs,類型為emptyDir,掛載到nginx容器內的/usr/local/nginx/logs目錄下。
-
Pod配置管理
同一集群配置管理方案ConfigMap,以文件cm-vars.yaml為例,
將幾個應用所需的變量定義為ConfigMap:
data一欄包括了配置數據,ConfigMap可以被用來保存單個屬性,也可以用來保存一個配置文件。配置數據可以通過很多種方式在Pods里被使ConfigMaps可以被用來:
- 設置環境變量的值;
- 在容器里設置命令行參數;
- 在數據卷里面創建config文件。
configmap
從本地文件、目錄或字符值創建一個configmap(類似Secrets,但是ConfigMaps只是作為多個屬性文件的引用)。configmap可以用來保存ke)叫alue pair配置數據。當基於文件創建configmap時,文件的名稱將默認為key,該key值的內容默認為文件的內容。如果文件名稱是無效的key,則可以指定備用的key。
更多詳細內容查看官網
https://kubernetes.io/zh/docs/concepts/configuration/configmap/
使用kubectl create創建:
kubectl create -f cm-vars.yaml
此處的文件並不一定要yaml格式,可以是任意鍵值對格式的文檔。例如下面,可以是一個目錄,鍵值對。
如何使用這些cm?要先建立一個pod定義文檔:
其中在env標簽中,使用了名為env-config和special-config的cm資源,這兩個文件如下:
如果執行這個Pod,會輸出如下
在cm中的鍵值對,對於Pod內部的容器來說是作為全局的變量存在的。除了使用上面的env方式加載cm外,還可以使用volume掛載cm資源。
-
Pod健康檢查
- 健康檢查
Kubernetes健康檢查被分成 Liveness和Readiness兩種Probes。LivenessProbe用於檢測容器是否正在運行,又稱為存活探針。在通常情況下,容器一旦崩潰,Kubernetes就會知道這個容器已經終止,然后自動重啟這個容器。LivenessProbe的目的就是監測容器的運行狀態並返回給API server,所以一個簡單的HTTP請求 就可以成為一個LivenessProbe。
LivenessProbe探針通過三種方式來檢查容器是否健康。
ExecAction:在容器內部執行一個命令,如果返回碼為0,則表示健康。
TcpAction:通過IP和Port發送請求,如果能夠和容器建立連接,貝iJ表示 容器健康。
HttpGetAction:發送一個http Get 請求(ip+port+請求路徑),如果返回狀態碼在200~400之間,則表示健康。
三個方法的示例如下
在這個例子中,設置了一個容器,使用echo ok > /tmp/healthy: sleep 10; rm -rf /tmp/healthy; sleep 600模擬一個容器"不健康"的狀態,下面exec類型的探針中定義了使用cat命令檢查/tmp/healthy文件的內容,當10秒之后,容器內部的/tmp/healthy文件被刪除,探針無法獲取這個文件,於是這個容器就會被標記為"不健康"狀態。
在這個例子中,使用了TcpAction類型的探針,探針在容器啟動15秒后執行tcp連接測試,如果一秒內沒有成功建立連接,那么探針就會標記容器為"不健康",並向API server匯報,等待Kubernetes重新調度新的容器或者根據重啟策略恢復容器狀態。
在這個例子中,使用了HttpGetAction類型的探針,探針在容器啟動15秒后執行httpget操作,如果一秒內沒有返回200到400之間的狀態碼,表示容器不正常,然后向API Server匯報。
- 重啟策略
Pod的重啟策略是指當容器異常退出后調度器如何處理容器的策略,重啟策略在上面配置詳解中有介紹。Pod一共有四種狀態,如下
Pod的重啟策略應用於Pod內的所有容器,由Pod所在Nod巳節點上的Kubelet進行判斷和重啟操作。重啟策略有以下三種,如下
創建一個Pod如下:
查看Pod的重啟次數
kubectl get pod on-failure-restart-pod --template="{{range .status.containerStatuses}}{{.name}}:{{.restartCount}}{{end}}"
-
Pod擴容和縮容
Pod的規模伸縮Kubernetes在前面中已有介紹,例如HPA資源;在細談命令行中,也介紹了相關的命令,例如scale等。
例如通過scale來完成擴容或縮容,假設nginx這個Pod原來定義了5個副本,想擴容到10個。
kubectl scale rc nginx –replicas=10
縮容到2個
kubectl scale rc nginx –replicas=2
還可以使用動態擴容縮容(HPA),通過對CPU使用率的監控,HPA ( Horizontal Pod Autoscaler ) 可以動態地擴容或縮容。
Pod的CPU使用率是通過Heapster組件來獲取的,所以要預先安裝好比組件。
下面創建一個HPA,在創建HPA前需要已經存在一個RC或Deployment 對象, 並且該RC或Deployment中的Pod必須定義resource.request.cpu的請求值, 否則Kubernetes不會主動獲取CPU使用情況,導致HPA無法工作。
kubectl autoscale rc java –-min=1 –-max=10 –-cpu-percent=50
上面命令表示當CPU使用率超過50%就啟動自動伸縮規模,副本數量范圍在 l~10之間調整。除了使用autoscale命令創建HPA之外,還可以通過配置文件的方式創建HPA:如下。
