Container lifeCycle中的postStart和preStop两种hook小结
Contents
一 postStart hook小结
1 应用场景是什么
对于那些在Container启动之后,在正式对外提供服务之后,需要预热的场景,可以通过在Container级别配置postStart hook来实现。比如:一个NGINX服务启动之后,在正式对外提供之前,可以先在Container内部做一个预热,通过执行某个命令请求,使得服务可以提前缓存一些数据。这样,正式对外提供服务时,可以直接使用
2 postStart类型
postStart只支持httpGet和exec类型的probe,不支持tcpSocket。
3 postStart工作机制
它随着Container中的主进程的运行而运行。如果postStart hook执行失败了,那么它会认为整个Container失败。Container将会被重启。
4 postStart作用范围
它是作用在pod中的Container级别的。
5 postStart举例
[root@master-node Chapter06]# pwd /root/kubernetes-in-action-2nd-edition/Chapter06 [root@master-node Chapter06]# cat pod.quote-poststart.yaml apiVersion: v1 kind: Pod metadata: name: quote-poststart spec: containers: - name: nginx image: nginx:alpine ports: - name: http containerPort: 80 lifecycle: postStart: exec: command: - sh - -c - | apk add fortune && \ curl -O https://luksa.github.io/kiada/book-quotes.txt && \ curl -O https://luksa.github.io/kiada/book-quotes.txt.dat && \ fortune book-quotes.txt > /usr/share/nginx/html/quote [root@master-node Chapter06]#
执行,并启动:
[root@master-node Chapter06]# kubectl apply -f pod.quote-poststart.yaml pod/quote-poststart created [root@master-node Chapter06]# =================================== [root@master-node ~]# kubectl get events -w LAST SEEN TYPE REASON OBJECT MESSAGE 21s Normal Scheduled pod/quote-poststart Successfully assigned default/quote-poststart to node-1 19s Normal Pulled pod/quote-poststart Container image "nginx:alpine" already present on machine 19s Normal Created pod/quote-poststart Created container nginx 19s Normal Started pod/quote-poststart Started container nginx ... 0s Warning FailedPostStartHook pod/quote-poststart Exec lifecycle hook ([sh -c apk add fortune && \... 0s Normal Killing pod/quote-poststart FailedPostStartHook 0s Normal Pulled pod/quote-poststart Container image "nginx:alpine" already present on machine 0s Normal Created pod/quote-poststart Created container nginx 0s Normal Started pod/quote-poststart Started container nginx ================================== [root@master-node Chapter06]# kubectl get pods -w NAME READY STATUS RESTARTS AGE quote-poststart 0/1 PostStartHookError 0 (91s ago) 6m18s ... quote-poststart 1/1 Running 1 (4m32s ago) 9m19s
同时,从kubectl describe pod quote-poststart 可以看到postStart报错:
[root@master-node Chapter06]# kubectl describe pod quote-poststart Name: quote-poststart Namespace: default Priority: 0 Node: node-1/172.16.11.148 Start Time: Mon, 30 May 2022 09:11:19 +0800 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 5m34s default-scheduler Successfully assigned default/quote-poststart to node-1 Normal Pulled 47s (x2 over 5m32s) kubelet Container image "nginx:alpine" already present on machine Warning FailedPostStartHook 47s kubelet Exec lifecycle hook ([sh -c apk add fortune && \ curl -O https://luksa.github.io/kiada/book-quotes.txt && \ curl -O https://luksa.github.io/kiada/book-quotes.txt.dat && \ fortune book-quotes.txt > /usr/share/nginx/html/quote ]) for Container "nginx" in Pod "quote-poststart_default(0a375afc-e51b-4033-bd56-d5c932a4171b)" failed - error: command 'sh -c apk add fortune && \ curl -O https://luksa.github.io/kiada/book-quotes.txt && \ curl -O https://luksa.github.io/kiada/book-quotes.txt.dat && \ fortune book-quotes.txt > /usr/share/nginx/html/quote ' exited with 2: ERROR: https://dl-cdn.alpinelinux.org/alpine/v3.15/main: BAD signature WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.15/main: No such file or directory ERROR: unable to select packages: , message: "fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/main/x86_64/APKINDEX.tar.gz\nfetch https://dl-cdn.alpinelinux.org/alpine/v3.15/community/x86_64/APKINDEX.tar.gz\n so:libbsd.so.0 (no such package):\n required by: fortune-0.1-r1[so:libbsd.so.0]\nERROR: https://dl-cdn.alpinelinux.org/alpine/v3.15/main: BAD signature\nWARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.15/main: No such file or directory\nERROR: unable to select packages:\n" Normal Killing 47s kubelet FailedPostStartHook Normal Created 46s (x2 over 5m32s) kubelet Created container nginx Normal Started 46s (x2 over 5m32s) kubelet Started container nginx [root@master-node Chapter06]#
原来报错是,postStart hook中的下载命令失败了,由于网络原因。此时,我们进入pod中的Container里,却是可以看到NGINX已经正常运行的:
[root@master-node Chapter06]# kubectl exec -it quote-poststart -- /bin/sh / # ps aux PID USER TIME COMMAND 1 root 0:00 nginx: master process nginx -g daemon off; 31 nginx 0:00 nginx: worker process 32 nginx 0:00 nginx: worker process 33 root 0:00 sh -c apk add fortune && \ curl -O https://luksa.github.io/kiada/book-quotes.txt && \ curl -O https://luksa.github.io/kiada/book-quotes.txt.dat && \ fortune 38 root 0:00 apk add fortune 44 root 0:00 /bin/sh 49 root 0:00 ps aux / # exit [root@master-node Chapter06]#
二 preStop hook小结
1 应用场景
如果想要在停止Container中的应用之前,做一些“压轴收尾”工作。那么,可以通过在Container中指定lifecycle字段,并指定preStop类型的探针来实现。比如:想要优雅的停止一个NGINX的服务,可以通过在NGINX Container里指定preStop的类型为exec,并执行nginx -s quit命令,这个命令会告知NGINX,对于新起的请求就不响应了,对于已经建立会话的连接,直到client正常退出,而不是直接杀掉所有会话连接。
2 preStop类型
httpGet和exec类型
3 preStop工作机制
它会在Container退出之前,执行该preStop hook。需要注意的是 ,即使preStop hook执行失败了,它也不会导致Container进入terminate状态。
4 preStop作用范围
Container级别
5 preStop举例
[root@master-node Chapter06]# pwd /root/kubernetes-in-action-2nd-edition/Chapter06 [root@master-node Chapter06]# cat pod.quote-prestop.yaml apiVersion: v1 kind: Pod metadata: name: quote-prestop spec: containers: - name: nginx image: nginx:alpine ports: - name: http containerPort: 80 lifecycle: postStart: exec: command: - sh - -c - | apk add fortune && \ curl -O https://luksa.github.io/kiada/book-quotes.txt && \ curl -O https://luksa.github.io/kiada/book-quotes.txt.dat && \ fortune book-quotes.txt > /usr/share/nginx/html/quote preStop: exec: command: - nginx - -s - quit [root@master-node Chapter06]#
三 小结和参考
Container中的lifecycle hook包含postStart和preStop两种类型。见名知意,postStart是在Container启动后,马上执行,其实它是跟Container main process同时执行的;preStop则是在Container停止前,执行的hook,通常用于优雅的关闭容器。
参考:
《Kubernetes in Action Second Edition》 Marko luksa Chapter 06 managing the lifecycle of the Pod’s containers P160–P169.