pod(五):pod hook(pod勾點)和優雅的關閉nginx pod

2022-11-02 12:00:20

一.系統環境

伺服器版本 docker軟體版本 Kubernetes(k8s)叢集版本 CPU架構
CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 x86_64

Kubernetes叢集架構:k8scloude1作為master節點,k8scloude2,k8scloude3作為worker節點

伺服器 作業系統版本 CPU架構 程序 功能描述
k8scloude1/192.168.110.130 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master節點
k8scloude2/192.168.110.129 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker節點
k8scloude3/192.168.110.128 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker節點

二.前言

本文介紹pod hook(pod勾點)和如何優雅的關閉nginx pod。

管理pod的前提是已經有一套可以正常執行的Kubernetes叢集,關於Kubernetes(k8s)叢集的安裝部署,可以檢視部落格《Centos7 安裝部署Kubernetes(k8s)叢集》https://www.cnblogs.com/renshengdezheli/p/16686769.html

三.pod hook(pod勾點)

為容器的生命週期事件設定處理常式,Kubernetes 支援 postStart 和 preStop 事件。 當一個容器啟動後,Kubernetes 將立即傳送 postStart 事件;在容器被終結之前, Kubernetes 將傳送一個 preStop 事件。容器可以為每個事件指定一個處理程式。

pod hook:目前pod3容器裡執行的是nginx程序,在啟動容器的時候,除了主程序,還想啟動一個程序,怎麼辦?這時候就需要使用pod hook(pod 勾點),pod hook有兩個選項:

  • postStart:容器啟動之後執行XXXX,和主程序是同時執行起來的,並沒有先後順序;
  • preStop:在容器關閉之前執行XXXX

postStart例子:容器啟動之後執行"/bin/sh","-c","date >> /tmp/bb.txt",列印日期到/tmp/bb.txt檔案

[root@k8scloude1 pod]# vim pod3.yaml 

[root@k8scloude1 pod]# cat pod3.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod3
  name: pod3
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: nginx
    command: ["sh","-c","date > /tmp/aa.txt ; sleep 10000"]
    imagePullPolicy: IfNotPresent
    name: n1
    resources: {}
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh","-c","date >> /tmp/bb.txt"]
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

[root@k8scloude1 pod]# kubectl apply -f pod3.yaml 
pod/pod3 created

[root@k8scloude1 pod]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
pod3    1/1     Running   0          8s

檢視檔案可以發現,/tmp/aa.txt /tmp/bb.txt 時間是一致的,就說明兩個命令是同時執行的,證明了postStart:容器啟動之後執行XXXX,和主程序是同時執行起來的,並沒有先後順序。

[root@k8scloude1 pod]# kubectl exec -it pod3 -- bash
root@pod3:/# cat /tmp/aa.txt /tmp/bb.txt 
Thu Jan 13 07:40:24 UTC 2022
Thu Jan 13 07:40:24 UTC 2022
root@pod3:/# exit
exit

#刪除pod
[root@k8scloude1 pod]# kubectl delete -f pod3.yaml 
pod "pod3" deleted

現在新增preStop處理常式:在容器關閉之前執行"/bin/sh","-c","date >> /tmp/bb.txt ; sleep 100",列印日期到/tmp/bb.txt檔案,並休眠100秒。

[root@k8scloude1 pod]# vim pod4.yaml 

[root@k8scloude1 pod]# cat pod4.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod3
  name: pod3
spec:
  terminationGracePeriodSeconds: 600
  containers:
  - image: nginx
    command: ["sh","-c","date > /tmp/aa.txt ; sleep 10000"]
    imagePullPolicy: IfNotPresent
    name: n1
    resources: {}
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh","-c","date >> /tmp/bb.txt"]
      preStop:
        exec:
          command: ["/bin/sh","-c","date >> /tmp/bb.txt ; sleep 100"]
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

[root@k8scloude1 pod]# kubectl apply -f pod4.yaml 
pod/pod3 created

[root@k8scloude1 pod]# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
pod3    1/1     Running   0          7s

執行一段時間後,刪除pod,在容器關閉之前執行preStop的命令,preStop執行完成之後,主程式還要執行10000秒,但是寬限期terminationGracePeriodSeconds只有600s,所以600秒之後pod被刪除

[root@k8scloude1 pod]# kubectl delete pod pod3 
pod "pod3" deleted
^C

#強制刪除pod
[root@k8scloude1 pod]# kubectl delete pod pod3 --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "pod3" force deleted

四.如何優雅的關閉nginx pod

說明: 當一個 Pod 被刪除時,執行kubectl get pod 命令會展示這個 Pod 的狀態為 Terminating(終止)。 這個 Terminating 狀態並不是 Pod 階段之一。 Pod 被賦予一個可以體面終止的期限,預設為 30 秒。 你可以使用 --force 引數來強制終止 Pod。

由於nginx預設是fast shutdown,關閉的時間一般小於30秒,如果想優雅的關閉nginx,可以在關閉容器之前執行nginx -s quit ,達到優雅的關閉nginx的效果

[root@k8scloude1 pod]# vim pod5.yaml 

#preStop處理常式指定在容器關閉之前執行"/bin/sh","-c","/usr/sbin/nginx -s quit"
[root@k8scloude1 pod]# cat pod5.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod5
  name: pod5
spec:
  terminationGracePeriodSeconds: 600
  containers:
  - image: nginx
    command: ["sh","-c","date > /tmp/aa.txt ; sleep 10000"]
    imagePullPolicy: IfNotPresent
    name: n1
    resources: {}
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh","-c","date >> /tmp/bb.txt"]
      preStop:
        exec:
          command: ["/bin/sh","-c","/usr/sbin/nginx -s quit"]
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

[root@k8scloude1 pod]# kubectl apply -f pod5.yaml 
pod/pod5 created

[root@k8scloude1 pod]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
pod5   1/1     Running   0          5s

[root@k8scloude1 pod]# kubectl delete pod pod5 
pod "pod5" deleted
^C
[root@k8scloude1 pod]# kubectl delete pod pod5 --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "pod5" force deleted