容器編排系統之Pod生命週期、健康/就緒狀態探測以及資源限制

1874發表於2020-12-16

  前文我們瞭解了在k8s上的資源標籤、標籤選擇器以及資源註解相關話題,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/14141080.html;今天我們來聊下k8s上的核心資源pod生命週期、健康/就緒狀態探測以及pod資源限制相關話題;

  1、Pod生命週期

  pod生命週期是指在pod開始建立到pod退出所消耗的時間範圍,我們把開始到結束的這段時間範圍就叫做pod的生命週期;其大概過程如下圖所示

  提示:上圖主要描述了一個pod從建立到退出,中間這段時間經歷的過程;從大的方向上看,pod生命週期分兩個階段,第一階段是初始化容器,第二階段是主容器的整個生命週期;其中對於主容器來來說,它的生命週期有分了三個階段,第一階段是執行post start hook,這個階段是主容器執行之後立即需要做的事;第二階段是主容器正常執行的階段,在這個階段中,我們可以定義對容器的健康狀態檢查和就緒狀態檢查;第三階段是執行pre stop hook,這個階段主要做容器即將退出前需要做的事;這裡需要注意對於初始化容器來說,一個pod中可以定義多個初始化容器,他們必須是序列執行,只有當所有的初始化容器執行完後,對應的主容器才會啟動;對於對容器的健康狀態檢查和就緒狀態檢查,我們也可以定義開始檢查的延遲時長;因為有些容器存在容器顯示running狀態,但內部程式還沒有初始化,如果立即做健康狀態檢查,可能存在健康狀態為不健康,從而導致容器重啟的狀況;

  2、Pod建立過程

  提示:首先使用者通過客戶端工具將請求提交給apiserver,apiserver收到使用者的請求以後,它會嘗試將使用者提交的請求內容存進etcd中,etcd存入完成後就反饋給apiserver寫入資料完成,此時apiserver就返回客戶端,說某某資源已經建立;隨後apiserver要傳送一個watch訊號給scheduler,說要建立一個新pod,請你看看在那個節點上建立合適,scheduler收到訊號以後,就開始做排程,並把排程後端結果反饋給apiserver,apiserver收到排程器的排程資訊以後,它就把對應排程資訊儲存到etcd中,隨後apiServer要傳送一個watch訊號給對應被排程的主機上的kubelet,對應主機上的kubelet收到訊息後,立刻呼叫docker,並把對應容器跑起來;當容器執行起來以後,docker會向kubelet返回容器的狀體;隨後kubelet把容器的狀態反饋給apiserver,由apiserver把容器的狀態資訊儲存到etcd中;最後當etcd中的容器狀態資訊更新完成後,隨後apiserver把容器狀態資訊更新完成的訊息傳送給對應主機的kubelet;

  3、在資源配置清單中定義初始化容器

[root@master01 ~]# cat pod-demo6.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-demo6
  namespace: default
  labels:
    app: nginx
    env: testing
  annotations:
    descriptions: "this is test pod "
spec:
  containers:
  - image: nginx:1.14-alpine
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
      - containerPort: 80
        hostPort: 8080
        name: web
        protocol: TCP
  initContainers:
  - name: init-something
    image: busybox
    command:
    - /bin/sh
    - -c 
    - "sleep 60"
[root@master01 ~]# 

  提示:在資源配置清單中定義初始化容器需要在spec欄位下,使用initContainers欄位來定義,這個欄位的值是一個列表物件;初始化容器的定義和主容器的定義方式很類似;上面初始化容器中主要乾了一件事,就是sleep 60,意思是在啟動主容器前,首先要讓初始化容器中的操作執行完以後,對應的主容器才會開始執行;如果定義的初始化容器有多個,則要等待所有初始化容器中的操作執行完以後,對應主容器才會開始啟動;

  4、Pod生命週期的兩個函式鉤子的使用

  postStart:這個函式鉤子主要用來定義在主容器啟動之後,立即需要做的事,比如執行一個命令,建立一個檔案等等;這裡需要注意的是,postStart這個函式鉤子說定義的操作,都是針對主容器的,所以執行命令或其他操作的前提都是主容器上能夠正常執行的操作;

  示例:定義執行一個nginx容器,在容器啟動之後立即在對應html目錄下建立一個檔案,作為使用者自定義測試頁面

