kubernetes pod 資源限制 探針

資源限制

當定義 Pod 時可以選擇性地為每個容器設定所需要的資源數量。 最常見的可設定資源是 CPU 和內存大小,以及其他類型的資源。

當為 Pod 中的容器指定了 request 資源時,代表容器運行所需的最小資源量,調度器就使用該信息來決定將 Pod 調度到哪個節點上。當還為容器指定了 limit 資源時,kubelet 就會確保運行的容器不會使用超出所設的 limit 資源量。kubelet 還會為容器預留所設的 request 資源量, 供該容器使用。

如果 Pod 運行所在的節點具有足夠的可用資源,容器可以使用超出所設置的 request 資源量。不過,容器不可以使用超出所設置的 limit 資源量。

如果給容器設置了內存的 limit 值,但未設置內存的 request 值,Kubernetes 會自動為其設置與內存 limit 相匹配的 request 值。 類似的,如果給容器設置了 CPU 的 limit 值但未設置 CPU 的 request 值,則 Kubernetes 自動為其設置 CPU 的 request 值 并使之與 CPU 的 limit 值匹配。

官網示例:
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

資源限制 總結

limit與request區別【重中之重】

spec.containers.resources.requests.cpu|memory ? ? 設置Pod容器創建時需要預留的資源量 ? ?容器應用最低配置 <= requests <= limits
spec.containers.resources.limits.cpu|memory? ? ? ? ? ?設置Pod容器能夠使用的資源量上限,如果容器進程內存使用量超過limits.memory會引發OOM

資源單位?

CPU資源量單位: cpu個數 ?1 ?2 ?0.1 ?0.5 ?0.25 ? ? 毫核 ?100m ? 250m ? 1000m ? 1500m
內存資源量單位:整數(默認單位為字節) ? ? ?2的底數單位(Ki Mi Gi Ti) ? ?10的底數單位(K M G T)

kubectl describe -n 命名空間 pod <pod名稱>
查看Pod中每個容器的資源量限制kubectl describe node <node名稱>
查看Node節點中的每個Pod或總的資源限制使用情況

Pod 和 容器 的資源請求和限制

spec.containers[].resources.requests.cpu?? ??? ?//定義創建容器時預分配的CPU資源
spec.containers[].resources.requests.memory?? ??? ?//定義創建容器時預分配的內存資源
spec.containers[].resources.limits.cpu?? ??? ??? ?//定義 cpu 的資源上限?
spec.containers[].resources.limits.memory?? ??? ?//定義內存的資源上限

CPU 資源單位
CPU 資源的 request 和 limit 以 cpu 為單位。Kubernetes 中的一個 cpu 相當于1個 vCPU(1個超線程)。
Kubernetes 也支持帶小數 CPU 的請求。spec.containers[].resources.requests.cpu 為 0.5 的容器能夠獲得一個 cpu 的一半(cpu中一個核的一半。多核需要乘以核數) CPU 資源(類似于Cgroup對CPU資源的時間分片)。表達式 0.1 等價于表達式 100m(毫核),表示每 1000 毫秒內容器可以使用的 CPU 時間總量為 0.1*1000 毫秒。
Kubernetes 不允許設置精度小于 1m 的 CPU 資源。?

內存 資源單位?
內存的 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

示例1:

apiVersion: v1
kind: Pod
metadata:name: frontend
spec:containers:- name: appimage: images.my-company.example/app:v4env: #MySQL必須要有這個環境變量 并且內存至少1G- name: MYSQL_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"- name: log-aggregatorimage: images.my-company.example/log-aggregator:v6resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"

此例子中的 Pod 有兩個容器。每個容器的 request 值為 0.25 cpu 和 64MiB 內存,每個容器的 limit 值為 0.5 cpu 和 128MiB 內存。

那么可以認為該 Pod 的總的資源 request 為 0.5 cpu 和 128 MiB 內存,總的資源 limit 為 1 cpu 和 256MiB 內存。

MySQL需要的內存至少1G,這里可能會報錯OOM不停重啟。實例2將修改內存限制

示例2:cpu限制的簡便寫法,并放寬內存限制

