pod进阶(资源管理和探针)
文章目錄
- 一: Pod的資源限制
- 1.1 概念
- 1.1.1 什么是pod的計算資源顯稚嫩
- CPU和內存的Requests和Limits的特點
- 1.2 pod 之間,和容器之間的通信
- 1.3 官網中的示例
- 1.4 CPU 資源單位
- 1.5 內存資源單位
- 1.6 示例
- 二:健康檢查(探針Probe)
- 2.1 探針的三種規則
- 2.2 Probe支持的三種檢查方法
- 2.3 探測獲得的三種結果
- 三: 示例
- 3.1 示例1 exec方式
- 3.1.1 exec 官網示例
- 3.1.2 編寫示例,查看
- 3.2 示例2 httpGet方式
- 3.2.1 官方示例
- 3.2.2 編寫httpGet 示例
- 3.3 示例3 ,tcpSocket 方式
- 3.3.1 官方示例
- 3.3.2 編寫tcpSocket 方式示例
- 3.4 示例4 配置就緒探測 httpGet的方式
- 3.5 就緒探測示例2
- **總結**
一: Pod的資源限制
1.1 概念
1.1.1 什么是pod的計算資源顯稚嫩
在配置Pod時,我們可以為其中的每個容器指定需要使用的計算資源(CPU和內存)。計算資源的配置項分為兩種:Requests和Limits。
- Requests表示容器希望被分配到的、可完全保證的資源量(資源請求量);
- Limits是容器最多能使用的資源量的上限(資源限制量)。
當為Pod中的容器指定了request資源時,調度器就使用該信息來決定將Pod調度到哪個節點上。當還為容器指定了limit資源時, kubelet就會確保運行的容器不會使用超出所設的limit資源量。kubelet還會為容器預留所設的request資源量, 供該容器使用。
如果Pod運行所在的節點具有足夠的可用資源,容器可以使用超出所設置的request資源量。不過,容器不可以使用超出所設置的limit資源量
資源請求量能夠保證Pod有足夠的資源來運行,資源限制量則是防止某個Pod無限制地使用資源,導致其他Pod崩潰。
我們創建一個pod時,可以指定容器對CPU和內存的資源請求量及資源限制量,它們并不在pod里定義,而是針對每個容器單獨指定。
pod對資源的請求量和限制量是它所包含的所有容器的請求量和限制量之和。
CPU和內存的Requests和Limits的特點
CPU和內存的Requests和Limits有如下特點:
- Requests和Limits都是可選的。在Pod創建和更新時,如果未設置Requests和Limits,則使用系統提供的默認值,該默認值取決于集群配置。
- 如果Requests沒有配置,默認被設置等于Limits。
- requests 是創建容器時需要預留的資源量。如果無法滿足,則pod 無法調度。但是,這不是容器運行實際使用的資源,容器實際運行使用的資源可能比這個大,也可能比這個小。
- Limit 是限制pod容器可以使用資源的上限。容器使用的資源無法高于這個限制任何情況下Limits都應該設置為大于或等于Requests。
1.2 pod 之間,和容器之間的通信
- 同一個pod 里的容器之間通信使用IPC進行通信(進程間通信),通過localhost找到彼此
- 同一個node節點上的pod的通信使用虛擬網橋docker0進行通信
- 不同node節點上的pod 通信可以借助CNI(Container Network Interface)插件進行通信。如Flannel,calico等
1.3 官網中的示例
官網示例:https://kubernetes.io/zh/docs/concepts/configuration/manage-resources-containers/
Pod和容器的資源請求和限制:
1.4 CPU 資源單位
CPU資源的request和limit以cpu為單位。Kubernetes中的一個cpu相當于1個VCPU (1個超線程)
Kubernetes也支持帶小數CPU的請求。spec.containers [].resources.requests.cpu為0.5的容器能夠獲得一個cpu的一半CPU資源(類似于cgroup對CPU資源的時間分片)。表達式0.1等價于表達式100m (毫核) ,表示每1000毫秒內容器可以使用的CPU時間總量為0.1*1000毫秒。
1.5 內存資源單位
內存的request和limit以字節為單位。可以以整數表示,或者以10為底數的指數的單位(E、P,T,G,M,K)來表示,或者以2為底數的指數的單位(Ei, Pi,Ti,Gi、Mi, Ki)來表示。
如: 1KB-10^3-1000, 1MB-10^6-1000000-1000KB, 1GB=10^9-1000000000-1000MB
1KiB-2^10-1024, 1MiB-2 20-1048576-1024KiB
PS:在買硬盤的時候,操作系統報的數量要比產品標出或商家號稱的小一些,主要原因是標出的是以MB, GB為單位的, 1GB
就是1,000,000, 000Bte ,而操作系統是以2進制為處理單位的,因此檢查硬盤容量時是以MiB, GiB為單位, 1GB-2^30-1,073, 741, 824,相比較而言,1GiB要比1GB多出1,073, 741, 824-1, 000, 000, 000-73, 741, 824Byte,所以檢測實際結果要比標出的少一些。
1.6 示例
#先在每個節點上清空內存 echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys/vm/drop_caches echo 3 > /proc/sys/vm/drop_caches free -m [root@master ~]# vim demo1.yaml apiVersion: v1 kind: Pod metadata:name: frontend spec:containers:- name: webimage: nginxenv:- name: WEB_ROOT_PASSWORDvalue: "password"resources:#此容器預分配資源:內存為 64Mi ; 每個cpu 分配250mrequests:memory: "64Mi"cpu: "250m"#此容器限制使用資源(最大): 內存最大使用128Mi,每個cpu最大分配500mlimits:memory: "128Mi"cpu: "500m"- name: dbimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"resources:#此容器的預分配資源:內存預分配為512Mi;cpu預分配為每個cpu的50%,即1000*50%=500mrequests:memory: "512Mi"cpu: "0.5"#此容器的限制使用資源配額為:內存最大使用1Gi;cpu最大使用1000m limits:memory: "1Gi"cpu: "1"#pod有兩個容器,web 和db。所以,總的請求資源和限制資源為 web 和db 請求,限制資源總和。 #其中,cpu 的資源請求和限制,是以單個cpu 資源進行計算的。如果有多個cpu,則最終的結果是數值*N [root@master ~]# kubectl get pod [root@master ~]# kubectl describe pod frontend # 查看pod的詳細信息,查看pod被調度到了哪個node節點 [root@master ~]# kubectl get pod -o wide #查看node01 節點的信息 [root@master ~]# kubectl describe nodes node01二:健康檢查(探針Probe)
2.1 探針的三種規則
健康檢查,又名 探針(Probe):探針是由kubelet對容器執行定期診斷。
探針有三種規則:
- livenessProbe: 判斷容器是否正在運行。如果探測失敗,則kubelet會殺死容器,并且容器將根據 restartPolicy 來設置Pod狀態。如果容器不提供存活探針,則默認狀態為Success
- readinessProbe: 判斷容器是否準備好接受請求。如果探測失敗,端點控制器將從Pod匹配的所有service endpoints中剔除該Pod的IP地址。初始延遲之前的就緒狀態默認我為Failure.如果容器不提供就緒探針,則默認狀態為success。
- startupProbe(1.17版本新增):判斷容器內的應用程序是否已經啟動,主要針對于不能確定具體啟動時間應用。如果配置了startupProbe探測,則在startuProbe狀態為success 之前,其他所有探針都處于無效狀態,知道它成功后其他探針才起作用。如果startupProbe失敗,kubelet將殺死容器你,容器將根據restartPolicy來重啟。如果容器沒有配置startupProbe,則默認狀態為Success。、
注:以上規則可以同時定義。在readinessProbe檢測成功之前,Pod的running狀態是不會變成ready狀態。
2.2 Probe支持的三種檢查方法
- exec: 在容器內執行命令。如果命令退出時返回碼為0 ,則認為診斷成功
- tcpSocket: 對指定端口上的容器IP 地址進行TCP 檢查(三次握手)。 如果端口打開,則診斷被認為是成功的
- httpGet: 對指定端口和路徑上的容器的IP地址執行HTTPGET請求。如果響應的狀態碼大于等于200,且小于400,則診斷被認為是成功的。
2.3 探測獲得的三種結果
每次探測,都將會獲得以下三種結果之一:
- 成功: 容器通過了診斷
- 失敗: 容器未通過診斷
- 未知:診斷失敗,因此不會采取任何行動
三: 示例
3.1 示例1 exec方式
3.1.1 exec 官網示例
https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
apiVersion: v1 kind: Pod metadata:labels:test: livenessname: liveness-exec spec:containers:- name: livenessimage: k8s.gcr.io/busyboxargs:- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600livenessProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 5periodSeconds: 5探針可選的參數:
- initialDelayseconds:容器啟動多少秒后開始執行探測。最小值為0
- periodSeconds:探測的周期頻率,每多少秒執行一次探測默認是10秒,最小值為1
- failureThreshold:探測失敗后,允許再試幾次。
- timeoutSeconds :探測等待超時的時間。默認為1 秒,最小值為1 秒
在這個配置文件中,可以看到 Pod 中只有一個容器。
periodSeconds 字段指定了 kubelet 應該每 5 秒執行一次存活探測。
initialDelaySeconds 字段告訴 kubelet 在執行第一次探測前應該等待 5 秒。
kubelet 在容器內執行命令 cat /tmp/healthy 來進行探測。 如果命令執行成功并且返回值為 0,kubelet 就會認為這個容器是健康存活的。 如果這個命令返回非 0 值,kubelet 會殺死這個容器并重新啟動它。
3.1.2 編寫示例,查看
[root@master ~]#vim exec.yaml apiVersion: v1 kind: Pod metadata:name: liveness-execnamespace: default spec:containers:- name: liveness-exec-containerimage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh","-c","touch /tmp/live ; sleep 30; rm -rf /tmp/live; sleep 3600"]#存活檢查探針,使用exec的方式,進入容器內部,檢測是否有文件或目錄/tmp/livelivenessProbe:exec:command: ["test","-e","/tmp/live"]initialDelaySeconds: 1periodSeconds: 3 #創建pod [root@master ~]# kubectl create -f exec.yaml #跟蹤查看pod 信息 [root@master ~]# kubectl get pod -o wide -w#新開一個終端,查看pod 的消息信息 [root@master ~]# kubectl describe pod liveness-exec3.2 示例2 httpGet方式
3.2.1 官方示例
apiVersion: v1 kind: Pod metadata:labels:test: livenessname: liveness-http spec:containers:- name: livenessimage: k8s.gcr.io/livenessargs:- /serverlivenessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 3periodSeconds: 3在這個配置文件中,可以看到 Pod 也只有一個容器。 periodSeconds 字段指定了 kubelet 每隔 3 秒執行一次存活探測。 initialDelaySeconds 字段告訴 kubelet 在執行第一次探測前應該等待 3 秒。 kubelet 會向容器內運行的服務(服務會監聽 8080 端口)發送一個 HTTP GET 請求來執行探測。 如果服務器上 /healthz 路徑下的處理程序返回成功代碼,則 kubelet 認為容器是健康存活的。 如果處理程序返回失敗代碼,則 kubelet 會殺死這個容器并且重新啟動它。
任何大于或等于 200 并且小于 400 的返回代碼標示成功,其它返回代碼都標示失敗。
3.2.2 編寫httpGet 示例
[root@master ~]# vim httpget.yaml apiVersion: v1 kind: Pod metadata:name: liveness-httpgetnamespace: default spec:containers:- name: liveness-httpget-containerimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10 #創建pod [root@master ~]# kubectl create -f httpget.yaml#刪除pod里容器的文件 [root@master ~]# kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html#查看pod 狀態和 詳細信息 [root@master ~]# kubectl get pods [root@master ~]# kubectl describe pod liveness-httpge3.3 示例3 ,tcpSocket 方式
3.3.1 官方示例
apiVersion: v1 kind: Pod metadata:name: goproxylabels:app: goproxy spec:containers:- name: goproxyimage: k8s.gcr.io/goproxy:0.1ports:- containerPort: 8080readinessProbe:tcpSocket:port: 8080initialDelaySeconds: 5periodSeconds: 10livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 20如你所見,TCP 檢測的配置和 HTTP 檢測非常相似。 下面這個例子同時使用就緒(readinessProbe)和存活(livenessProbe)探測器。
kubelet 會在容器啟動 5 秒后發送第一個就緒探測。 這會嘗試連接 goproxy 容器的 8080 端口。 如果探測成功,這個 Pod 會被標記為就緒狀態,kubelet 將繼續每隔 10 秒運行一次檢測。
除了就緒探測,這個配置包括了一個存活探測。 kubelet 會在容器啟動 15 秒后進行第一次存活探測。 與就緒探測類似,會嘗試連接 goproxy 容器的 8080 端口。 如果存活探測失敗,這個容器會被重新啟動
3.3.2 編寫tcpSocket 方式示例
[root@master ~]# tcpsocket.yaml apiVersion: v1 kind: Pod metadata:name: probe-tcp spec:containers:- name: nginximage: soscscs/myapp:v1livenessProbe:initialDelaySeconds: 5timeoutSeconds: 1tcpSocket:port: 8080periodSeconds: 3 [root@master ~]# kubectl create -f tcpsocket.yaml#查看容器里的端口(查看有無8080端口) [root@master ~]# kubectl exec -it probe-tcp -- netstat -natp#查看pod的狀態和詳細信息 [root@master ~]# kubectl get pods [root@master ~]# kubectl describe pod probe-tcp3.4 示例4 配置就緒探測 httpGet的方式
[root@master ~]# vim readiness-httpget.yaml apiVersion: v1 kind: Pod metadata:name: readiness-httpgetnamespace: default spec:containers:- name: readiness-httpget-containerimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index1.htmlinitialDelaySeconds: 1periodSeconds: 3livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10 # 創建pod [root@master ~]# kubectl create -f readiness-httpget.yaml #查看pod的詳細信息 [root@master ~]# kubectl get pod -w [root@master ~]# kubectl describe pod readiness-httpget#此時,因為容器里沒有 index1.html文件,所以,httpGet的就緒探測失敗 [root@master ~]# kubectl exec -it readiness-httpget -- ls /usr/share/nginx/html #進入容器,創建index1.html,讓就緒探測成功 [root@master ~]# kubectl exec -it readiness-httpget sh / # cd /usr/share/nginx/html/ /usr/share/nginx/html # ls 50x.html index.html /usr/share/nginx/html # echo abc > index1.html /usr/share/nginx/html # exit[root@master ~]# kubectl get pods3.5 就緒探測示例2
[root@master ~]# vim readiness-myapp.yaml apiVersion: v1 kind: Pod metadata:name: myapp1labels:app: myapp spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 --- apiVersion: v1 kind: Pod metadata:name: myapp2labels:app: myapp spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 --- apiVersion: v1 kind: Pod metadata:name: myapp3labels:app: myapp spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 --- apiVersion: v1 kind: Service metadata:name: myapp spec:selector:app: myapptype: ClusterIPports:- name: httpport: 80targetPort: 80所有的自主式Pod,name不可以相同。但是使用同一個標簽myapp。 service通過標簽選擇器和對應標簽的pod關聯
[root@master ~]# kubectl create -f readiness-myapp.yaml #查看這些資源的詳細信息。 [root@master ~]# kubectl get pods,svc,endpoints -o wide #刪除myapp1的 index.html文件,讓就緒探測 失敗 [root@master ~]# kubectl exec -it myapp1 -- rm -rf /usr/share/nginx/html/index.html# 查看發現,就緒探測失敗的pod被從關聯的service中移除ip [root@master ~]# kubectl get pods,svc,endpoints -o wide總結
探針有3種:
- livenessProbe:(存活探針)
-
- 判斷容器是否正常運行,如果失敗,則殺掉容器(注意,不是殺掉pod),再根據重啟策略是否重啟容器
- readinessProbe(就緒探針)
-
- 判斷容器是否能夠進入ready狀態。探針失敗則進入noready狀態,并從service的endpoints中剔除此容器
- startupProbe
-
- 判斷容器內的應用是否啟動成功。再success狀態前,其他探針都處于無效狀態
檢查方式3種
- exec:
-
- 使用command 字段設置命令,在容器中執行次命令,如果命令返回狀態碼為0,則認為探測成功。
- httpget
-
- 通過訪問指定端口和url 路徑,執行http get 訪問。如果返回的 http 狀態碼 為 大于 等于200 且小于400 ,則認為探測成功
- tcpsock
-
- 通過tcp連接pod(podIP) 和指定端口,如果端口無誤,且tcp連接成功,則認為探測成功。
探針可選的參數
- initialDelaySeconds
-
- 容器啟動多少秒后開始執行探測
- periodSeconds
-
- 探測的頻率。每多少秒執行一次探測
- failureThreshold
-
- 探測失敗后,允許再試幾次
- timeoutSeconds
-
- 探測等待超時時間
總結
以上是生活随笔為你收集整理的pod进阶(资源管理和探针)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚拟化概念和KVM简述
- 下一篇: k8s的list-watch机制和 po