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

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

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

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

最常見的可設(shè)定資源是 CPU 和內(nèi)存大小,以及其他類型的資源;另一方面,通過配置探針,可以確保容器在運(yùn)行時(shí)保持健康,并且只有在準(zhǔn)備好接收流量時(shí)才會(huì)被負(fù)載均衡器引導(dǎo)流量。

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

一、容器管理資源概念

1.1.概述

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

官網(wǎng)示例:

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

1.2. Pod 和 容器 的資源請(qǐng)求和限制

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

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

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

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

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

1.3. K8s 中的資源單位

1.3.1 CPU 資源單位

CPU 資源的 request 和 limit 以 cpu 為單位。在 K8s 中,一個(gè) CPU 等于 1 個(gè)物理 CPU 核 或者 1 個(gè)虛擬核, 取決于節(jié)點(diǎn)是一臺(tái)物理主機(jī)還是運(yùn)行在某物理主機(jī)上的虛擬機(jī)。

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

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

1.3.2 內(nèi)存資源單位

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

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

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

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

如果給容器設(shè)置了內(nèi)存的 limit 值,但未設(shè)置內(nèi)存的 request 值,Kubernetes 會(huì)自動(dòng)為其設(shè)置與內(nèi)存 limit 相匹配的 request 值;類似的 cpu 同理。

1.5. 容器資源示例

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

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

