欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Kubernetes中Pod容器的資源限制和探針配置方式

 更新時間:2025年07月04日 10:15:11   作者:wys_jj  
這篇文章主要介紹了Kubernetes中Pod容器的資源限制和探針配置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

在 Kubernetes 中,定義 Pod 時可以選擇性地為每個容器設定所需要的資源數(shù)量。

最常見的可設定資源是 CPU 和內存大小,以及其他類型的資源;另一方面,通過配置探針,可以確保容器在運行時保持健康,并且只有在準備好接收流量時才會被負載均衡器引導流量。

從而提高應用程序的可靠性和穩(wěn)定性。

一、容器管理資源概念

1.1.概述

在 K8s 中,對 Pod 容器的資源限制主要圍繞著兩個關鍵參數(shù):request 資源和 limit 資源,用于配置 CPU 和內存的使用情況;避免資源競爭和不必要的浪費,同時確保 Pod 在運行時具有足夠的資源支持。

官網(wǎng)示例:

https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

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

spec.containers[].resources.requests.cpu        //定義創(chuàng)建容器時預分配的CPU資源
spec.containers[].resources.requests.memory        //定義創(chuàng)建容器時預分配的內存資源
spec.containers[].resources.limits.cpu            //定義 cpu 的資源上限 
spec.containers[].resources.limits.memory        //定義內存的資源上限
request 預留資源

創(chuàng)建 pod 容器時需要預留的資源量,cpu(0.5 或 500m),內存 Mi、Gi(以2為底的冪數(shù)),M、G(以10為底)。

spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory
limit 限制資源

pod 容器能夠使用資源量的一個上限。如:4Gi 代表內存上限不允許超過上限值;1 代表 cpu 上限不允許超過上限值。

spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory

1.3. K8s 中的資源單位

1.3.1 CPU 資源單位

CPU 資源的 request 和 limit 以 cpu 為單位。在 K8s 中,一個 CPU 等于 1 個物理 CPU 核 或者 1 個虛擬核, 取決于節(jié)點是一臺物理主機還是運行在某物理主機上的虛擬機。

當定義一個容器,將其 spec.containers[].resources.requests.cpu 設置為 0.5 時, 所請求的 CPU 是請求 1.0 CPU 時的一半。 對于 CPU 資源單位,數(shù)量表達式 0.1 等價于表達式 100m(一百毫核),可以看作 “100 millicpu”。 

注意:K8s 不允許設置精度小于 1m 或 0.001 的 CPU 資源。

1.3.2 內存資源單位

內存的 request 和 limit 以字節(jié)為單位。 可以使用普通的整數(shù),或者帶有以下 數(shù)量后綴 的定點數(shù)字來表示內存:E、P、T、G、M、k。 也可以使用對應的 2 的冪數(shù):Ei、Pi、Ti、Gi、Mi、Ki。

PS:在買硬盤的時候,操作系統(tǒng)報的數(shù)量要比產品標出或商家號稱的小一些,主要原因是標出的是以 MB、GB為單位的,1GB 就是1,000,000,000Byte,而操作系統(tǒng)是以2進制為處理單位的,因此檢查硬盤容量時是以MiB、GiB為單位,1GiB=2^30=1,073,741,824,相比較而言,1GiB要比1GB多出1,073,741,824-1,000,000,000=73,741,824Byte,所以檢測實際結果要比標出的少一些。

1.4. 資源限制配置規(guī)則

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

如果給容器設置了內存的 limit 值,但未設置內存的 request 值,Kubernetes 會自動為其設置與內存 limit 相匹配的 request 值;類似的 cpu 同理。

1.5. 容器資源示例

1.5.1 request 與 limit 創(chuàng)建 pod 模板

以下例子中的 Pod 有兩個容器。每個容器的 request 值為 0.25 cpu 和 64MiB 內存,每個容器的 limit 值為 0.5 cpu 和 128MiB 內存。那么可以認為該 Pod 的總的資源 request 為 0.5 cpu 和 128 MiB 內存,總的資源 limit 為 1 cpu 和 256MiB 內存。

[root@master01 demo]# vim demo1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: demo-01
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    env:                         # 定義了容器的環(huán)境變量
    - name: MYSQL_ROOT_PASSWORD  # 設置環(huán)境變量
      value: "123456"            # 環(huán)境變量的值
    resources:                   # 容器的資源限制和請求
      requests:                  # 容器的資源請求
        memory: "64Mi"           # 請求容器使用的內存量為64MiB
        cpu: "250m"              # 請求容器使用的CPU量為250 m
      limits:                    # 容器的資源限制
        memory: "128Mi"          # 限制容器使用的最大內存量為128MiB
        cpu: "500m"              # 限制容器使用的最大CPU量為500 m
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:                   # 容器的資源限制和請求
      requests:                  # 容器的資源請求
        memory: "64Mi"           # 容器使用的內存量為64MiB
        cpu: "250m"              # 第二個容器使用的CPU量為250 m
      limits:                    # 容器的資源限制
        memory: "128Mi"          # 限制第二個容器使用的最大內存量為128MiB
        cpu: "500m"              # 限制第二個容器使用的最大CPU量為500 m