vim pod2.yamlapiVersion: v1
kind: Pod
metadata:name: frontend
spec:containers:- name: webimage: nginxenv:- name: WEB_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"- name: dbimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"resources:requests:memory: "512Mi"cpu: "0.5"limits:memory: "1Gi"cpu: "1"
kubectl apply -f pod2.yaml
kubectl describe pod frontend
kubectl get pods -o wideNAME ? ? ? READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? NODE ? ? NOMINATED NODE ? READINESS GATES
frontend ? 2/2 ? ? Running ? 5 ? ? ? ? ?15m ? 10.244.2.4 ? node02 ? <none> ? ? ? ? ? <none>
kubectl describe nodes node02?? ??? ??? ??? ?#由于當前虛擬機有2個CPU,所以Pod的CPU Limits一共占用了50%Namespace ? ? ? ? ? ? ? ? ?Name ? ? ? ? ? ? ? ? ? ? ? ? ? CPU Requests ?CPU Limits ?Memory Requests ?Memory Limits ?AGE--------- ? ? ? ? ? ? ? ? ?---- ? ? ? ? ? ? ? ? ? ? ? ? ? ------------ ?---------- ?--------------- ?------------- ?---default ? ? ? ? ? ? ? ? ? ?frontend ? ? ? ? ? ? ? ? ? ? ? 500m (25%) ? ?1 (50%) ? ? 128Mi (3%) ? ? ? 256Mi (6%) ? ? 16mkube-system ? ? ? ? ? ? ? ?kube-flannel-ds-amd64-f4pbp ? ?100m (5%) ? ? 100m (5%) ? 50Mi (1%) ? ? ? ?50Mi (1%) ? ? ?19hkube-system ? ? ? ? ? ? ? ?kube-proxy-pj4wp ? ? ? ? ? ? ? 0 (0%) ? ? ? ?0 (0%) ? ? ?0 (0%) ? ? ? ? ? 0 (0%) ? ? ? ? 19h
Allocated resources:(Total limits may be over 100 percent, i.e., overcommitted.)Resource ? ? ? ? ? Requests ? ?Limits-------- ? ? ? ? ? -------- ? ?------cpu ? ? ? ? ? ? ? ?600m (30%) ?1100m (55%)memory ? ? ? ? ? ? 178Mi (4%) ?306Mi (7%)ephemeral-storage ?0 (0%) ? ? ?0 (0%)

重啟策略(restartPolicy)

當 Pod 中的容器退出時通過節點上的 kubelet 重啟容器。適用于 Pod 中的所有容器。

  1. Always:當容器終止退出后,總是重啟容器,默認策略
  2. OnFailure:當容器異常退出(退出狀態碼非0)時,重啟容器;正常退出則不重啟容器
  3. Never:當容器終止退出,從不重啟容器。

#注意:K8S 中不支持重啟 Pod 資源,只有刪除重建。
? ? ? 在用 yaml 方式創建 Deployment 和 StatefulSet 類型時,restartPolicy 只能是 Always,kubectl run 創建 Pod 可以選擇 Always,OnFailure,Never 三種策略

kubectl edit deployment nginx-deployment
......restartPolicy: Always

//示例 命令每過30s退出,但是根據重啟策略默認always會不斷重啟

vim pod3.yamlapiVersion: v1
kind: Pod
metadata:name: foo
spec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 30; exit 3
kubectl apply -f pod3.yaml

//查看Pod狀態,等容器啟動后30秒后執行exit退出進程進入error狀態,就會重啟次數加1

kubectl get pods -wNAME   READY   STATUS              RESTARTS   AGE
foo    0/1     ContainerCreating   0          7s
foo    1/1     Running             0          21s
foo    0/1     Error               0          50s
foo    1/1     Running             1          66s
foo    0/1     Error               1          97s
foo    0/1     CrashLoopBackOff    1          111s
foo    1/1     Running             2          2m7s
foo    0/1     Error               2          2m37s
foo    0/1     CrashLoopBackOff    2          2m52s
foo    1/1     Running             3          3m23s
foo    0/1     Error               3          3m53s
foo    0/1     CrashLoopBackOff    3          4m7s
foo    1/1     Running             4          5m
foo    0/1     Error               4          5m30s
foo    0/1     CrashLoopBackOff    4          5m43s
foo    1/1     Running             5          6m51s
foo    0/1     Error               5          7m21s
foo    0/1     CrashLoopBackOff    5          7m36s
foo    1/1     Running             6          10m
foo    0/1     Error               6          10m
kubectl delete -f pod3.yaml

?更改為從不重啟

vim pod3.yamlapiVersion: v1
kind: Pod
metadata:name: foo
spec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 30; exit 3restartPolicy: Never

#注意:跟container同一個級別

kubectl apply -f pod3.yaml