[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  # 設(shè)置環(huán)境變量
      value: "123456"            # 環(huán)境變量的值
    resources:                   # 容器的資源限制和請(qǐng)求
      requests:                  # 容器的資源請(qǐng)求
        memory: "64Mi"           # 請(qǐng)求容器使用的內(nèi)存量為64MiB
        cpu: "250m"              # 請(qǐng)求容器使用的CPU量為250 m
      limits:                    # 容器的資源限制
        memory: "128Mi"          # 限制容器使用的最大內(nèi)存量為128MiB
        cpu: "500m"              # 限制容器使用的最大CPU量為500 m
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:                   # 容器的資源限制和請(qǐng)求
      requests:                  # 容器的資源請(qǐng)求
        memory: "64Mi"           # 容器使用的內(nèi)存量為64MiB
        cpu: "250m"              # 第二個(gè)容器使用的CPU量為250 m
      limits:                    # 容器的資源限制
        memory: "128Mi"          # 限制第二個(gè)容器使用的最大內(nèi)存量為128MiB
        cpu: "500m"              # 限制第二個(gè)容器使用的最大CPU量為500 m

1.5.2. OOMKilled 內(nèi)存耗盡保護(hù)機(jī)制

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

請(qǐng)注意,在生產(chǎn)環(huán)境中,調(diào)整容器的資源請(qǐng)求和限制應(yīng)該謹(jǐn)慎進(jìn)行,以避免對(duì)系統(tǒng)產(chǎn)生不可預(yù)料的影響。

① 創(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"

 ② 啟動(dòng) 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 表示容器由于內(nèi)存耗盡而被系統(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" 失敗并且在多次嘗試后仍然無法成功啟動(dòng),導(dǎo)致觸發(fā)了 BackOff 機(jī)制

④ 調(diào)整資源配額限制

[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"

⑤ 再次嘗試啟動(dòng) 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é)點(diǎn)資源占比

[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" 的資源請(qǐng)求和限制如下:

  • CPU 請(qǐng)求:750m,CPU 限制:1500m
  • 內(nèi)存請(qǐng)求:192Mi,內(nèi)存限制:1152Mi

已分配的資源情況如下:

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

二、Pod 容器的探針

2.1. 概述

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

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

2.2.1 存活探針(Liveness Probe)

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

2.2.2 就緒探針(Readiness Probe)

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

2.2.3 啟動(dòng)探針(Startup Probe)

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

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

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

2.3. 探針三種檢查方法

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

每次探測(cè)都將獲得以下三種結(jié)果之一:

  • 成功:容器通過了診斷;
  • 失敗:容器未通過診斷;
  • 未知:診斷失敗,因此不會(huì)采取任何行動(dòng)。

2.4.探針配置示例

2.4.1 定義存活命令

許多長(zhǎng)時(shí)間運(yùn)行的應(yīng)用最終會(huì)進(jìn)入損壞狀態(tài),除非重新啟動(dòng),否則無法被恢復(fù)。 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 的標(biāo)簽
    test: liveness
  name: liveness-exec
spec:                         # Pod 的規(guī)格
  containers:                 # 容器列表
  - name: liveness            # 容器的名稱
    image: busybox            # 一個(gè)輕量級(jí)的 BusyBox 鏡像
    imagePullPolicy: IfNotPresent # 鏡像拉取策略,先本地后倉庫
    args:                     # 容器的啟動(dòng)參數(shù)部分
    - /bin/sh
    - -c                      # 后面的內(nèi)容將作為 shell 的命令執(zhí)行
    - touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 10
# 在容器啟動(dòng)時(shí)執(zhí)行的命令,首先創(chuàng)建一個(gè)/tmp/healthy文件,然后等待10秒,接著刪除該文件,最后再等待10秒
    livenessProbe:            # 定義存活探針的配置
      exec:                   # 使用 exec 方式執(zhí)行命令
        command:              # 要執(zhí)行的命令
        - cat
        - /tmp/healthy        # 讀取 /tmp/healthy 文件的內(nèi)容
      failureThreshold: 1     # 存活探針的失敗閾值為1,即連續(xù)失敗1次后認(rèn)為探針失敗,默認(rèn)值是3。最小值是1
      initialDelaySeconds: 3  # 容器啟動(dòng)后等待3秒開始進(jìn)行存活探測(cè),其實(shí)是4秒,默認(rèn)是0秒,最小值是0
      periodSeconds: 2        # 每隔2秒進(jìn)行一次存活探測(cè),默認(rèn)是10秒。最小值是1。

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

② 啟動(dòng) 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由于存活探針失敗而不斷重啟,并最終進(jìn)入了CrashLoopBackOff狀態(tài)
# 輸出結(jié)果顯示RESTARTS的值增加了1。 請(qǐng)注意,一旦失敗的容器恢復(fù)為運(yùn)行狀態(tài),RESTARTS計(jì)數(shù)器就會(huì)加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
# 顯示存活探針失敗了,這個(gè)失敗的容器被殺死并且被重建了
# 是否重啟還是根據(jù)重啟策略來決定,這里明顯是always

2.4.2 定義一個(gè)存活態(tài) HTTP 請(qǐng)求接口

另外一種類型的存活探測(cè)方式是使用 HTTP GET 請(qǐng)求。

示例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              # 容器內(nèi)部的端口號(hào)為 80
    livenessProbe:                   # 定義存活探針的配置
      httpGet:                       # 使用HTTP GET請(qǐng)求方式進(jìn)行探測(cè)
        port: http                   # 探測(cè)請(qǐng)求發(fā)送到的端口為http,即容器內(nèi)部的80端口
        path: /index.html            # 探測(cè)請(qǐng)求的路徑為 /index.html
      initialDelaySeconds: 1         # 容器啟動(dòng)后等待1秒后開始進(jìn)行存活探測(cè)
      periodSeconds: 3               # 每隔3秒進(jìn)行一次存活探測(cè)
      timeoutSeconds: 5              # 超時(shí)時(shí)間為5秒

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

② 啟動(dòng) 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

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

2.4.3 定義 TCP 的存活探測(cè)

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

示例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 # 容器啟動(dòng)后等待 5 秒后開始執(zhí)行存活探針
      timeoutSeconds: 1      # 探測(cè)超時(shí)時(shí)間為 1 秒
      tcpSocket:             # 使用 TCP 探測(cè)方式
        port: 8080           # 探測(cè)的端口為 8080
      periodSeconds: 10      # 每隔 10 秒執(zhí)行一次存活探針
      failureThreshold: 2    # 如果連續(xù) 2 次探測(cè)失敗,則認(rèn)為容器不健康

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

② 啟動(dòng) 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
# 由于探測(cè)8080端口失敗,可以看到 Pod 重啟了多次
# 理論上第一次重啟時(shí)間為:5+1+10=16秒
# 理論上第二次重啟時(shí)間為:+20秒
# 理論上第三次重啟時(shí)間為:+20秒
# 理論上第四次重啟時(shí)間為:+20秒

2.4.4 定義 readinessProbe 就緒探針

有時(shí)候,應(yīng)用會(huì)暫時(shí)性地?zé)o法為請(qǐng)求提供服務(wù)。 例如,應(yīng)用在啟動(dòng)時(shí)可能需要加載大量的數(shù)據(jù)或配置文件,或是啟動(dòng)后要依賴等待外部服務(wù)。 在這種情況下,既不想殺死應(yīng)用,也不想給它發(fā)送請(qǐng)求。 Kubernetes 提供了就緒探針來發(fā)現(xiàn)并緩解這些情況。 容器所在 Pod 上報(bào)還未就緒的信息,并且不接受通過 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 請(qǐng)求
        port: 80             # 指定進(jìn)行就緒性檢查的端口(端口 80)
        path: /index1.html   # 指定就緒性檢查期間請(qǐng)求的路徑("/index1.html")
      initialDelaySeconds: 1 # 指定容器啟動(dòng)后開始就緒性探針的等待時(shí)間(1 秒)
      periodSeconds: 3       # 指定連續(xù)就緒性探針之間的間隔(3 秒)
    livenessProbe:           # 定義容器的存活性探針
      httpGet:               # 指定用于存活性檢查的 HTTP GET 請(qǐng)求
        port: http           # 指定進(jìn)行存活性檢查的端口("http"端口)
        path: /index.html    # 指定存活性檢查期間請(qǐng)求的路徑("/index.html")
      initialDelaySeconds: 1 # 指定容器啟動(dòng)后開始存活性探針的等待時(shí)間(1 秒)
      periodSeconds: 3       # 指定連續(xù)存活性探針之間的間隔(3 秒)
      timeoutSeconds: 10     # 指定存活性探針在等待響應(yīng)的最大時(shí)間(10 秒)

② 啟動(dòng) 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表示該P(yáng)od中的容器當(dāng)前處于未就緒狀態(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
# 就緒性探針失敗,因?yàn)?HTTP 探測(cè)返回了狀態(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,查看存活探針結(jié)果

[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 多資源配置就緒檢測(cè)

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

測(cè)試目的:readiness 探測(cè)失敗,pod 無法進(jìn)入 ready 狀態(tài),則端點(diǎn)控制器會(huì)將 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       # 容器內(nèi)部的端口號(hào)為 80
    readinessProbe:           # 定義了就緒性探針
      httpGet:                # 指定了使用 HTTP GET 請(qǐng)求進(jìn)行探測(cè)
        port: 80              # 指定了探測(cè)的端口為 80
        path: /index.html     # 指定健康檢查發(fā)送請(qǐng)求的路徑為 /index.html
      initialDelaySeconds: 5  # 容器創(chuàng)建后等待 5 秒開始執(zhí)行健康檢查
      periodSeconds: 5        # 每隔 5 秒進(jìn)行一次健康檢查
      timeoutSeconds: 10      # 健康檢查的超時(shí)時(shí)間為 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

② 啟動(dòng) pod 

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

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

[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

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

[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

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

2.4.6 啟動(dòng)和退出動(dòng)作

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

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

① 編輯 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:          # 此為關(guān)鍵字段,定義容器的生命周期
      postStart:        # 容器啟動(dòng)后執(zhí)行的操作
        exec:           # 使用執(zhí)行命令的方式
          command: ["/bin/sh", "-c", "echo Hello Start >> /var/log/nginx/message"]  
# 執(zhí)行的命令是往日志中寫入啟動(dòng)信息
      preStop:          # 容器終止前執(zhí)行的操作
        exec:           # 使用執(zhí)行命令的方式
          command: ["/bin/sh", "-c", "echo Hello Stop >> /var/log/nginx/message"]  
# 執(zhí)行的命令是往日志中寫入停止信息
    volumeMounts:       # 掛載卷到容器內(nèi)部
    - 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:       # 掛載卷到容器內(nèi)部
    - name: message-log # 卷的名稱
      mountPath: /var/log/nginx/  # 掛載路徑
      readOnly: false   # 是否只讀
  volumes:              # 定義卷
  - name: message-log   # 卷的名稱
    hostPath:           # 使用主機(jī)路徑
      path: /data/volumes/nginx/log/  # 主機(jī)上的路徑
      type: DirectoryOrCreate         # 類型為目錄或創(chuàng)建

② 啟動(dò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

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

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

[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é)點(diǎn)上查看日志

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

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

三、補(bǔ)充概念

3.1.pod 的狀態(tài)

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

3.2.Container生命周期

  • Waiting:?jiǎn)?dòng)到運(yùn)行中間的一個(gè)等待狀態(tài)。
  • Running:運(yùn)行狀態(tài)。
  • Terminated:終止?fàn)顟B(tài)。 如果沒有任何異常的情況下,container應(yīng)該會(huì)從Waiting狀態(tài)變?yōu)镽unning狀態(tài),這時(shí)容器可用。

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

總結(jié)

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

相關(guān)文章

  • k8s?常見面試題集錦

    k8s?常見面試題集錦

    這篇文章主要為大家介紹了k8s?常見面試題集錦,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    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的地址和認(rèn)證鑒權(quán)信息,感興趣的朋友一起看看吧
    2025-03-03
  • Kubernetes應(yīng)用服務(wù)質(zhì)量管理詳解

    Kubernetes應(yīng)用服務(wù)質(zhì)量管理詳解

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

    Rancher通過界面管理K8s平臺(tái)的圖文步驟詳解

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

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

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

    k8s證書有效期時(shí)間修改的方法詳解

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

    kubernetes部署dashboard及應(yīng)用小結(jié)

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

    Rancher部署配置開源Rainbond云原生應(yīng)用管理平臺(tái)

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

    k8s部署ingress-nginx的詳細(xì)步驟大全

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

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

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

最新評(píng)論