1.5.2. OOMKilled 內存耗盡保護機制

為了模擬內存耗盡情況并觀察OOMKilled(Out Of Memory Killed)內存耗盡保護機制的效果,我們將調整數(shù)據(jù)庫容器的資源請求(requests)和內存限制(limits)到一個較小的值,以便觸發(fā)內存不足的情況。

請注意,在生產環(huán)境中,調整容器的資源請求和限制應該謹慎進行,以避免對系統(tǒng)產生不可預料的影響。

① 創(chuàng)建 yaml 文件

[root@master01 demo]# vim demo2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: web-db
spec:
  containers:
  - name: web
    image: nginx
    env:
    - name: WEB_ROOT_PASSWORD
      value: "123123"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "123123"
    resources:
      requests:
        memory: "64Mi"
        cpu: "0.25"
      limits:
        memory: "128Mi"
        cpu: "500m"

 ② 啟動 pod

[root@master01 demo]# kubectl apply -f demo2.yaml 
pod/web-db created

③ 查看資源信息

[root@master01 demo]# kubectl get pod web-db -w
NAME     READY   STATUS              RESTARTS   AGE
web-db   0/2     ContainerCreating   0          18s
web-db   2/2     Running             0          63s
web-db   1/2     OOMKilled           0          76s
web-db   2/2     Running             1          93s
web-db   1/2     OOMKilled           1          105s
web-db   1/2     CrashLoopBackOff    1          2m
web-db   2/2     Running             2          2m1s
web-db   1/2     OOMKilled           2          2m14s
web-db   1/2     CrashLoopBackOff    2          2m28s
# 多次出現(xiàn)的 OOMKilled 表示容器由于內存耗盡而被系統(tǒng)終止
 
[root@master01 demo]# kubectl describe pod web-db 
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  3m20s                default-scheduler  Successfully assigned default/web-db to node01
  Normal   Pulling    3m19s                kubelet            Pulling image "nginx"
  Normal   Pulled     3m4s                 kubelet            Successfully pulled image "nginx" in 15.521857377s
  Normal   Created    3m4s                 kubelet            Created container web
  Normal   Started    3m4s                 kubelet            Started container web
  Normal   Pulled     2m18s                kubelet            Successfully pulled image "mysql" in 46.048445572s
  Normal   Pulled     108s                 kubelet            Successfully pulled image "mysql" in 15.474925496s
  Normal   Pulled     80s                  kubelet            Successfully pulled image "mysql" in 399.833869ms
  Normal   Pulling    38s (x4 over 3m4s)   kubelet            Pulling image "mysql"
  Normal   Created    38s (x4 over 2m17s)  kubelet            Created container db
  Normal   Started    38s (x4 over 2m17s)  kubelet            Started container db
  Normal   Pulled     38s                  kubelet            Successfully pulled image "mysql" in 388.467767ms
  Warning  BackOff    13s (x5 over 95s)    kubelet            Back-off restarting failed container
# 容器 "db" 失敗并且在多次嘗試后仍然無法成功啟動,導致觸發(fā)了 BackOff 機制

④ 調整資源配額限制

[root@master01 demo]# kubectl delete -f demo2.yaml 
pod "web-db" deleted
[root@master01 demo]# vim demo2.yaml
    resources:
      requests:
        memory: "128Mi"
        cpu: "0.5"
      limits:
        memory: "1Gi"
        cpu: "1000m"

⑤ 再次嘗試啟動 pod 

[root@master01 demo]# kubectl apply -f demo2.yaml 
pod/web-db created
 
[root@master01 demo]# kubectl get pod web-db 
NAME     READY   STATUS    RESTARTS   AGE
web-db   2/2     Running   0          42s

⑥ 查看 node 節(jié)點資源占比

[root@master01 demo]# kubectl get pod web-db -o wide
NAME     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
web-db   2/2     Running   0          94s   10.244.1.22   node01   <none>           <none>
 
[root@master01 demo]# kubectl describe node node01
  Namespace                   Name                     CPU Requests  CPU Limits   Memory Requests  Memory Limits  AGE
  ---------                   ----                     ------------  ----------   ---------------  -------------  ---
  default                     pod-01                   0 (0%)        0 (0%)       0 (0%)           0 (0%)         4h19m
  default                     web-db                   750m (37%)    1500m (75%)  192Mi (11%)      1152Mi (66%)   2m13s
  kube-flannel                kube-flannel-ds-wz8p2    100m (5%)     0 (0%)       50Mi (2%)        0 (0%)         8d
  kube-system                 kube-proxy-w7vl7         0 (0%)        0 (0%)       0 (0%)           0 (0%)         8d
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests     Limits
  --------           --------     ------
  cpu                850m (42%)   1500m (75%)
  memory             242Mi (14%)  1152Mi (66%)
  ephemeral-storage  0 (0%)       0 (0%)
  hugepages-1Gi      0 (0%)       0 (0%)
  hugepages-2Mi      0 (0%)       0 (0%)

