4.k8s資源清單
一、資源型別
叢集資源分類(適用性範圍)
名稱空間級別:kubeadm k8s kube-system (kubectl get pod -n default)預設是加default
叢集級別:role
元資料型:HPA
K8s 中所有的內容都抽象為資源, 資源例項化之後, 叫做物件
- 名稱空間
- 工作負載型資源(workload): pod , ReplicaSet, Deployment, StatefulSet,DaemonSet,Job,CronJob(ReplicationController在1.11版本被廢棄)
- 服務發現及負載均衡型資源(ServiceDiscovery LoadBalance):Service,Ingress,..
- 配置與儲存型資源: Volume(儲存卷),CSI(容器儲存介面, 可以擴容各種各樣的第三方儲存卷)
- 特殊型別的儲存卷: ConfigMap(當配置中心來使用的資源型別),Secret(儲存敏感資料),DownwardAPI(把外部環境中的資訊輸出給容器)
- 叢集級別資源:
- Namespace,node,role ,clusterRole,RoleBinding,ClusterRoleBinding
- 元資料型資源:
- HPA(元資料),PodTemplate(pod模板),LimitRange(資源限制)
二、YAML格式
pod定義yaml 檔案說明
三、常用欄位說明
Spec: 達到預期的狀態
引數名 | 欄位型別 | 說明 |
---|---|---|
version | String | 這裡是值的是k8s API的版本, 目前基本上是v1, 可以用kubectl api-versions命令查詢 |
kind | String | 這裡指的是yaml檔案定義的資源型別和角色, 比如:Pod |
metadata | Object | 元資料物件, 固定值就寫metadata |
metadata.name | String | 元資料物件的名字, 這裡由我們編寫,比如命名Pod的名字 |
metadata.namespace | String | 元資料物件的名稱空間, 由我們自身定義 |
spec | Object | 詳細定義物件, 固定值就寫spec |
spec.containers[] | list | 這裡是spec物件的容器列表定義 , 是一個列表 |
spec.containers[].name | String | 這裡定義容器的名字 |
spec.containers[].image | String | 這裡定義要用到的映象名稱 |
spec.containers[].imagePullPolicy | String | 定義映象拉取策略, 有Always,Never,IfNotPresent三個值(1)Always:意思是每次都嘗試重新拉取映象(2)Never:表示僅使用本地映象(3)IfNotPresent:如果本地有映象就使用本地映象, 沒有就拉取線上映象,上面三個值都沒有設定的話, 預設是Always |
spec.containers[].command[] | List | 指定容器啟動命令, 因為是陣列可以指定多個,不指定則使用映象打包時使用的啟動命令 |
spec.containers[].args[] | list | 指定容器啟動命令引數, 因為是陣列可以指定多個 |
spec.containers[].workingDir | String | 指定容器的工作目錄 |
spec.containers[].volumeMounts[] | 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.containers[].resources.requests | Object | 指定容器啟動和排程時的限制設定 |
spec.containers[].resources.requets.cpu | string | CPU請求, 單位為core數,容器啟動時初始化可用數量 |
spec.containers[].resources.requets.memory | string | 記憶體請求, 單位為MIB,GiB, 容器啟動的初始化可用數量 |
Spec.restartPolicy | String | 定義Pod的重啟策略, 可選值為Always,OnFailure,預設為Always,1.Always:Pod 一旦終止執行則無論容器是如何終止的, kubelet服務都將重啟它,2,OnFailure: 只有Pod以非零退出碼終止時 , kubelet才會重啟該容器, 如果容器正常結束(退出碼為0),則kubelet將不會重啟它, 3.Never:pod終止後,kubelet將退出碼報告給Master,不會重啟該pod |
spec.nodeSelector | object | 定義node的label過濾標籤, 以key:value格式指定 |
spec.imagePullSecrets | object | 定義pull映象時使用secret名稱, 以name:secretkey格式指定 |
spec.hostNetwork | Boolean | 定義是否使用主機網路模式, 預設為false, 設定true表示使用宿主機網路, 不使用docker網橋, 同時設定了true將無法再同一臺宿主機上啟動第二個副本 |
kubectl explain 可以檢視詳細的引數
例如看pod 的:kubectl explain pod
kubectl explain pod.spec
定義一個pod
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
version: v1
spec:
containers:
- name: app
image: hub.syuee.com/library/nginx:v1
- name: test
image: hub.syuee.com/library/nginx:v1
這裡的兩個容器都是使用的80埠, 所以會報錯 ,下面排查報錯
檢視詳細資訊
kubectl describe pod myapp-pod
這裡可以看到第二個容器報錯
kubectl log myapp-pod -c test
從日誌可以看到報錯資訊是80 埠被佔用
四、pod生命週期
init c: 初始化容器(只是初始化,初始化完成後就會死掉,initc 不能並行)
pause: 初始化建立的時候initc 會連線到pause
mainc :主容器(有多個), 容器啟動的時候會start操作, 當容器停止是會執行stop
liveness : 就緒檢查,可以通過tcp檢查, 通過程序檢測 都通過了在改成ready
readiness : 生命週期檢查(如容器裡面的nginx程序卡死)當檢測到程序卡死 ,我們可以執行重啟或重建pod
pod生命周--》kube-》kubelet-》CRI-》pause-》init C-》main c (指令碼和命名)(過程中有readiness和liveness參與)
五、initC
pod 能夠具有多個容器, 應用執行在容器裡面 , 但是它也可能有一個或多個先於應用容器啟動的Init容器
Init 容器與普通的容器非常像 , 除了如下兩點:
- Init 容器總是執行到成功完成為止
- 每個Init 容器都必須在下一個Init容器啟動之前成功完成
如果Pod 的Init 容器失敗, Kubernetes 會不斷地重啟Pod , 直到Init 容器成功為止, 然而,如果Pod對應的restartPolicy為Never, 它不會重新啟動
Init容器的作用
因為init容器具有應用程式容器分離的單獨映象, 所以它們的啟動相關程式碼具有如下優勢:
- 它們可以包含並執行實用工具, 但是出於安全考慮, 是不建議在應用程式容器映象中包含這些實用工具的
- 它們可以包含實用工具和定製化程式碼來安裝, 但是不能出現在應用程式映象中,例如, 建立映象沒有必要FROM另一個映象, 只需要在安裝過程中使用類似sed ,awk, python或dig這樣的工具
- 應用程式映象可以分離出建立和部署角色, 二沒有必要聯合他們構建一個單獨的映象
- init容器使用linux namespace , 所以相對應用程式容器來說具有不同的檔案系統檢視 , 因此, 他們能夠具有訪問secret 的許可權, 二應用程式容器則不能
- 他們必須在應用程式容器啟動之前執行完成, 二應用程式容器是並行執行的。 所以inti容器能夠提供了一種簡單的阻塞或延遲應用容器的啟動的方法, 知道滿足了一種先決條件
例項1: vim init-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh','-c','echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for mysevice; slepp 2; done;']
- name: init-mydb
image: busybox
command: ['sh','-c','until nsloopup mydb; do echo waiting for mydb; sleep 2; done;']
kubectl describe pod myapp-pod # 檢視myapp-pod 詳情
kubectl log myapp-pod -c init-myservice # 檢視初始化程序詳情
這裡可以看到解析不了myservice 和mydb
建立myservice.yaml
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
建立mydb
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
特殊說明
- 在Pod啟動過程中, Init容器會按順序在網路和資料卷初始化之後啟動, 每個容器必須在一下容器啟動之前成功退出
- 如果由於執行時或失敗退出, 將導致容器啟動失敗, 它會根據Pod的restartPolicy 指定的策略進行重試 , 然而, 如果Pod 的restartPolicy 設定為Always, Init容器失敗時會使用RestartPolicy策略
- 在所有的Init 容器沒有成功之前, Pod 將不會變成Ready狀態, Init 容器的埠將不會在Service中進行聚集, 正在初始化中的Pod 處於Pending狀態, 但應該會將Initializing狀態設定為true
- 如果Pod 重啟, 所有Init容器必須重新執行
- 對Init 容器spec 的修改被限制在容器image 欄位, 修改其他欄位都不會生效, 更改Init 容器的image欄位, 等價於重啟該Pod
六、探針
探針是由kubectl 對容器執行的定期診斷,要執行診斷 , kubelet 呼叫由容器實現的Handler。 有三種類型的處理程式:
- ExecAction: 在容器內執行指定命令 。 如果命令退出時返回碼為0 則認為診斷成功
- TCPSocketAction: 對指定埠上的容器的IP 地址進行TCP 檢查。 如果埠開啟。 則診斷被認為是成功的。
- HTTPGetAction: 對指定的埠和路徑上的容器的IP 地址執行HTTP Get 請求。 如果響應的狀態碼大於等於200 ,且小於400 。 則診斷被認為是成功的
每次探測都將獲得以下三種結果之一:
- 成功: 容器通過了診斷
- 失敗: 容器未通過診斷
- 未知: 診斷失敗 , 因此不會採取任何行動
探測方式
livenessProbe: 指示容器是否正在執行 。 如果存貨探測失敗,則kubelet 會殺死容器, 並且容器將受到其重啟策略的影響。 如果容器不提供存貨探針, 則預設狀態為Sussess
readinessProbe: 指示容器是否準備好服務請求, 如果就緒探測失敗, 端點控制器將從與pod 匹配的所有Service的端點中刪除該pod 的IP地址 , 初始化延遲之前的就緒狀態預設為Failure 。 如果容器不提供就緒探針。 則預設狀態為Sussess 。
檢測探針-就緒檢測
readlinessProbe-httpget
Vim read.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: nginx
imagePullPolicy: IfNotPresent
readinerssProbe:
httpGet:
port: 80
path: /index1.html #
initialDelaySeconds: 1 #延遲1秒
periodSeconds: 3 #過期3秒 就是3秒後重新檢測
檢測探針-存活檢測
livenessProbe-exec
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: hub.syuee.com/library/busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep 3600"]
livenessProbe:
exec:
command: ["test", "-e", "/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3
livenessProbe-httpget
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: hub.syuee.com/library/nginx:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
livenessProbe-tcp
apiVersion: v1
kind: Pod
metadata:
name: probe-tcp
spec:
containers:
- name: nginx
image: hub.syuee.com/library/nginx:v1
livenessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 80
periodSeconds: 3
多個檢查合在一起
apiVersion: v1
kind: Pod
metadata:
name: probe-tcp
spec:
containers:
- name: nginx
image: hub.syuee.com/library/nginx:v1
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1
periodSeconds: 3
livenessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 80
periodSeconds: 3
七、start、stop、相位
啟動、退出動作
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c","echo Hello form the postStart handler > /usr/share/message"]
proStop:
exec:
command: ["/usr/sbin/nginx", "-s", "quit"]
Pod phase 可能存在的值
掛起(Pending): Pod 已被Kubernetes系統接受, 但有一個或者多個容器映象尚未建立, 等待時間包括排程Pod 的時間和通過網路下載映象的時間, 這可能需要花點時間
執行中(Running):該Pod已經繫結到了一個節點上,Pod中所有的容器都已被建立, 至少有一個容器正在執行, 或者正處於啟動或重啟狀態
成功(Succeeded): Pod中的所有容器都被成功終止, 並且不會在重啟
失敗(Failed):Pod中所有容器都已終止了, 並且至少有一個容器是因為失敗終止, 也就是說, 容器以非0狀態退出或者被系統終止
未知(Unknown):因為某些原因無法取得Pod的狀態, 通常是因為與Pod所有主機通訊失敗
pod中只有一個容器並且正在執行, 容器成功退出
- 記錄時間完成
- 如果restartPolicy為:
- Always: 重啟容器, Pod phase任為Running
- OnFailure: Pod phase變成Succeeded
- Never: Pod phase變成Susseeded
Pod中只有一個容器並且正在執行。 容器退回失敗
- 記錄失敗事件
- 如果restartPolicy為:
- Always: 重啟容器, Pod phase仍為Running
- OnFailure:重啟容器, Pod phase仍為Running
- Never: Pod phase變成Failed
Pod 中有兩個容器並且正在執行。 容器退出失敗
- 記錄失敗時間
- 如果restartPolicy
- Always: 重啟容器; Pod phase 仍為Running
- OnFailure: 重啟容器, Pod phase 仍為Running
- Never: 不重啟容器; Pod phase 仍為Running
- 如果有容器1沒有處於執行狀態, 並且容器2 退出
- 記錄失敗事件
- 如果restartPolicy為:
- Always:重啟容器; Pod phase 仍為Running
- OnFailure: 重啟容器; Pod phase仍為Running
- Never: Pod phase 變成Failed
Pod 中只有一個容器並處於執行狀態。 容器執行時記憶體超出限制
- 容器以失敗狀態終止
- 記錄oom 事件
- 如果restartPolicy為:
- Always: 重啟容器; Pod phase仍為Running
- OnFailure: 重啟容器; Pod phase 仍為Running
- Never: 記錄失敗事件; Pod phase 仍為Failed
Pod 正在執行, 磁碟故障
- 殺掉所有容器。 記錄適當事件
- Pod phase 程式設計Failed
- 如果使用控制器來執行, Pod 將在別處重建
Pod 正在執行, 其節點被分段
- 節點控制器等待直到超時
- 節點控制器將Pod phase 設定為Failed
- 如果是用控制器來執行, Pod 將在別處重建