//容器進入error狀態不會進行重啟

kubectl get pods -w

健康檢查:又稱為探針(Probe)

探針是由kubelet對容器執行的定期診斷。

官網示例:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

Pod 容器的 3 種探針(健康檢查)【重中之重】

  • 存活探針(livenessProbe):探測是否正常運行。如果探測失敗則kubelet殺掉容器(Pod容器會根據重啟策略決定是否重啟)
  • 就緒探針(readinessProbe):探測Pod是否進入就緒狀態(ready狀態欄1/1),并做好接收service請求的準備。如果探測失敗則Pod會變成未就緒狀態(ready狀態欄0/1),service資源會刪除所關聯的端點(endpoints),并不再轉發請求給就緒探測失敗的Pod
  • 啟動探針(startupProbe):探測容器內的應用是否啟動成功。在啟動探針探測成功之前,存活探針和就緒探針都會暫時處于禁用狀態,直到啟動探針探測成功

探針的 3 種探測方式

  • exec:在command字段中指定在容器內執行的Linux命令來進行探測,如果命令返回碼為0則認為探測成功,如果返回碼為非0則認為探測失敗
  • tcpSocket:向指定的Pod容器端口發送tcp連接請求,如果端口正確且tcp連接成功則認為探測成功,如果tcp連接失敗則認為探測失敗
  • httpGet:向指定的Pod容器端口和URL路徑發送http get請求,如果http響應狀態碼為2XX 3XX則認為探測成功,如果響應狀態碼為4XX 5XX則認為探測失敗

探針參數
initialDelaySeconds:指定容器啟動后延遲幾秒開始探測
periodSeconds:每天探測的間隔時間(秒數)
failureThreshold:探測連續失敗幾次后判斷探測失敗
timeoutSeconds:指定探測超時等待時間(秒數)

How to know the args probe have?

kubectl explain pod.spec.containers
查看有哪些探針kubectl explain pod.spec.containers.livenessprobe
#查看具體探針參數

//示例1:exec方式 根據命令行執行結果判斷

apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-exec
spec:containers:- name: livenessimage: k8s.gcr.io/busyboxargs:- /bin/sh- -c        #容器運行命令 創建文件夾 30秒后刪除。- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60livenessProbe:exec:command: #探針命令,檢查文件夾是否存在。由于30s刪除,30s后存活探針失效,重啟容器- cat- /tmp/healthyfailureThreshold: 1initialDelaySeconds: 5periodSeconds: 5initialDelaySeconds:
指定 kubelet 在執行第一次探測前應該等待5秒,即第一次探測是在容器啟動后的第6秒才開始執行。默認是 0 秒,最小值是 0。periodSeconds:
指定了 kubelet 應該每 5 秒執行一次存活探測。默認是 10 秒。最小值是 1。failureThreshold: 
當探測失敗時,Kubernetes 將在放棄之前重試的次數。 存活探測情況下的放棄就意味著重新啟動容器。
就緒探測情況下的放棄 Pod 會被打上未就緒的標簽。默認值是 3。最小值是 1。timeoutSeconds:探測的超時后等待多少秒。默認值是 1 秒。最小值是 1。
(在 Kubernetes 1.20 版本之前,exec 探針會忽略 timeoutSeconds 探針會無限期地 持續運行,甚至可能超過所配置的限期,直到返回結果為止。)

可以看到 Pod 中只有一個容器。kubelet 在執行第一次探測前需要等待 5 秒,kubelet 會每 5 秒執行一次存活探測。kubelet 在容器內執行命令 cat /tmp/healthy 來進行探測。如果命令執行成功并且返回值為 0,kubelet 就會認為這個容器是健康存活的。 當到達第 31 秒時,這個命令返回非 0 值,kubelet 會殺死這個容器并重新啟動它。

.

編寫測試yaml文件(與上面那段原理無太大區別,命令格式稍作修改)

vim exec.yamlapiVersion: 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"]livenessProbe:exec:command: ["test","-e","/tmp/live"]initialDelaySeconds: 1periodSeconds: 3
kubectl create -f exec.yaml

30秒后刪除文件,導致存活探針認為寄寄,重啟容器?