Pod "web-db" 的資源請求和限制如下:

  • CPU 請求:750m,CPU 限制:1500m
  • 內存請求:192Mi,內存限制:1152Mi

已分配的資源情況如下:

  • CPU 請求總量:850m(42%),CPU 限制總量:1500m(75%)
  • 內存請求總量:242Mi(14%),內存限制總量:1152Mi(66%) 

二、Pod 容器的探針

2.1. 概述

探針是由 kubelet 對容器執(zhí)行的定期診斷。容器的探針是一種關鍵的機制,用于監(jiān)測和管理容器的健康狀態(tài),確保容器在各種情況下都能正常運行。通過配置適當?shù)奶结?,可以提高容器的可靠性和穩(wěn)定性,確保容器能夠有效應對各種運行時情況,并及時處理健康狀態(tài)的變化。

2.2.探針的三種規(guī)則

2.2.1 存活探針(Liveness Probe)

用于確定容器是否正在運行并且健康。如果存活探針失敗,Kubernetes 將根據(jù)重啟策略(如 `RestartPolicy`)嘗試重新啟動容器。如果容器不提供存活探針,則默認狀態(tài)為 Success。

2.2.2 就緒探針(Readiness Probe)

用于確定容器是否已準備好接收流量。如果就緒探針失敗,容器將被從 Service 的負載均衡池中移除該 Pod 的 IP 地址,直到就緒探針再次成功。初始延遲之前的就緒狀態(tài)默認為 Failure。如果容器不提供就緒探針,則默認狀態(tài)為 Success。

2.2.3 啟動探針(Startup Probe)

1.17版本增加的。用于確定容器是否已經(jīng)啟動并且已經(jīng)準備好接收其它探針的檢查。啟動探針在容器啟動后執(zhí)行,但在就緒探針和存活探針之前執(zhí)行。

如果 startupProbe 失敗,kubelet 將殺死容器,容器將根據(jù) restartPolicy 來重啟。如果容器沒有配置 startupProbe, 則默認狀態(tài)為 Success。

以上規(guī)則可以同時定義。在 readinessProbe 檢測成功之前,Pod 的 running 狀態(tài)是不會變成 ready 狀態(tài)的。通過配置這些探針,可以確保容器在運行時保持健康,并且只有在準備好接收流量時才會被負載均衡器引導流量。這有助于提高應用程序的可靠性和穩(wěn)定性。

2.3. 探針三種檢查方法

  • exec :在容器內執(zhí)行指定命令。如果命令退出時返回碼為0則認為診斷成功;
  • tcpSocket :對指定端口上的容器的IP地址進行TCP檢查(三次握手)。如果端口打開,則診斷被認為是成功的;
  • httpGet :對指定的端口和路徑上的容器的IP地址執(zhí)行HTTPGet請求。如果響應的狀態(tài)碼大于等于200且小于400,則診斷被認為是成功的。

每次探測都將獲得以下三種結果之一:

  • 成功:容器通過了診斷;
  • 失?。喝萜魑赐ㄟ^診斷;
  • 未知:診斷失敗,因此不會采取任何行動。

2.4.探針配置示例

2.4.1 定義存活命令

許多長時間運行的應用最終會進入損壞狀態(tài),除非重新啟動,否則無法被恢復。 Kubernetes 提供了存活探針來發(fā)現(xiàn)并處理這種情況。

示例1:livenessProbe 規(guī)則,配合 exec 檢查方法。

① 編輯 pod 的 yaml 配置文件

[root@master01 demo]# vim demo3.yaml
apiVersion: v1
kind: Pod
metadata:                     # 元數(shù)據(jù)
  labels:                     # Pod 的標簽
    test: liveness
  name: liveness-exec
spec:                         # Pod 的規(guī)格
  containers:                 # 容器列表
  - name: liveness            # 容器的名稱
    image: busybox            # 一個輕量級的 BusyBox 鏡像
    imagePullPolicy: IfNotPresent # 鏡像拉取策略,先本地后倉庫
    args:                     # 容器的啟動參數(shù)部分
    - /bin/sh
    - -c                      # 后面的內容將作為 shell 的命令執(zhí)行
    - touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 10