[root@master01 ~]# cat pod-demo7.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-demo7
  namespace: default
  labels:
    app: nginx
    env: testing
  annotations:
    descriptions: "this is test pod "
spec:
  containers:
  - image: nginx:1.14-alpine
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
      - containerPort: 80
        hostPort: 8080
        name: web
        protocol: TCP
    lifecycle:
      postStart: 
        exec:
          command: 
          - /bin/sh
          - -c
          - "echo 'this is test page' > /usr/share/nginx/html/test.html"
[root@master01 ~]# 

  提示:在資源配置清單中定義主容器啟動之後需要做的事,需要在對應主容器下用lifecycle欄位來定義;其中postStart欄位使用用來指定主容器啟動之後要做到事,這個欄位的值是一個物件;其中exec是用來定義使用exec來執行命令,command欄位用來指定要執行的命令;除了可以用exec來定義執行命令,還可以使用httpGet來向當前容器中的url發起http請求,或者使用tcpSocket來向某個主機的某個埠套接字發起請求,預設不指定host表示向當前podip發起請求;

  執行配置清單

[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   2          7d19h
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   3          7d19h
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   2          7d19h
ngx-dep-5c8d96d457-w6nss     1/1     Running   2          7d20h
[root@master01 ~]# kubectl apply -f pod-demo7.yaml
pod/nginx-pod-demo7 created
[root@master01 ~]# kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP            NODE             NOMINATED NODE   READINESS GATES
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   2          7d19h   10.244.1.12   node01.k8s.org   <none>           <none>
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   3          7d19h   10.244.3.13   node03.k8s.org   <none>           <none>
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   2          7d19h   10.244.2.8    node02.k8s.org   <none>           <none>
nginx-pod-demo7              1/1     Running   0          6s      10.244.1.13   node01.k8s.org   <none>           <none>
ngx-dep-5c8d96d457-w6nss     1/1     Running   2          7d20h   10.244.2.9    node02.k8s.org   <none>           <none>
[root@master01 ~]# 

  驗證:訪問對應pod看看test.html是否能夠訪問到?

[root@master01 ~]# curl 10.244.1.13/test.html
this is test page
[root@master01 ~]# 

  提示:可以看到訪問對應的pod的ip地址,能夠訪問到我們剛才定義容器啟動之後建立的檔案內容;

  preStop:這個函式鉤子主要用來定義在容器結束之前需要做的事情,使用方式和postStart一樣,都是在對應主容器裡的lifesycle欄位下定義;它也可以使用exec來執行命令或者httpGet來向容器的某個url發起請求,或者使用tcpSocket向某個套接字發起請求;

  示例:在容器結束前執行echo 命令

[root@master01 ~]# cat pod-demo8.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-demo8
  namespace: default
  labels:
    app: nginx
    env: testing
  annotations:
    descriptions: "this is test pod "
spec:
  containers:
  - image: nginx:1.14-alpine
    imagePullPolicy: IfNotPresent
    name: nginx
    lifecycle:
      postStart: 
        exec:
          command: 
          - /bin/sh
          - -c
          - "echo 'this is test page' > /usr/share/nginx/html/test.html"
      preStop:
        exec:
          command: ["/bin/sh","-c","echo goodbye.."]
[root@master01 ~]# 

  5、pod終止過程

  提示:使用者通過客戶端工具想APIserver傳送刪除pod的指令,在APIserver收到使用者發來的刪除指令後,首先APIserver會把對應的操作寫到etcd中,並設定其寬限期,然後etcd把對應資料寫好以後,響應APIserver,隨後APIserver響應客戶端說對應容器已經標記為terminating狀態;隨後APIserver會傳送一個把對應pod標記為terminating狀態的訊息給endpoint端點控制,讓其刪除與當前要刪除pod相關的所有service,(其實在k8s上我們建立service關聯pod不是直接關聯pod,是現關聯endpoint端點控制器,然後端點控制器再關聯pod),隨後APIserver會向對應要刪除pod所在主機上的kubelet傳送將pod標記為terminating狀態的訊息,當對應主機收到APIserver傳送的標記pod為terminating狀態訊息後,對應主機上的kubelet會向對應pod裡執行的容器傳送TERM訊號,隨後再執行preStop中定義的操作;隨後等待寬限期超時,如果對應的pod還沒有被刪除,此時APIserver就會向對應pod所在主機上的kubelet傳送寬限期超時的訊息,此時對應kubelet會向對應容器傳送SIGKILL訊號來強制刪除對應的容器,隨後docker把對應容器刪除後,把刪除完容器的訊息響應給APIserver,此時APIserver會向etcd傳送刪除對應pod在etcd中的所有資訊;

  6、pod健康狀態探測

  所謂pod健康狀態探測是指檢查對應pod是否健康,如果不健康就把對應的pod重啟;健康狀態探測是一個週期性的工作;只要發現對應pod不健康,就重啟對應pod;在k8s上對pod的健康狀態探測的方式有三種,第一種上執行命令,只有對應命令執退出碼為0就表示對應pod是處於健康狀態,否則就不健康;第二種是用httpGet來探測對應pod裡的容器的某個url是否可以訪問,只有請求對應的url狀態碼為200才表示對應pod是健康的,否則就不健康;第三種是使用tcpSocket的方式來對某個套接字傳送請求,只有套接字正常響應就表示對應pod是處於健康的,否則就是不健康;至於我們要使用那種方式來判斷pod的健康與否,這取決與pod裡的服務和業務邏輯;

  示例:使用exec執行命令的方式來探測pod的健康狀態

[root@master01 ~]# cat pod-demo9.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec
  namespace: default
  labels:
    app: nginx
    env: testing
  annotations:
    descriptions: "this is test pod "
spec:
  containers:
  - image: nginx:1.14-alpine
    imagePullPolicy: IfNotPresent
    name: nginx
    lifecycle:
      postStart: 
        exec:
          command: 
          - /bin/sh
          - -c
          - "echo 'this is test page' > /usr/share/nginx/html/test.html"
      preStop:
        exec:
          command: ["/bin/sh","-c","echo goodbay.."]
    livenessProbe:
      exec:
        command: ["/usr/bin/test","-e","/usr/share/nginx/html/test.html"]
[root@master01 ~]# 

  提示:使用配置清單定義pod的健康狀態監測需要用到livenessProbe這個欄位,這個欄位的值是一個物件;以上配置表示判斷/usr/share/nginx/html/test.html這個檔案是否存在,存在就表示對應pod健康,否則就不健康;

  應用配置清單

[root@master01 ~]# kubectl apply -f pod-demo9.yaml
pod/liveness-exec created
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   0          4s
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          4h45m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
[root@master01 ~]# 

  提示:可以看到對應pod現在已經正常執行著,並且重啟次數為0;

  測試:進入對應pod把test.html檔案刪除,看看對應pod還會正常處於健康狀態嗎?重啟次數還是0嗎?

[root@master01 ~]# kubectl exec liveness-exec -- rm -f /usr/share/nginx/html/test.html

  檢視對應pod狀態

[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   1          2m45s
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          4h48m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
[root@master01 ~]# 

  提示:可以看到對應pod重啟數已經變為1了,說明pod發生了重啟;

  檢視pod的詳細資訊

  提示:從上面的截圖可以看到,pod健康狀態檢查不通過,就把容器給重啟了;重啟以後對應的檔案又回重新建立,所以再次健康狀態監測就通過了,所以pod處於健康狀態;

  示例:使用httpGet探測對應pod是否健康

[root@master01 ~]# cat liveness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget
  namespace: default
  labels:
    app: nginx
    env: testing
  annotations:
    descriptions: "this is test pod "
spec:
  containers:
  - image: nginx:1.14-alpine
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
    - name: http
      containerPort: 80
    lifecycle:
      postStart: 
        exec:
          command: 
          - /bin/sh
          - -c
          - "echo 'this is test page' > /usr/share/nginx/html/test.html"
      preStop:
        exec:
          command: ["/bin/sh","-c","echo goodbay.."]
    livenessProbe:
      httpGet:
        path: /test.html
        port: http
        scheme: HTTP
      failureThreshold: 2
      initialDelaySeconds: 2
      periodSeconds: 3
[root@master01 ~]# 

  提示:failureThreshold欄位用於指定失敗閾值,即多少次失敗就把對應pod標記為不健康;預設是3次;initialDelaySeconds欄位用於指定初始化後延遲多少時間再做健康狀態監測;periodSeconds欄位用於指定監測頻率,預設是10秒一次;最小為1秒一次;以上配置清單表示對pod容器裡的/test.html這個url發起請求,如果響應碼為200就表示pod健康,否則就不健康;httpGet中必須指定埠,埠資訊可以應用上面容器中定義的埠名稱;

  應用配置清單

[root@master01 ~]# kubectl apply -f liveness-httpget.yaml
pod/liveness-httpget created
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   2          29m
liveness-httpget             1/1     Running   0          5s
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          5h15m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
[root@master01 ~]# 

  驗證:進入對應pod,把test.html檔案刪除,看看對應pod是否會重啟?

[root@master01 ~]# kubectl exec liveness-httpget -- rm -rf /usr/share/nginx/html/test.html
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   2          30m
liveness-httpget             1/1     Running   1          97s
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          5h16m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
[root@master01 ~]# 

  提示:可以看到對應pod已經發生了重啟;

  檢視pod詳細資訊

  提示:可以看到對應pod健康狀態探測失敗,並重啟的事件;

  示例:使用tcpsocket方式來探測pod健康狀態

[root@master01 ~]# cat liveness-tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-tcpsocket
  namespace: default
  labels:
    app: nginx
    env: testing
  annotations:
    descriptions: "this is test pod "
spec:
  containers:
  - image: nginx:1.14-alpine
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      tcpSocket:
        port: http
      failureThreshold: 2
      initialDelaySeconds: 2
      periodSeconds: 3
[root@master01 ~]# 

  提示:使用tcpSocket方式來探測健康與否,預設不指定host欄位表示探測對應podip;

  應用資源配置清單

[root@master01 ~]# kubectl apply -f liveness-tcpsocket.yaml 
pod/liveness-tcpsocket created
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   2          42m
liveness-httpget             1/1     Running   1          12m
liveness-tcpsocket           1/1     Running   0          5s
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          5h27m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
[root@master01 ~]# 

  測試:進入pod裡的容器,修改nginx的埠為81,看看對應pod是否會重啟?

[root@master01 ~]# kubectl exec liveness-tcpsocket -it -- /bin/sh
/ # netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      
/ # grep "listen" /etc/nginx/conf.d/default.conf 
    listen       80;
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
/ # sed -i 's@    listen.*@    listen 81;@g' /etc/nginx/conf.d/default.conf 
/ # grep "listen" /etc/nginx/conf.d/default.conf 
    listen 81;
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
/ # nginx -s reload
2020/12/16 11:49:51 [notice] 35#35: signal process started
/ # command terminated with exit code 137
[root@master01 ~]# 

  提示:可以看到我們修改了配置檔案讓nginx監聽81埠,沒過幾秒就退出了;

  檢視對應pod是否發生了重啟?

  提示:可以看到對應pod裡的事件資訊說健康狀態監測10.244.3.22:80連線失敗,容器重啟了;

  7、pod就緒狀態探測

  所謂pod就緒狀態探測是指探測對應pod是否就緒,主要用在service關聯後端pod的一個重要依據,如果對應pod未就緒,對應service就不應該關聯pod,否則可能發生使用者訪問對應service,響應服務不可用;pod就緒狀態檢查和健康狀態檢查兩者最主要的區別是,健康狀態檢查,一旦對應pod不健康了,就會執行重啟對應pod的操作,而就緒狀態檢查是沒有許可權去重啟pod,如果對應pod沒有就緒,它不會做任何操作;同樣的對就緒狀態檢查在k8s上也有三種方式和健康狀態檢查的方式一摸一樣;

  示例:使用exec方式探測pod就緒狀態

[root@master01 ~]# cat readiness-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: readiness-demo
  namespace: default
  labels:
    app: nginx
    env: testing
  annotations:
    descriptions: "this is test pod "
spec:
  containers:
  - image: nginx:1.14-alpine
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
    - name: http
      containerPort: 80
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh","-c","echo 'this is test page' > /usr/share/nginx/html/test.html"]
    readinessProbe:
      exec:
        command: ["/usr/bin/test","-e","/usr/share/nginx/html/test.html"]
      failureThreshold: 2
      initialDelaySeconds: 2
      periodSeconds: 3
[root@master01 ~]# 

  提示:以上清單表示如果/usr/share/nginx/html/test.html檔案存在,則表示對應pod就緒,否則就表示為就緒;

  應用配置清單

[root@master01 ~]# kubectl apply -f readiness-demo.yaml
pod/readiness-demo created
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   2          65m
liveness-httpget             1/1     Running   1          35m
liveness-tcpsocket           1/1     Running   1          23m
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          5h50m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
readiness-demo               0/1     Running   0          5s
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   2          65m
liveness-httpget             1/1     Running   1          36m
liveness-tcpsocket           1/1     Running   1          23m
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          5h51m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
readiness-demo               1/1     Running   0          25s
[root@master01 ~]# 

  提示:可以看到應用配置清單以後,對應的pod從未就緒到就緒狀態了;

  測試:刪除pod容器中的test.html檔案,看看對應pod是否會從就緒狀態到未就緒狀態?

[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   2          67m
liveness-httpget             1/1     Running   1          37m
liveness-tcpsocket           1/1     Running   1          25m
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          5h52m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
readiness-demo               1/1     Running   0          2m3s
[root@master01 ~]# kubectl exec readiness-demo -- rm -rf /usr/share/nginx/html/test.html
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   2          67m
liveness-httpget             1/1     Running   1          38m
liveness-tcpsocket           1/1     Running   1          25m
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          5h53m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
readiness-demo               0/1     Running   0          2m36s
[root@master01 ~]# 

  提示:可以看到對應pod已經處於未就緒狀態了;

  檢視對應pod的詳細資訊

  提示:在對應pod的詳細資訊中也能看到對應的事件,不同於健康狀態探測,就緒狀態探測,它這裡不會重啟pod;

  測試:建立test.html檔案,看看對應pod是否會從未就緒狀態到就緒狀態?

[root@master01 ~]# kubectl exec readiness-demo -- touch /usr/share/nginx/html/test.htm
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
liveness-exec                1/1     Running   2          72m
liveness-httpget             1/1     Running   1          42m
liveness-tcpsocket           1/1     Running   1          30m
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d
nginx-pod-demo7              1/1     Running   1          5h57m
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d
readiness-demo               1/1     Running   0          7m11s
[root@master01 ~]# 

  提示:可以看到對應pod已經處於就緒狀態;

  8、pod資源限制

  所謂pod資源限制就是指限制對應pod裡容器的cpu和記憶體使用量;我們知道如果一個容器不限制其資源的使用大小,很有可能發生一個容器將宿主機上的記憶體耗盡的情況,如果一旦發生記憶體耗盡,核心很有可能向容器程式發起oom(out of memory),這樣一來執行在docker上的其他容器也會相繼退出;所以為了不讓類似的情況發生,我們有必要給pod裡的容器做資源限定;

  資源計量方式

  對於cpu來講,它是可壓縮資源,所謂可以壓縮資源就是表示cpu不夠用時,它並不會報錯,pod可以等待;對於記憶體來講,它是不可壓縮資源,不可壓縮就是指如果記憶體不夠用對應程式就會崩潰,從而導致容器退出;cpu的計量方式是m,即1核心=1000m,0.5個核心就等於500m;記憶體的計量方式預設單位是位元組,我們在指定記憶體資源,直接加上單位即可;可以使用E、P、T、G、M、K為字尾單位,也可以使用Ei、Pi、Ti、Gi、Mi、Ki作為單位;

  示例:在資源清單中限制pod資源

[root@master01 ~]# cat resource.yaml
apiVersion: v1
kind: Pod
metadata:
  name: stress-pod
spec:
  containers:
  - name: stress
    image: ikubernetes/stress-ng
    command: ["/usr/bin/stress-ng", "-c 1", "-m 1", "--metrics-brief"]
    resources:
      requests:
        memory: "128Mi"
        cpu: "200m"
      limits:
        memory: "512Mi"
        cpu: "400m"
[root@master01 ~]# 

  提示:定義pod的資源限制,需要用到resources這個欄位,這個欄位的值為一個物件;其中requests欄位用於指定下限,limits指定資源的上限;

  應用資源清單

[root@master01 ~]# kubectl apply -f resource.yaml 
pod/stress-pod created
[root@master01 ~]# kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP            NODE             NOMINATED NODE   READINESS GATES
liveness-exec                1/1     Running   2          147m    10.244.3.21   node03.k8s.org   <none>           <none>
liveness-httpget             1/1     Running   1          118m    10.244.2.14   node02.k8s.org   <none>           <none>
liveness-tcpsocket           1/1     Running   1          105m    10.244.3.22   node03.k8s.org   <none>           <none>
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   3          8d      10.244.1.16   node01.k8s.org   <none>           <none>
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   4          8d      10.244.3.17   node03.k8s.org   <none>           <none>
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   3          8d      10.244.2.11   node02.k8s.org   <none>           <none>
nginx-pod-demo7              1/1     Running   1          7h12m   10.244.1.14   node01.k8s.org   <none>           <none>
ngx-dep-5c8d96d457-w6nss     1/1     Running   3          8d      10.244.2.12   node02.k8s.org   <none>           <none>
readiness-demo               1/1     Running   0          82m     10.244.3.23   node03.k8s.org   <none>           <none>
stress-pod                   1/1     Running   0          13s     10.244.2.16   node02.k8s.org   <none>           <none>
[root@master01 ~]# 

  提示:可以看到stress-pod被排程到node02上執行了;

  測試:在node02上使用doucker stats命令檢視對應stress-pod容器佔用資源情況

  提示:可以看到在node02上跑的k8s_stress_stress-pod_default容器佔有cpu和記憶體都是我們在資源清單中定義的量;

  示例:當pod裡的容器資源不夠用時,對應pod是否會發生oom呢?

[root@master01 ~]# cat memleak-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: memleak-pod
spec:
  containers:
  - name: simmemleak
    image: saadali/simmemleak
    resources:
      requests:
        memory: "64Mi"
        cpu: "1"
      limits:
        memory: "1Gi"
        cpu: "1"
[root@master01 ~]# 

  提示:以上配置清單主要限制了容器最大記憶體為1G,最小記憶體為64M,cpu上下限都為1核心;

  應用配置清單

[root@master01 ~]# kubectl apply -f memleak-pod.yaml
pod/memleak-pod created
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS              RESTARTS   AGE
liveness-exec                1/1     Running             2          155m
liveness-httpget             1/1     Running             1          126m
liveness-tcpsocket           1/1     Running             1          113m
memleak-pod                  0/1     ContainerCreating   0          2s
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running             3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running             4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running             3          8d
nginx-pod-demo7              1/1     Running             1          7h21m
ngx-dep-5c8d96d457-w6nss     1/1     Running             3          8d
readiness-demo               1/1     Running             0          90m
stress-pod                   1/1     Running             0          8m46s
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS      RESTARTS   AGE
liveness-exec                1/1     Running     2          156m
liveness-httpget             1/1     Running     1          126m
liveness-tcpsocket           1/1     Running     1          114m
memleak-pod                  0/1     OOMKilled   0          21s
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running     3          8d
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running     4          8d
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running     3          8d
nginx-pod-demo7              1/1     Running     1          7h21m
ngx-dep-5c8d96d457-w6nss     1/1     Running     3          8d
readiness-demo               1/1     Running     0          91m
stress-pod                   1/1     Running     0          9m5s
[root@master01 ~]# 

  提示:可以看到應用資源清單以後,對應的pod處於OOMKilled狀態;原因是我們執行的映象裡面的程式一直申請記憶體,超出了最大限制;

  檢視pod詳細資訊

  提示:可以看到當前pod狀態為terminated狀態,原因是OOMKilled;上一次狀態為terminated,原因也是OOMKilled;

相關文章