kubectl describe pods liveness-exec -wEvents:Type     Reason     Age                    From               Message----     ------     ----                   ----               -------Normal   Scheduled  5m13s                  default-scheduler  Successfully assigned default/liveness-exec to node1Normal   Killing    2m17s (x3 over 4m35s)  kubelet            Container liveness-exec-container failed liveness probe, will be restartedNormal   Pulled     107s (x4 over 5m13s)   kubelet            Container image "busybox" already present on machineNormal   Created    107s (x4 over 5m13s)   kubelet            Created container liveness-exec-containerNormal   Started    107s (x4 over 5m13s)   kubelet            Started container liveness-exec-containerWarning  Unhealthy  5s (x13 over 4m41s)    kubelet            Liveness probe failed:
kubectl get pods -wNAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   4          5m45s
liveness-exec   1/1     Running   5          5m45s

若容器是NGINX等,用創建文件再檢測的方法太蠢了,可以直接命令行檢測,指定必定存在的文件?(如index.html)

注意不要混淆,并不是一定通過檢測文件存在性,其本質原理是根據命令行執行結果返回值判斷

示例2:httpGet方式

apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-http
spec:containers:- name: livenessimage: k8s.gcr.io/livenessargs:- /serverlivenessProbe:httpGet:path: /healthz        #原理為通過8080端口 發送http get請求 get /healthz 查看返回的狀態碼port: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 3periodSeconds: 3

在這個配置文件中,可以看到 Pod 也只有一個容器。initialDelaySeconds 字段告訴 kubelet 在執行第一次探測前應該等待 3 秒。periodSeconds 字段指定了 kubelet 每隔 3 秒執行一次存活探測。kubelet 會向容器內運行的服務(服務會監聽 8080 端口)發送一個 HTTP GET 請求來執行探測。如果服務器上 /healthz 路徑下的處理程序返回成功代碼,則 kubelet 認為容器是健康存活的。如果處理程序返回失敗代碼,則 kubelet 會殺死這個容器并且重新啟動它。

任何大于或等于 200 并且小于 400 的返回代碼標示成功,其它返回代碼都標示失敗。

編寫測試yaml文件

vim httpget.yamlapiVersion: v1
kind: Pod
metadata:name: liveness-httpgetnamespace: default
spec:containers:- name: liveness-httpget-containerimage: nginximagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10


?? ? ?

kubectl create -f httpget.yaml
創建pod
kubectl get pods -w #-w實時更新NAME ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE
liveness-httpget ? 1/1 ? ? Running ? 1 ? ? ? ? ?2m44s

?再開個終端,執行刪除

kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html-- 為免交互不進入容器執行命令
去容器里刪除探針指向的主頁文件,這樣探針不通過,容器重啟

只會重啟一次,因為刪除了文件,容器重啟,根據鏡像又生成了這個文件。?

示例3:tcpSocket方式

apiVersion: v1
kind: Pod
metadata:name: goproxylabels:app: goproxy
spec:containers:- name: goproxyimage: k8s.gcr.io/goproxy:0.1ports:- containerPort: 8080         readinessProbe:               #就緒探針,效果是node顯示notready,不會重啟容器tcpSocket:port: 8080                #與8080端口 進行tcp三次握手 檢測initialDelaySeconds: 5periodSeconds: 10livenessProbe:                #存活探針,不通過重啟容器tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 20

這個例子同時使用 readinessProbe 和 livenessProbe 探測。kubelet 會在容器啟動 5 秒后發送第一個 readinessProbe 探測。這會嘗試連接 goproxy 容器的 8080 端口。如果探測成功,kubelet 將繼續每隔 10 秒運行一次檢測。除了 readinessProbe 探測,這個配置包括了一個 livenessProbe 探測。kubelet 會在容器啟動 15 秒后進行第一次 livenessProbe 探測。就像 readinessProbe 探測一樣,會嘗試連接 goproxy 容器的 8080 端口。如果 livenessProbe 探測失敗,這個容器會被重新啟動。

編寫測試yaml?

vim tcpsocket.yamlapiVersion: v1
kind: Pod
metadata:name: probe-tcp
spec:containers:- name: nginximage: nginxlivenessProbe:initialDelaySeconds: 5timeoutSeconds: 1tcpSocket:port: 8080        #監聽8080口 但是由于NGINX提供80端口服務,所以存活探針會重啟容器periodSeconds: 10failureThreshold: 2
kubectl create -f tcpsocket.yaml
kubectl exec -it probe-tcp ?-- netstat -natp-- 為免交互不進入容器執行命令Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address ? ? ? ? ? Foreign Address ? ? ? ? State ? ? ? PID/Program name ? ?
tcp ? ? ? ?0 ? ? ?0 0.0.0.0:80 ? ? ? ? ? ? ?0.0.0.0:* ? ? ? ? ? ? ? LISTEN ? ? ?1/nginx: master pro