# 在容器啟動時執(zhí)行的命令,首先創(chuàng)建一個/tmp/healthy文件,然后等待10秒,接著刪除該文件,最后再等待10秒
    livenessProbe:            # 定義存活探針的配置
      exec:                   # 使用 exec 方式執(zhí)行命令
        command:              # 要執(zhí)行的命令
        - cat
        - /tmp/healthy        # 讀取 /tmp/healthy 文件的內容
      failureThreshold: 1     # 存活探針的失敗閾值為1,即連續(xù)失敗1次后認為探針失敗,默認值是3。最小值是1
      initialDelaySeconds: 3  # 容器啟動后等待3秒開始進行存活探測,其實是4秒,默認是0秒,最小值是0
      periodSeconds: 2        # 每隔2秒進行一次存活探測,默認是10秒。最小值是1。

這個容器生命的前 10 秒,/tmp/healthy 文件是存在的。 所以在這最開始的 10 秒內,執(zhí)行命令 cat /tmp/healthy 會返回成功代碼。 10 秒之后,執(zhí)行命令 cat /tmp/healthy 就會返回失敗代碼。

② 啟動 pod

[root@master01 demo]# kubectl apply -f demo3.yaml 
pod/liveness-exec created

③ 查看容器狀態(tài)詳情信息

[root@master01 demo]# kubectl get pod liveness-exec -w
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   0          3s
liveness-exec   1/1     Running   1          22s
liveness-exec   1/1     Running   2          43s
liveness-exec   1/1     Running   3          63s
liveness-exec   1/1     Running   4          83s
liveness-exec   0/1     CrashLoopBackOff   4          103s
# Pod中的容器liveness由于存活探針失敗而不斷重啟,并最終進入了CrashLoopBackOff狀態(tài)
# 輸出結果顯示RESTARTS的值增加了1。 請注意,一旦失敗的容器恢復為運行狀態(tài),RESTARTS計數(shù)器就會加1
 
查看 Pod 的事件:
[root@master01 demo]# kubectl describe pod liveness-exec
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  2m24s                default-scheduler  Successfully assigned default/liveness-exec to node01
  Normal   Pulled     62s (x5 over 2m24s)  kubelet            Container image "busybox" already present on machine
  Normal   Created    62s (x5 over 2m24s)  kubelet            Created container liveness
  Normal   Started    62s (x5 over 2m24s)  kubelet            Started container liveness
  Warning  Unhealthy  51s (x5 over 2m13s)  kubelet            Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Killing    51s (x5 over 2m13s)  kubelet            Container liveness failed liveness probe, will be restarted
# 顯示存活探針失敗了,這個失敗的容器被殺死并且被重建了
# 是否重啟還是根據(jù)重啟策略來決定,這里明顯是always

2.4.2 定義一個存活態(tài) HTTP 請求接口

另外一種類型的存活探測方式是使用 HTTP GET 請求。

示例2:livenessProbe 規(guī)則,配合 httpGet 檢查方法。

① 編輯 pod 的 yaml 配置文件

[root@master01 demo]# vim demo4.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: soscscs/myapp:v1
    imagePullPolicy: IfNotPresent    # 鏡像拉取策略
    ports:
    - name: http
      containerPort: 80              # 容器內部的端口號為 80
    livenessProbe:                   # 定義存活探針的配置
      httpGet:                       # 使用HTTP GET請求方式進行探測
        port: http                   # 探測請求發(fā)送到的端口為http,即容器內部的80端口
        path: /index.html            # 探測請求的路徑為 /index.html
      initialDelaySeconds: 1         # 容器啟動后等待1秒后開始進行存活探測
      periodSeconds: 3               # 每隔3秒進行一次存活探測
      timeoutSeconds: 5              # 超時時間為5秒

如果存活探針發(fā)送的 HTTPGET 請求返回成功(即能夠訪問到 /index.html),則認為容器是健康的。如果請求失?。o法訪問到 /index.html 或返回錯誤),則認為容器不健康處理程序返回失敗代碼,kubelet 會殺死這個容器并且重新啟動它。

② 啟動 pod 

[root@master01 demo]# kubectl apply -f demo4.yaml 
pod/liveness-httpget created
 
[root@master01 demo]# kubectl get pod liveness-httpget -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
liveness-httpget   1/1     Running   0          65s   10.244.1.24   node01   <none>           <none>
 
嘗試訪問頁面:
[root@master01 demo]# curl 10.244.1.24
Hello MyApp | Version: v1 | <a href="hostname.html" rel="external nofollow" >Pod Name</a>
[root@master01 demo]# curl 10.244.1.24 -I
Server: nginx/1.12.2

③ 刪除容器中 index.html

[root@master01 demo]# kubectl exec -it liveness-httpget -- rm -f /usr/share/nginx/html/index.html

③ 查看容器狀態(tài)詳情信息

[root@master01 demo]# kubectl get pod liveness-httpget 
NAME               READY   STATUS    RESTARTS   AGE
liveness-httpget   1/1     Running   2          5m42s
 
