一、資源清單
1,定義:
在k8s中一般使用yaml格式的檔案來建立符合我們預期的資源,這樣的yaml被稱為資源清單。
使用資源清單建立Pod:
kubectl apply -f nginx.yaml
定義nginx.yaml內容為:
apiVersion: v1
kind: Pod
metadata:
name: my-pod #自定義的名稱只能用小寫字母使用 - 連線,駝峰 或者 _ 連線會報錯
labels:
app: nginx-app
version: v1
spec:
containers:
- name: test-nginx
image: nginx
2,資源清單常用欄位
欄位 | 型別 | 說明 |
---|---|---|
apiVersion | String | k8s api 的版本,目前基本上是 v1。可以用 kubectl api-versions 命令檢視 |
kind | String | 定義的資源型別。比如定義為一個 Pod 或者 Deployment等等。 |
metadata | Object | 宣告後設資料物件,固定值:metadata。 |
metadata.name | String | 後設資料物件的名字。我們自己定義,比如該資源被 kind 定義為一個 Pod,那麼 Pod 的名稱就是在這裡定義。 |
metadata.namespace | String | 後設資料物件的名稱空間。我們自己定義,不寫預設為 default。這裡定義的名稱空間必須是已存在的。 |
metadata.labels | Object | 標籤。 |
metadata.labels.app | String | 標籤名稱。 |
metadata.labels.version | String | 標籤版本號。 |
Spec | Object | 詳細定義物件。固定值:Spec。 |
spec.containers[] | List | 這裡是Spec物件的容器列表。即這個資源可以宣告多個容器。 |
spec.containers[].name | String | 容器的名字。建議不寫,會自動建立。如果此處寫了容器的名字,那麼 k8s 對該容器進行擴容時會報錯,因為不能存在相同名稱的容器。 |
spec.containers[].image | String | 容器使用的映象。 |
spec.containers[].imagePullPolicy | String | 映象拉取策略。如果不設定,預設為 Always。Always:每次都拉取新的映象;Never:僅使用本地映象,如果本地映象不存在則不使用該映象;IfNotPresent:如果本地沒有,就拉取新映象。 |
spec.containers[].command[] | List | 指定容器啟動命令,可以指定多個。不指定則預設為容器打包時使用的啟動命令,若指定了則會覆蓋原命令。 |
spec.containers[].args[] | List | 指定容器啟動命令引數,可傳入多個。 |
spec.containers[].workingDir | String | 指定容器的工作目錄。 |
spec.containers[] | List | 指定容器北部的儲存卷配置。 |
spec.containers[].volumeMounts[].name | String | 指定可以被容器掛載的儲存卷的名稱。 |
spec.containers[].volumeMounts[].mountPath | String | 指定可以被容器掛載的儲存卷的路徑。 |
spec.containers[].volumeMounts[].readOnly | String | 設定儲存卷路徑的讀寫模式,ture 或 false,預設為讀寫模式。 |
spec.containers[].ports[] | List | 指定容器需要用到的埠列表。 |
spec.containers[].ports[].name | String | 指定埠名稱。 |
spec.containers[].ports[].containerPort | String | 指定容器需要監聽的埠號。 |
spec.containers[].ports[].hostPort | String | 指定容器所在主機需要監聽的埠號,預設跟 containerPort 相同。設定了 hostPort ,那麼同一臺主機就無法啟動該容器的相同副本(同一主機埠號衝突)。 |
spec.containers[].ports[].protocol | String | 指定埠協議,支援 TCP 和 UDP,預設為 TCP。 |
spec.containers[].env[] | List | 指定容器執行前需要設定的環境變數列表。 |
spec.containers[].env[].name | String | 指定環境變數名稱。 |
spec.containers[].env[].value | String | 指定環境變數的值。 |
spec.containers[].resources | Object | 指定資源限制和資源請求的值。 |
spec.containers[].resources.limits | Object | 設定容器執行時的資源執行上限。 |
spec.containers[].resources.limits.cpu | String | 指定 CPU 的限制,單位為 core 數,將用於 docker run -- cpu-shares 引數。 |
spec.containers[].resources.limits.memory | String | 指定 MEM 記憶體的限制,單位為 MIB、GIB。 |
spec.restartPolicy | String | Pod 重啟策略。Always:Pod 一旦終止執行,不論是以什麼方式終止的,kubelet 都會重啟它;OnFailure:如果 Pod 的退出碼是0,kubelet 不會重啟,其它任何非0退出碼終止的,都會重啟;Never:Pod 終止後,kubelet 將退出碼報告給 master 並不會重啟該 Pod。 |
spec.nodeSelector | Object | 定義 Node 的 Label 過濾標籤,言外之意就是選擇在哪些 Node 上執行。以 key:value 格式指定。 |
spec.imagePullSecrets | Object | 定義 pull 映象時使用的 secret 名稱,格式為 name:secretkey 。 |
spec.hostNetwork | Boolean | 是否使用主機網路模式,預設值為 false。ture 表示使用宿主機網路,不使用 docker 網橋,並且將無法在同一臺宿主機上啟動第二個副本,否則端埠衝突。 |
3,排錯思路
如果我們使用資源清單進行資源的建立時發生錯誤(某個容器啟動失敗),可以通過以下思路排查(以 Pod 為例):
# 檢視 Pod,-n 指定名稱空間名稱 kubectl get pod -n myspace -o wide # 檢視 Pod 的詳細資訊(假設 Pod 名稱為 my-pod),查詢結果包括 Pod 中所有容器的執行情況,如果某個容器正常執行,其 State 屬性會是 Running kubectl describe pod my-pod -n myspace # 檢視 Pod 中容器的執行日誌,找出容器執行失敗的原因。-c 表示要檢視的容器,若 Pod 裡只有一個容器,不加也可以。 kubectl log my-pod -c my-nginx -n myspace
二、Pod定義
每個Pod都會存在一個Pause根容器,是每一個Pod都會去執行的,container即為應用程式,所以Pod就是根容器Pause和應用程式container所組成,在Pod當中可以執行多個小的容器的。
1,Pod組成的意義
- 使用Pause根容器可以防止由於將多個容器組成一個單元,當其中某個容器掛掉就會導致整個單元無法使用的情況發生。
- Pod可以執行過個container,這些container是共享Pause根容器的IP地址,也共享Pause的volume掛債卷,這樣既簡化了關聯業務容器之間的通訊問題,也很好的解決了容器之間共享的問題
- 在Kubernetes中的Pod之間是可以進行相互通訊的,因為他們之間是一個二層交換的網路,所以不同主機之間Pod是可以進行相互訪問的
2,Pod型別劃分
靜態Pod:不會將狀態存放到Etcd儲存資料庫中,而是放到了某個Node上的具體檔案當中,並且只有在這個Node上才能啟動執行
普通Pod:普通Pod一旦被建立成功,那麼Pod狀態資訊就會放到Etcd儲存資料庫當中,狀態就會實時進行更新,就會被Master節點繫結到某個Node節點上進行排程和資源分配,隨後Pod就放到了指定的Node上面,相當於把一個應用例項化成了一組相關Docker容器並啟動去執行
3,Pod、容器與Node之間的關係
- 在Node當中執行著Pod,而在Pod當中是包含著容器。
- 在K8s當中都是以Docker映象釋出的,每個Pod可以理解為上面執行著多個映象,在預設情況下,比如在Pod當中某個容器停止了,K8s會自動檢查這個問題並重啟這個Pod(即將Pod當中的所有容器全部重啟)
- 如果Pod所在的Node當機了,K8s會把Pod排程到其他的Node節點上
- Pod當中是可以執行多個應用的,即支援多容器執行,每一個Pod相當於一個資源池,Pod當中的容器可以共享IP和檔案系統
三、Pod的生命週期
1,生命週期描述
初始化 Pod 環境:每一個 Pod 在建立時都會先初始化 Pod 執行所必須的條件。然後才繼續執行後面的容器初始化操作。比如會先建立 pause 這樣的容器。 Init C:Init Containers,初始化容器。 我們在 Pod 裡面執行的容器,可能會依賴某些檔案或者環境才能夠正常啟動或執行。Init C 就是來完成這些檔案或者環境的建立的。 Init C 可以有多個,也可以沒有。按順序執行,必須要等到前一個執行完成(必須是正常退出,否則會根據重啟策略判斷是否重新執行該 Init C),才會執行後一個。 Init C 只存在容器初始化階段,Init C 執行完成之後會消亡,不參與 Pod 的後續流程。 所有的 Init C 都正常結束後,Main C 主容器才開始建立並啟動。 Main C:主容器。即執行在 Pod 裡提供服務的容器。主容器一旦停止執行,那麼 Pod 也就停止了。需要注意的是一個 Pod 裡面可以有很多個 Main C,且每個 Main C 都有自己的 Init C 等。 start:Main C 建立之前執行的操作,可以是一條命令或一個指令碼。 stop:Main C 結束之後執行的操作,可以是一條命令或一個指令碼。 readiness:容器就緒檢測,可以指定在容器啟動之後的某個時間點執行,比如 10 秒後。只有當 readiness 正常執行完成,該 Pod 才會顯示為就緒狀態。 liveness:容器是否正在執行。
2,InitC
Init容器與普通的容器非常像,但是:1,Init容器總是執行到成功為止;2,每個Init容器必須都在下一個Init容器啟動之前成功完成。
InitC簡單例項init.yaml:(kubectl create -f init.yaml)
apiVersion: v1 kind: Pod #Pod型別 metadata: name: myapp-pod #Pod名稱 labels: app: myapp spec: containers: - name: myapp-container #主容器 image: busybox command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: #InitC - name: init-myservice #率先啟動的Init容器 image: busybox command: [ 'sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] #監控myservice - name: init-mydb #在主容器之前啟動,在init-myservice正常退出之後啟動。 image: busybox command: [ 'sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;'] #監控mydb
myservice.yaml :(kubectl create -f myservice.yaml)
apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376
mydb.yaml :(kubectl create -f myservice.yaml)
apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377
InitC特點:
- 在 Pod 啟動過程中,Init 容器會按順序在網路和資料卷初始化之後啟動(即在 pause 容器之後啟動)。每個容器必須在下一個 容器啟動之前成功退出。
- 如果由於執行時或失敗退出,將導致容器啟動失敗,它會根據 Pod 的 restartPolicy 指定的策略進行重試。
- 在所有的 Init 容器沒有成功之前,Pod 將不會變成 Ready 狀態。Init 容器的埠將不會在 Service 中進行聚集。正在初始化中的 Pod 處於 Pending 狀態,但應該會將 Initializing 狀態設定為true。
- 如果 Pod 重啟,所有 Init 容器必須重新執行。
- 對 Init 容器 spec 的修改被限制在容器 image 欄位,修改其他欄位都不會生效。更改 Init 容器的 image 欄位,等價於重啟該Pod。
- Init 容器具有應用容器的所有欄位。除了 readinessProbe,因為 Init 容器無法定義不同於完成 (conpletion)的就緒(readiness)之外的其他狀態。
- 在 Pod 中的每個 app 和 Init 容器的名稱必須唯一;與任何其它容器共享同一個名稱,會在驗證時丟擲錯誤。
3,探針
探針是由 kubelet 對容器執行的定期診斷。要執行診斷,kubelet 呼叫由容器實現的 Handler。有三種型別的處理程式:
-
- ExecAction:在容器內執行指定命令。如果命令退出時返回碼為 0 則認為診斷成功。
- TCPSocketAction:對指定埠上的容器的 IP 地址進行 TCP 檢查。如果埠開啟,則診斷被認為是成功的。
- HTTPGetAction:對指定的埠和路徑上的容器的 IP 地址執行 HTTPGet 請求。如果響應的狀態碼大於等於 200 且小於 400,則診斷被認為是成功的。
每次探測都將獲得以下三種結果之一:
-
- 成功:容器通過了診斷。
- 失敗:容器未通過診斷。
- 未知:診斷失敗,因此不會採取任何行動。
探針有兩種型別:
- readinessProbe:探測容器是否準備好服務請求(即是否就緒 [READY])。如果就緒探測失敗,端點控制器將從與 Pod 匹配的所有Service 的端點中刪除該 Pod 的 IP 地址。初始延遲之前的就緒狀態預設為 Failure 。如果容器不提供就緒探針,則預設狀態為Success。
- livenessProbe:探測容器是否正常執行。如果存活探測失敗,則 kubelet 會殺死容器,並且容器將受到其重啟策略的影響。如果容器不提供存活探針,則預設狀態為 Success。
readinessProbe例項:採用HTTPGetAction(readness-httpget.yaml
)
apiVersion: v1 kind: Pod metadata: name: readness-httpget-pod spec: containers: - name: readness-httpget-container image: hub.xcc.com/library/mynginx:v1 imagePullPolicy: IfNotPresent #映象拉取策略 readinessProbe: httpGet: #探測方式 port: 80 path: /index1.html #檢測路徑 initialDelaySeconds: 1 #容器啟動後1s開始探測 periodSeconds: 3 #如果檢測失敗,每3s繼續探測,直到檢測成功或者達到最大檢測值
livenessProbe例項:採用ExecAction(liveness-exec
.yaml
)
apiVersion: v1 kind: Pod metadata: name: liveness-exec-pod namespace: default spec: containers: - name: lineness-exec-container image: busybox imagePullPolicy: IfNotPresent command: ['sh', '-c', 'touch /tmp/live; sleep 50; rm -rf /tmp/live; sleep 3600'] livenessProbe: exec: command: ['test', '-e', '/tmp/live'] initialDelaySeconds: 1 periodSeconds: 3
4,Pod hook
Pod hook(鉤子)是由 Kubernetes 管理的 kubelet 發起的,當容器中的程式啟動前或者容器中的程式終止之前執行,這是包含在容器的生命週期之中,也就是上面 Pod 生命週期
中提到的 start 和 stop。可以同時為 Pod 中的所有容器都配置 hook。
Hook的型別包括兩種:
-
- exec:執行一段命令。
- HTTP:傳送HTTP請求。
apiVersion: v1 kind: Pod metadata: name: lifecycle-demo spec: containers: - name: lifecycle-demo-container image: hub.xcc.com/library/mynginx:v1 lifecycle: postStart: exec: command: [......] preStop: exec: command: [......]
5,Pod相位(phase )
Pod 的 status 欄位是一個 PodStatus 物件,PodStatus 中有一個 phase 欄位。
Pod 的相位(phase)是 Pod 在其生命週期中的簡單巨集觀概述。該階段並不是對容器或 Pod 的綜合彙總,也不是為了做為綜合狀態機。
Pod 相位的數量和含義是嚴格指定的,以下是當前 Pod 相位的所有值:
-
- 掛起(Pending):Pod 已被 Kubernetes 系統接受,但有一個或者多個容器映象尚未建立。等待時間包括排程 Pod 的時間和通過網路下載映象的時間。
- 執行中(Running):該 Pod 己經繫結到了一個節點上,Pod 中所有的容器都己被建立。至少有一個容器正在執行,或者正處於啟動或重啟狀態。
- 成功(Succeeded):Pod 中的所有容器都被成功終止,並且不會再重啟。
- 失畋(Failed):Pod 中的所有容器都己終止了,並且至少有一個容器是因為失敗終止。也就是說,容器以非0狀態退出或者被系統終止。
- 未知(Unknown):因為某些原因無法取得 Pod 的狀態,通常是因為與 Pod 所在主機通訊失敗。