監聽8080口 但是由于NGINX提供80端口服務,所以存活探針會重啟容器?

kubectl get pods -wNAME ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
probe-tcp ? 1/1 ? ? Running ? ? ? ? ? ? 0 ? ? ? ? ?1s
probe-tcp ? 1/1 ? ? Running ? ? ? ? ? ? 1 ? ? ? ? ?25s ? ? ? #第一次是 init(5秒) + period(10秒) * 2
probe-tcp ? 1/1 ? ? Running ? ? ? ? ? ? 2 ? ? ? ? ?45s ? ? ? #第二次是 period(10秒) + period(10秒) ?重試了兩次
probe-tcp ? 1/1 ? ? Running ? ? ? ? ? ? 3 ? ? ? ? ?65s

若要通過探針測試,將探針監聽端口改為NGINX的80口,就不會在重啟容器。?

示例4:存活探針 就緒探針 啟動探針 合集

vim readiness-httpget.yamlapiVersion: v1
kind: Pod
metadata:name: readiness-httpgetnamespace: default
spec:containers:- name: readiness-httpget-containerimage: nginximagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80startupProbe: #啟動探針 /index2.html存在,才會將檢測權限交給 存活探針 就緒探針httpGet:port: httppath: /index2.htmlfailureThreshold: 30periodSeconds: 10livenessProbe: #存活探針 /index.html存在,不會重啟httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10readinessProbe: #就緒探針 /index1.html存在,才會readyhttpGet:port: httppath: /index1.htmlinitialDelaySeconds: 1periodSeconds: 3

因為有啟動探針 應用最多有5分鐘的(?failureThreshold * periodSeconds =30*10=300s )的時間完成啟動

一旦成功一次,存活探針和就緒探針就會接管對容器的檢測

若啟動探針一直沒有成功,容器在300s后被殺死,并且根據重啟策略進行重啟。


根據配置文件創建pod資源
kubectl create -f readiness-httpget.yaml

?啟動探針部分

kubectl describe pod readiness-httpget
查看錯誤詳細信息

?目前是啟動探針出錯(啟動探針完成后才會把后續探測權限交給 存活和就緒探針)

進入容器,創建啟動探針需要的文件?

kubectl exec -it readiness-httpget -- touch /usr/share/nginx/html/index2.html-- 為免交互不進入容器執行命令

?啟動探針條件滿足,此時步進到就緒探針無文件

kubectl describe pod readiness-httpget
查看錯誤詳細信息


?就緒探針部分

?//readiness就緒探針探測失敗,無法進入READY狀態

kubectl get podsNAME ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
readiness-httpget ? 0/1 ? ? Running ? 0 ? ? ? ? ?18s

進入容器,滿足就緒探針需求?

kubectl exec -it readiness-httpget shcd /usr/share/nginx/html/
ls50x.html ? ?index.html
echo 123 > index1.html
exit········································或者免交互命令
kubectl exec -it readiness-httpget -- touch /usr/share/nginx/html/index1.html

就緒探針滿足,pod就緒?

kubectl get podsNAME ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
readiness-httpget ? 1/1 ? ? Running ? 0 ? ? ? ? ?2m31s

存活探針部分

若此時再刪除存活探針指向的文件(http get不到index.html 容器重啟)

kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html-- 為免交互不進入容器執行命令
kubectl get pods -wNAME ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
readiness-httpget ? 1/1 ? ? Running ? 0 ? ? ? ? ?4m10s
readiness-httpget ? 0/1 ? ? Running ? 1 ? ? ? ? ?4m15s

//示例5:同一pod內 多容器就緒檢測 查看ready與service相關信息