[root@master01 demo]# kubectl describe pod liveness-httpget
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  6m32s                default-scheduler  Successfully assigned default/liveness-httpget to node01
  Normal   Pulling    6m32s                kubelet            Pulling image "soscscs/myapp:v1"
  Normal   Pulled     6m14s                kubelet            Successfully pulled image "soscscs/myapp:v1" in 18.054706565s
  Normal   Created    66s (x3 over 6m13s)  kubelet            Created container liveness-httpget-container
  Warning  Unhealthy  66s (x6 over 2m54s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404
  Normal   Killing    66s (x2 over 2m48s)  kubelet            Container liveness-httpget-container failed liveness probe, will be restarted
  Normal   Pulled     66s (x2 over 2m48s)  kubelet            Container image "soscscs/myapp:v1" already present on machine
  Normal   Started    65s (x3 over 6m13s)  kubelet            Started container liveness-httpget-container

容器中的存活探針失敗是因為 HTTP 探測返回了狀態(tài)碼 404,表示無法訪問到指定的路徑 /index.html。因此,容器被標記為不健康,被 Kubernetes 系統(tǒng)自動重新啟動以嘗試恢復其健康狀態(tài)。 

2.4.3 定義 TCP 的存活探測

使用這種配置時,kubelet 會嘗試在指定端口和容器建立套接字鏈接。 如果能建立連接,這個容器就被看作是健康的,如果不能則這個容器就被看作是有問題的。

示例3:livenessProbe 規(guī)則,配合 tcpSocket 檢查方法。

① 編輯 pod 的 yaml 配置文件

[root@master01 demo]# vim demo5.yaml
apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
    livenessProbe:
      initialDelaySeconds: 5 # 容器啟動后等待 5 秒后開始執(zhí)行存活探針
      timeoutSeconds: 1      # 探測超時時間為 1 秒
      tcpSocket:             # 使用 TCP 探測方式
        port: 8080           # 探測的端口為 8080
      periodSeconds: 10      # 每隔 10 秒執(zhí)行一次存活探針
      failureThreshold: 2    # 如果連續(xù) 2 次探測失敗,則認為容器不健康

上面的 YAML 文件描述了一個名為 probe-tcp 的 Pod,其中包含一個名為 nginx 的容器,使用鏡像 soscscs/myapp:v1,配置了一個針對端口 8080 的 TCP 探測器,用于檢測容器的健康狀態(tài)。由于業(yè)務本身端口是 80,所有這步就是探針肯定是失敗的,持續(xù)查看探針過程。 

② 啟動 pod 

[root@master01 demo]# kubectl apply -f demo5.yaml 
pod/probe-tcp created
 
使用kubectl工具在名為probe-tcp的容器中執(zhí)行netstat -natp命令:
[root@master01 demo]# 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 pr

③ 持續(xù)查看容器狀態(tài)詳情信息

[root@master01 demo]# kubectl get pod -w
NAME        READY   STATUS    RESTARTS   AGE
probe-tcp   0/1     Pending   0          0s
probe-tcp   0/1     Pending   0          0s
probe-tcp   0/1     ContainerCreating   0          0s
probe-tcp   1/1     Running             0          2s
probe-tcp   1/1     Running             1          18s
probe-tcp   1/1     Running             2          38s
probe-tcp   1/1     Running             3          57s
probe-tcp   1/1     Running             4          78s
# 由于探測8080端口失敗,可以看到 Pod 重啟了多次
# 理論上第一次重啟時間為:5+1+10=16秒
# 理論上第二次重啟時間為:+20秒
# 理論上第三次重啟時間為:+20秒
# 理論上第四次重啟時間為:+20秒

2.4.4 定義 readinessProbe 就緒探針

有時候,應用會暫時性地無法為請求提供服務。 例如,應用在啟動時可能需要加載大量的數(shù)據(jù)或配置文件,或是啟動后要依賴等待外部服務。 在這種情況下,既不想殺死應用,也不想給它發(fā)送請求。 Kubernetes 提供了就緒探針來發(fā)現(xiàn)并緩解這些情況。 容器所在 Pod 上報還未就緒的信息,并且不接受通過 Kubernetes Service 的流量。

示例4: readinessProbe 和 livenessProbe 規(guī)則,配合 httpGet 檢查方法。

① 編輯 pod 的 yaml 配置文件 

[root@master01 demo]# vim demo6.yaml
apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: soscscs/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80      # 指定容器將監(jiān)聽的端口為 80
    readinessProbe:          # 定義容器的就緒性探針
      httpGet:               # 指定用于就緒性檢查的 HTTP GET 請求
        port: 80             # 指定進行就緒性檢查的端口(端口 80)
        path: /index1.html   # 指定就緒性檢查期間請求的路徑("/index1.html")
      initialDelaySeconds: 1 # 指定容器啟動后開始就緒性探針的等待時間(1 秒)
      periodSeconds: 3       # 指定連續(xù)就緒性探針之間的間隔(3 秒)
    livenessProbe:           # 定義容器的存活性探針
      httpGet:               # 指定用于存活性檢查的 HTTP GET 請求
        port: http           # 指定進行存活性檢查的端口("http"端口)
        path: /index.html    # 指定存活性檢查期間請求的路徑("/index.html")
      initialDelaySeconds: 1 # 指定容器啟動后開始存活性探針的等待時間(1 秒)
      periodSeconds: 3       # 指定連續(xù)存活性探針之間的間隔(3 秒)
      timeoutSeconds: 10     # 指定存活性探針在等待響應的最大時間(10 秒)

② 啟動 pod 

[root@master01 demo]# kubectl apply -f demo6.yaml 
pod/readiness-httpget created

③ 查看容器狀態(tài)詳情信息

[root@master01 demo]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   0/1     Running   0          17s
# 0/1表示該Pod中的容器當前處于未就緒狀態(tài)
 
[root@master01 demo]# kubectl describe pod readiness-httpget 
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  39s                default-scheduler  Successfully assigned default/readiness-httpget to node01
  Normal   Pulled     38s                kubelet            Container image "soscscs/myapp:v1" already present on machine
  Normal   Created    38s                kubelet            Created container readiness-httpget-container
  Normal   Started    38s                kubelet            Started container readiness-httpget-container
  Warning  Unhealthy  3s (x12 over 36s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404
# 就緒性探針失敗,因為 HTTP 探測返回了狀態(tài)碼 404,由于就緒性探針配置中指定的路徑/index1.html不存在或有誤。

④ 創(chuàng)建 index1.html 頁面

[root@master01 demo]# kubectl exec -it readiness-httpget sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo "index1" > /usr/share/nginx/html/index1.html
/ # exit

⑤ 再次查看 pod 狀態(tài)

[root@master01 demo]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   1/1     Running   0          5m36s
# 已就緒

⑥ 刪除原有 index.html,查看存活探針結果

[root@master01 demo]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   0/1     Running   1          9m32s
 
[root@master01 demo]# kubectl describe pod readiness-httpget
  Warning  Unhealthy  33s                     kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404
# 無法找到 index.html 頁面

2.4.5 多資源配置就緒檢測

下面這個 YAML 文件定義了三個名為 myapp1、myapp2 和 myapp3 的 Pod,它們使用相同的鏡像并具有相似的配置,以及一個名為 myapp 的 Service,用于將流量路由到這些 Pod 上的端口 80。

測試目的:readiness 探測失敗,pod 無法進入 ready 狀態(tài),則端點控制器會將 pod 從 endpoints 中剔除刪除該 pod 的 IP 地址。

示例5: readinessProbe 規(guī)則,配合 httpGet 檢查方法。

① 編輯 pod 的 yaml 配置文件

[root@master01 demo]# vim readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp1
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80       # 容器內部的端口號為 80
    readinessProbe:           # 定義了就緒性探針
      httpGet:                # 指定了使用 HTTP GET 請求進行探測
        port: 80              # 指定了探測的端口為 80
        path: /index.html     # 指定健康檢查發(fā)送請求的路徑為 /index.html
      initialDelaySeconds: 5  # 容器創(chuàng)建后等待 5 秒開始執(zhí)行健康檢查
      periodSeconds: 5        # 每隔 5 秒進行一次健康檢查
      timeoutSeconds: 10      # 健康檢查的超時時間為 10 秒
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp2
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp3
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  type: ClusterIP
  ports:
  - name: http
    port: 80
    targetPort: 80

② 啟動 pod 

[root@master01 demo]# kubectl apply -f readiness-httpget.yaml 
pod/myapp1 created
pod/myapp2 created
pod/myapp3 created
service/myapp created

③ 查看 pod、svc 以及關聯(lián)后端的節(jié)點信息

[root@master01 demo]# kubectl get pod,svc,endpoints -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
pod/myapp1   1/1     Running   0          28s   10.244.1.27   node01   <none>           <none>
pod/myapp2   1/1     Running   0          28s   10.244.2.10   node02   <none>           <none>
pod/myapp3   1/1     Running   0          27s   10.244.1.28   node01   <none>           <none>
 
NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE   SELECTOR
service/kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP           10d   <none>
service/myapp              ClusterIP   10.96.35.59     <none>        80/TCP            27s   app=myapp
service/nginx              NodePort    10.96.75.23     <none>        80:32165/TCP      10d   app=nginx
service/nginx-deployment   NodePort    10.96.101.251   <none>        30000:31603/TCP   9d    app=nginx-deployment
 
NAME                         ENDPOINTS                                      AGE
endpoints/kubernetes         192.168.190.100:6443                           10d
endpoints/myapp              10.244.1.27:80,10.244.1.28:80,10.244.2.10:80   27s
endpoints/nginx              <none>                                         10d
endpoints/nginx-deployment   10.244.1.10:80,10.244.1.11:80,10.244.2.6:80    9d

④ 刪除 index.html

[root@master01 demo]# kubectl exec -it myapp3 -- rm -rf /usr/share/nginx/html/index.html

⑤ 再次查看關聯(lián)后端的節(jié)點

[root@master01 demo]# kubectl get pod,svc,endpoints -o wide
NAME         READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
pod/myapp1   1/1     Running   0          2m42s   10.244.1.27   node01   <none>           <none>
pod/myapp2   1/1     Running   0          2m42s   10.244.2.10   node02   <none>           <none>
pod/myapp3   0/1     Running   0          2m41s   10.244.1.28   node01   <none>           <none>
 
NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE     SELECTOR
service/kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP           10d     <none>
service/myapp              ClusterIP   10.96.35.59     <none>        80/TCP            2m41s   app=myapp
service/nginx              NodePort    10.96.75.23     <none>        80:32165/TCP      10d     app=nginx
service/nginx-deployment   NodePort    10.96.101.251   <none>        30000:31603/TCP   9d      app=nginx-deployment
 
NAME                         ENDPOINTS                                     AGE
endpoints/kubernetes         192.168.190.100:6443                          10d
endpoints/myapp              10.244.1.27:80,10.244.2.10:80                 2m41s
endpoints/nginx              <none>                                        10d
endpoints/nginx-deployment   10.244.1.10:80,10.244.1.11:80,10.244.2.6:80   9d

此時可以看到對于 readiness 探測失敗,pod myapp3 無法進入  reday 狀態(tài),端點控制器將 pod myapp3 的 ip  從 endpoints 中剔除刪除。

2.4.6 啟動和退出動作

以下將演示在 Kubernetes 中如何定義容器的生命周期事件,包括容器啟動后和終止前的操作,以及如何使用初始化容器來執(zhí)行特定任務。

示例6:根據(jù)日志反饋的內容了解容器處于生命周期的哪個階段

① 編輯 pod 的 yaml 配置文件

[root@master01 demo]# vim post.yaml
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: soscscs/myapp:v1
    lifecycle:          # 此為關鍵字段,定義容器的生命周期
      postStart:        # 容器啟動后執(zhí)行的操作
        exec:           # 使用執(zhí)行命令的方式
          command: ["/bin/sh", "-c", "echo Hello Start >> /var/log/nginx/message"]  
# 執(zhí)行的命令是往日志中寫入啟動信息
      preStop:          # 容器終止前執(zhí)行的操作
        exec:           # 使用執(zhí)行命令的方式
          command: ["/bin/sh", "-c", "echo Hello Stop >> /var/log/nginx/message"]  
# 執(zhí)行的命令是往日志中寫入停止信息
    volumeMounts:       # 掛載卷到容器內部
    - name: message-log # 卷的名稱
      mountPath: /var/log/nginx/  # 掛載路徑
      readOnly: false   # 是否只讀
  initContainers:       # 初始化容器
  - name: init-myservice          # 初始化容器的名稱
    image: soscscs/myapp:v1       # 初始化容器使用的鏡像
    command: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]  # 初始化容器執(zhí)行的命令,往日志中寫入初始化信息
    volumeMounts:       # 掛載卷到容器內部
    - name: message-log # 卷的名稱
      mountPath: /var/log/nginx/  # 掛載路徑
      readOnly: false   # 是否只讀
  volumes:              # 定義卷
  - name: message-log   # 卷的名稱
    hostPath:           # 使用主機路徑
      path: /data/volumes/nginx/log/  # 主機上的路徑
      type: DirectoryOrCreate         # 類型為目錄或創(chuàng)建

② 啟動 pod

[root@master01 demo]# kubectl create -f post.yaml
pod/lifecycle-demo created

③ 查看 pod 詳情

[root@master01 demo]# kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
lifecycle-demo   1/1     Running   0          6s    10.244.1.29   node01   <none>           <none>

④ 查看容器日志

[root@master01 demo]# kubectl exec -it lifecycle-demo -- cat /var/log/nginx/message
Hello initContainers
Start

由此可見,首先啟動了 init 容器,然后啟動成功后返回信息“Start”,代表啟動成功。

⑤ 在 node01 節(jié)點查看日志

[root@node01 ~]# cd /data/volumes/nginx/log/
[root@node01 log]# ls
access.log  error.log  message
[root@node01 log]# cat message 
Hello initContainers
Start

⑥ 刪除 pod 后,再在 node01 節(jié)點上查看日志

[root@master01 demo]# kubectl delete pod lifecycle-demo
pod "lifecycle-demo" deleted
 
[root@node01 log]# cat message 
Hello initContainers
Start
Stop

由此課件,當在容器被終結之前, Kubernetes 將發(fā)送一個 preStop 事件,即探針關閉生命周期結束。

三、補充概念

3.1.pod 的狀態(tài)

  • pending:pod已經(jīng)被系統(tǒng)認可了,但是內部的container還沒有創(chuàng)建出來。這里包含調度到node上的時間以及下載鏡像的時間,會持續(xù)一小段時間。
  • Running:pod已經(jīng)與node綁定了(調度成功),而且pod中所有的container已經(jīng)創(chuàng)建出來,至少有一個容器在運行中,或者容器的進程正在啟動或者重啟狀態(tài)。--這里需要注意pod雖然已經(jīng)Running了,但是內部的container不一定完全可用。因此需要進一步檢測container的狀態(tài)。
  • Succeeded:這個狀態(tài)很少出現(xiàn),表明pod中的所有container已經(jīng)成功的terminated了,而且不會再被拉起了。
  • Failed:pod中的所有容器都被terminated,至少一個container是非正常終止的。(退出的時候返回了一個非0的值或者是被系統(tǒng)直接終止)
  • unknown:由于某些原因pod的狀態(tài)獲取不到,有可能是由于通信問題。 一般情況下pod最常見的就是前兩種狀態(tài)。而且當Running的時候,需要進一步關注container的狀態(tài)

3.2.Container生命周期

  • Waiting:啟動到運行中間的一個等待狀態(tài)。
  • Running:運行狀態(tài)。
  • Terminated:終止狀態(tài)。 如果沒有任何異常的情況下,container應該會從Waiting狀態(tài)變?yōu)镽unning狀態(tài),這時容器可用。