vim readiness-myapp.yamlapiVersion: v1
kind: Pod
metadata:name: myapp1labels:app: myapp
spec:containers:- name: myappimage: nginxports:- name: httpcontainerPort: 80               #三個一樣的容器,一樣的就緒探針和條件,測試多就緒探針顯示readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:name: myapp2labels:app: myapp
spec:containers:- name: myappimage: nginxports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:name: myapp3labels:app: myapp
spec:containers:- name: myappimage: nginxports:- 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
kubectl create -f readiness-myapp.yaml
kubectl get pods,svc,endpoints -o wideNAME         READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
pod/myapp1   1/1     Running   0          66s   10.244.1.33   node1   <none>           <none>
pod/myapp2   1/1     Running   0          66s   10.244.2.34   node2   <none>           <none>
pod/myapp3   1/1     Running   0          66s   10.244.2.33   node2   <none>           <none>NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE    SELECTOR
service/kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP        2d8h   <none>
service/myapp              ClusterIP   10.111.198.14   <none>        80/TCP         66s    app=myapp
service/nginx-service666   NodePort    10.96.38.38     <none>        80:31537/TCP   6h2m   app=nginxNAME                         ENDPOINTS                                      AGE
endpoints/kubernetes         192.168.80.101:6443                            2d8h
endpoints/myapp              10.244.1.33:80,10.244.2.33:80,10.244.2.34:80   66s
endpoints/nginx-service666   <none>                                         6h2m

刪除 myapp1 就緒探針指向的文件?

kubectl exec -it pod/myapp1 -- rm -rf /usr/share/nginx/html/index.html

//readiness探測失敗,Pod 無法進入READY狀態,且端點控制器將從 endpoints 中剔除刪除該 Pod(myapp1 ) 的 IP 地址

kubectl get pods,svc,endpoints -o wideNAME         READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
pod/myapp1   0/1     Running   0          2m48s   10.244.1.33   node1   <none>           <none>
pod/myapp2   1/1     Running   0          2m48s   10.244.2.34   node2   <none>           <none>
pod/myapp3   1/1     Running   0          2m48s   10.244.2.33   node2   <none>           <none>NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE     SELECTOR
service/kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP        2d8h    <none>
service/myapp              ClusterIP   10.111.198.14   <none>        80/TCP         2m48s   app=myapp
service/nginx-service666   NodePort    10.96.38.38     <none>        80:31537/TCP   6h4m    app=nginxNAME                         ENDPOINTS                       AGE
endpoints/kubernetes         192.168.80.101:6443             2d8h
endpoints/myapp              10.244.2.33:80,10.244.2.34:80   2m48s
endpoints/nginx-service666   <none>                          6h4m

啟動、退出動作

啟動 退出 動作,不像command一樣會把鏡像內的默認命令覆蓋掉。

而是在容器啟動和結束時執行。

Pod 應用容器生命周期的啟動動作和退出動作

spec.containers.lifecycle.postStart ? 配置子字段 exec.command 設置 Pod 容器啟動時額外的命令操作
spec.containers.lifecycle.preStop ? ? 配置子字段 exec.command 設置 Pod 容器運行中被kubelet殺掉退出時所執行的命令操作(不包含容器自行退出的情況)

vim post.yamlapiVersion: v1
kind: Pod
metadata:name: lifecycle-demo
spec:containers:- name: lifecycle-demo-containerimage: nginxlifecycle:   #此為關鍵字段postStart:                 #執行完init所需要的內容后創建容器,先執行poststartexec:command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"]preStop:                   #在容器結束時候執行prestopexec:command: ["/bin/sh", "-c", "echo Hello from the poststop handler >> /var/log/nginx/message"]volumeMounts:                #由于容器結束,日志會隨一并消失,所以加上掛載卷,存放日志。- name: message-logmountPath: /var/log/nginx/readOnly: false #可讀可寫initContainers:        #init容器在普通容器之前執行完畢,用于提供容器依賴項。所以第一個執行。- name: init-myserviceimage: nginxcommand: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]volumeMounts:- name: message-logmountPath: /var/log/nginx/readOnly: falsevolumes:         #定義一個存儲卷,讓容器掛載,存放日志- name: message-loghostPath:   #宿主機路徑path: /data/volumes/nginx/log/type: DirectoryOrCreate #不存在就創建
kubectl apply -f post.yaml

查看在哪個節點上?(因為雖然pod可以隨地查看,但是掛載的宿主機目錄在對應宿主機上)

kubectl get pods -o wideNAME ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE ? ?IP ? ? ? ? ? ?NODE ? ? NOMINATED NODE ? READINESS GATES
lifecycle-demo ? 1/1 ? ? Running ? 0 ? ? ? ? ?2m8s ? 10.244.2.28 ? node02 ? <none> ? ? ? ? ? <none>

免交互查看容器內輸出

kubectl exec -it lifecycle-demo -- cat /var/log/nginx/message
Hello initContainers
Hello from the postStart handler

//在 node02 節點(宿主機)上查看

cd /data/volumes/nginx/log/
lsaccess.log ?error.log ?messagecat message?Hello initContainersHello from the postStart handler#由上可知,init Container先執行,然后當一個主容器啟動后,Kubernetes 將立即發送 postStart 事件。

//刪除 pod 后,再在 node02 節點上(宿主機)查看

kubectl delete pod lifecycle-demo
[root@node02 log]# cat message?Hello initContainers
Hello from the postStart handler
Hello from the poststop handler


#由上可知,當在容器被終結之前, Kubernetes 將發送一個 preStop 事件。

并且無論是kubectl delete結束pod(容器),還是由于存活探針不滿足導致kubelet將容器重啟(刪除),都不會影響prestop的執行。

但是!如果是容器執行完命令自行退出(無論容器內執行 exit 0 正常退出還是執行 exit 3 異常退出),不會執行prestop。

概括一下就是,只有在容器 運行時 被第三方 退出 才會執行prestop。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36630.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36630.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36630.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java課題筆記~ JSP開發模型

MVC 1.JSP演化歷史 1. 早期只有servlet&#xff0c;只能使用response輸出標簽數據&#xff0c;非常麻煩 2. 后來有了jsp&#xff0c;簡化了Servlet的開發&#xff0c;如果過度使用jsp&#xff0c;在jsp中即寫大量的java代碼&#xff0c;有寫html表&#xff0c;造成難于維護&…

計算機網絡實驗4:HTTP、DNS協議分析

文章目錄 1. 主要教學內容2. HTTP協議3. HTTP分析實驗【實驗目的】【實驗原理】【實驗內容】【實驗思考】 4. HTTP分析實驗可能遇到的問題4.1 捕捉不到http報文4.2 百度是使用HTTPS協議進行傳輸4.3 Wireshark獲得數據太多如何篩選4.4 http報文字段含義不清楚General&#xff08…

[4G/5G/6G專題基礎-161]:常見的濾波技術

1. 濾波概述 1.1 什么是濾波 濾波&#xff08;Filtering&#xff09;是信號處理中的一種基本操作&#xff0c;用于改變信號的特性或者去除信號中的干擾成分。濾波器可以看作是一種系統&#xff0c;將輸入信號作為輸入&#xff0c;經過處理后產生輸出信號。 濾波在信號處理中…

Git和GitHub

文章目錄 1.Git介紹2. 常用命令3. Git分支操作4. Git團隊協作機制5. GitHub操作6. IDEA集成Git7.IDEA操作GitHub8. Gitee 1.Git介紹 Git免費的開源的分布式版本控制系統&#xff0c;可以快速高效從小到大的各種項目 Git易于學習&#xff0c;占地面積小&#xff0c;性能快。它…

@RunWith的使用

引言 當談到在Java中進行單元測試時&#xff0c;JUnit是開發人員的常見選擇之一。JUnit是一個流行的單元測試框架&#xff0c;它允許您編寫和執行測試來驗證代碼的正確性。在JUnit中&#xff0c;RunWith注解是一個強大的工具&#xff0c;它可以用來定制測試運行器&#xff0c;…

【日常積累】RPM包依賴下載及私有yum倉庫搭建

概述 某些時候&#xff0c;我們需要下載某個RPM包依賴的依賴。如某些內網環境&#xff0c;就需要自行準備rpm包。可以通過能上互聯網的服務器進行相應的rpm包下載&#xff0c;然后在拷貝到相應的服務器安裝&#xff0c;或者搭建自己的內容rpm包倉庫。 查看*.rpm 包依賴&#…

Flink多流處理之Broadcast(廣播變量)

寫過Spark批處理的應該都知道,有一個廣播變量broadcast這樣的一個算子,可以優化我們計算的過程,有效的提高效率;同樣在Flink中也有broadcast,簡單來說和Spark中的類似,但是有所區別,首先Spark中的broadcast是靜態的數據,而Flink中的broadcast是動態的,也就是源源不斷的數據流.在…

批處理自動切換ip地址與網絡的啟用、禁用

啟用禁用網絡 echo off :: BatchGotAdmin :------------------------------------- REM --> Check for permissions >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" REM --> If error flag set,…

什么是微服務?

2.微服務的優缺點 優點 單一職責原則每個服務足夠內聚&#xff0c;足夠小&#xff0c;代碼容易理解&#xff0c;這樣能聚焦一個指定的業務功能或業務需求&#xff1b;開發簡單&#xff0c;開發效率提高&#xff0c;一個服務可能就是專一的只干一件事&#xff1b;微服務能夠被小…

命令提示符之操作基礎(Windows)