但如果長時間處于Waiting狀態(tài),container會有一個字段reason表明它所處的狀態(tài)和原因,如果這個原因很容易能標識這個容器再也無法啟動起來時,例如ContainerCannotRun,整個服務啟動就會迅速返回。(這里是一個失敗狀態(tài)返回的特性,不詳細闡述)

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • k8s?常見面試題集錦

    k8s?常見面試題集錦

    這篇文章主要為大家介紹了k8s?常見面試題集錦,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • k8s?clientConfig和rawConfig區(qū)別解析

    k8s?clientConfig和rawConfig區(qū)別解析

    k8s clientConfig和rawConfig區(qū)別k8s.io/client-gov0.28.2基于kubeconfig可以創(chuàng)建clientConfig和rawConfig,兩者區(qū)別在于,clientConfig包含了訪問kube-apiserver的地址和認證鑒權信息,感興趣的朋友一起看看吧
    2025-03-03
  • Kubernetes應用服務質量管理詳解

    Kubernetes應用服務質量管理詳解

    這篇文章主要為大家介紹了Kubernetes應用服務質量管理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Rancher通過界面管理K8s平臺的圖文步驟詳解

    Rancher通過界面管理K8s平臺的圖文步驟詳解

    這篇文章主要為大家介紹了Rancher通過界面管理K8s平臺通過詳細的圖文進行步驟講解,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03
  • tkestack/gpu-manager在k8s1.23版本之后的使用方法

    tkestack/gpu-manager在k8s1.23版本之后的使用方法

    這篇文章主要介紹了tkestack/gpu-manager在k8s1.23版本之后的使用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • k8s證書有效期時間修改的方法詳解

    k8s證書有效期時間修改的方法詳解

    K8S集群有證書的概念,之前一直是使用默認的,默認都是1年和10年的,1年有效期這顯然對于生產環(huán)境是不合適的,下面這篇文章主要給大家介紹了關于k8s證書有效期時間修改的相關資料,需要的朋友可以參考下
    2022-08-08
  • kubernetes部署dashboard及應用小結

    kubernetes部署dashboard及應用小結

    Dashboard?是基于網(wǎng)頁的?Kubernetes?用戶界面,可以對?Deployment?實現(xiàn)彈性伸縮、發(fā)起滾動升級、重啟?Pod?或者使用向導創(chuàng)建新的應用,這篇文章主要介紹了kubernetes部署dashboard,需要的朋友可以參考下
    2024-06-06
  • Rancher部署配置開源Rainbond云原生應用管理平臺

    Rancher部署配置開源Rainbond云原生應用管理平臺

    這篇文章主要為大家介紹了Rancher部署配置開源Rainbond云原生應用管理平臺,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04
  • k8s部署ingress-nginx的詳細步驟大全

    k8s部署ingress-nginx的詳細步驟大全

    nginx一般是作為服務的入口,其在kubernetes的部署方式也大致相似,這篇文章主要給大家介紹了關于k8s部署ingress-nginx的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2024-01-01
  • k8s自身原理service及實現(xiàn)圖文示例解析

    k8s自身原理service及實現(xiàn)圖文示例解析

    這篇文章主要為大家介紹了k8s自身原理service圖文示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08

最新評論