打開命令提示符 方法一 打開指定文件的文件夾&#xff0c;在路徑欄里輸入“cmd”&#xff0c;回車&#xff0c;就進入控制臺了。默認路徑就是指定文件夾的路徑。 方法二 打開指定的文件夾&#xff0c;按住shift鍵&#xff0c;在空白處右擊&#xff0c;在菜單欄中選擇“在此處打…

社區團購商城拼團秒殺接龍分銷團長小程序開源版開發

社區團購商城拼團秒殺接龍分銷團長小程序開源版開發 功能介紹&#xff1a; 商品管理&#xff1a;增加商品-商品列表-商品分類-商品單/多規格-商品標簽 訂單管理&#xff1a;訂單列表-訂單挑選-訂單導出-訂單打印-批量發貨-商品評價 會員管理&#xff1a;會員列表-會員挑選-會員…

【Git】—— 標簽管理

目錄 &#xff08;一&#xff09;理解標簽 1、作用 &#xff08;二&#xff09;創建標簽 &#xff08;三&#xff09;操作標簽 1、刪除標簽 2、推送標簽 3、刪除遠程標簽 &#xff08;一&#xff09;理解標簽 標簽 tag &#xff0c;可以簡單的理解為是對某次 commit 的…

python中的迭代器和生成器

一、迭代器 支持迭代的容器&#xff0c;如列表&#xff08;list&#xff09;、元組&#xff08;tuple&#xff09;、字典&#xff08;dict&#xff09;、集合&#xff08;set&#xff09;這些序列式容器。 自定義迭代器的類中必須實現以下2個方法&#xff1a; __next__(self)…

監控Kubernetes 控制面組件的關鍵指標

控制面組件的監控&#xff0c;包括 APIServer、Controller-manager&#xff08;簡稱 CM&#xff09;、Scheduler、etcd 四個組件。 1、APIServer APIServer 的核心職能是 Kubernetes 集群的 API 總入口&#xff0c;Kube-Proxy、Kubelet、Controller-Manager、Scheduler 等都需…

【字符串】649. Dota2 參議院

649. Dota2 參議院 解題思路 R true 表示循環結束之后 字符串仍然存在 Rflag > 0 說明R在D之前出現 R可以消滅Dflag < 0 說明D在R之前出現 D 可以消滅R一旦其中有一個為false 說明只剩下R 或者D 那么就可以決定誰獲勝遍歷字符串 如果當前字符是R 判斷flag 如果flag &l…

‘open3d.open3d.geometry.PointCloud‘ object has no attribute ‘voxel_down_sample‘

scene_cloud open3d.geometry.PointCloud() scene_cloud.points open3d.utility.Vector3dVector(scene_points) scene_cloud scene_cloud.voxel_down_sample(voxel_size) 執行上面代碼第三句報錯&#xff0c;出現了下面這個錯誤&#xff1a; AttributeError: open3d.open…

TCP 協議十大相關特性總結

目錄 一、TCP特性 二、報文格式 TCP十大核心特性 1. 確認應答 2. 超時重傳 3. 連接管理(三次握手,四次揮手) 三次握手 四次揮手 4. 滑動窗口 情況一:接收方的ACK丟失 情況二:發送方的數據包丟失 5. 流量控制 6. 擁塞控制 7. 延遲應答 8. 捎帶應答 9. 字節流粘包問題 10. TCP的…

k8s--使用cornJob定時執行sql文件

CronJob apiVersion: batch/v1beta1 kind: CronJob metadata:name: hello spec:schedule: "0 * * * *"jobTemplate:spec:template:spec:containers:- name: postgres-alpineimage: xxxximagePullPolicy: IfNotPresentcommand:- psql- -h- 數據庫服務地址- -d- 數據庫…

大語言模型:LLM的概念是個啥?

一、說明 大語言模型&#xff08;維基&#xff1a;LLM- large language model&#xff09;是以大尺寸為特征的語言模型。它們的規模是由人工智能加速器實現的&#xff0c;人工智能加速器能夠處理大量文本數據&#xff0c;這些數據大部分是從互聯網上抓取的。 [1]所構建的人工神…

02 - git 文件重命名

查看所有文章鏈接&#xff1a;&#xff08;更新中&#xff09;GIT常用場景- 目錄 文章目錄 1. 第一種方式2. 第二種方式 1. 第一種方式 mv kongfu_person.txt kongfu.txt git add .2. 第二種方式 git mv kongfu_person.txt kongfu.txt