资讯动态

kubernetes学习(五)pod生命周期

发布时间:2026/8/6 10:51:01 来源:尧图企业网站定制
1、Pod的创建到死亡​从上图开始梳理从左往右pause从时间轴看pod的启动第一个容器pause这个容器是直接创建在节点上的用kubectl describe无法查询创建过程 。这个容器作用提到过初始化网络、挂载可能有的存储卷并且要和其他容器共享network、PID、IPC进程间通信和回收僵尸进程创建结束后就会创建另一个容器类型initCinitC初始化容器从时间轴来看这类容器只出现在我们pod生命周期的前面一部分。在Pod初始化期间完成运行的容器。非必须看需求添加initc会按照定义的顺序依次执行。一个initc完成后下一个initc才会启动。只有所有initc成功完成后主容器才会启动。阻塞特性利用阻塞特性可以实现类似启动前检测的机制比如在主容器运行之前检查外部依赖服务例如数据库、缓存服务、API 网关等是否可用。如果依赖服务未就绪initc会阻塞 pod的启动直到依赖服务正常运行mainC或叫主容器从时间轴来看这类容器出现在我们pod生命周期的后面部分。在Pod初始化结束后运行的容器mainC可以有很多在创建容器过程中它们是并发执行的mainC两个特性钩子和探测探测分为启动探测Startup Probe、就绪探测Readiness Probe、存活探测Liveness ProbeStartupProbe确保容器能够成功启动。如果探针检测失败容器会被杀死并重启在容器启动前生效ReadinessProbe确保容器能够接收流量。如果探针检测失败容器会被标记为未就绪并从服务的负载均衡中移除容器启动后立即生效LivenessProbe确保容器处于“存活”状态。如果探针检测到容器未存活例如进程卡死或进入死循环Kubernetes 会重启该容器容器启动后立即生效钩子分为容器启动后钩子PostStart Hook和容器停止前钩子PreStop Hook统称为生命周期钩子Lifecycle HookPostStart Hook图中mainC有个初始化过程这是容器启动后执行的操作也就是分配资源、设置网络、挂载存储等操作在容器ENTRYPOINT执行后立即触发。这是容器初始化结束后执行的第一条命令如docker run --name centos centos sleep 3600不等待PostStart完成容器就算启动。就是说钩子和容器启动是异步执行容器状态变为Running和Poststart是否完成无关这是官方设计如果PostStart失败容器会被杀死。很奇怪是不是和上面的冲突了。举个栗子一家餐厅宣布开业Pod Running状态同时厨师开始做第一道菜PostStart宣布开业不等于第一道菜做完钩子和容器启动异步执行菜做的难吃餐厅关门杀死容器菜做好了财源滚滚。PreStop Hook容器停止前执行的操作在发送TERM信号之前执行必须完成才能继续停止流程以上就是pod启动的过程详解每个mainC启动都是这些机制。可自定义在资源清单中使用某些机制除mainC以外像initC、钩子探针按需选择可全用部分使用甚至一个不用2、init容器针对initc特性官方有举例这是一个很直观的yaml就是创建一个mainC在mainC之前进行一个初始化的操作已知initC拥有阻塞特性所以在没达到条件之前mainC是永远不可能启动的开始实验apiVersion: v1 kind: Pod metadata: name: initc labels: app: initC spec: containers: - name: mainc image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 command: - sh - -c - echo The app is running! sleep 3600 initContainers: - name: initc-1 image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 command: - sh - -c - until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done - name: initc-2 image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 command: - sh - -c - until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done各位同志。busybox有些版本在使用循环时候即使nolookup无法解析域名返回值也会是0导致退出循环所以做实验的时候可以问问AI那些版本合适并且往后的实验也不加注释了。各位同志熟练使用AI工具创建资源对象后会发现主容器READY就绪状态一直无法启动STATUS状态也显示initC也没有一个启动​查看pod创建过程可以看到只有init-myservice这个容器被启动只有init-myservice这个容器顺利结束进程后死亡init-mydb才会建立。这里就可以体现出initc的阻塞特性了只有第一个以0的返回码退出后才会继续创建第二个​看下init-myservice日志myservice这个容器一直在循环解析域名但是一直解析不到进入了死循环导致了容器无法结束进程顺利死亡​创建一个域名不知道啥意思还没学到然后kubectl describe po initc-1看下可以发现init-mydb容器被创建再看容器日志可以发现已经跳出了循环kubectl create svc clusterip myservice --tcp80:80​但是主容器还是没启动因为第二个intic还没有结束循环​​在创建一个mydb域名 kubectl delete po initc-1查看创建流程init-mydb容器也已经被创建kubectl create svc clusterip mydb --tcp80:80​再看pod容器和日志​​ps关于initc返回码为0的问题这个还没学到可以从网上找找案例自己做测试3、探测探测是由当前pod所在节点的kubectl对容器执行的定期诊断。要执行诊断kubectl调用由容器实现的Handler。有三种类型的探测方式HTTPGetAction对指定的端口和路径上的容器的ip地址执行http get请求。返回状态码在2xx/3xx则诊断成功ExecAction在容器内执行指定命令。如果命令退出时返回码为0则代表诊断成功TCPSocketAction对指定端口上的容器的IP地址进行tcp检查。如果端口打开则诊断成功在三种探测方式中HTTP使用最广EXEC中等TCP需要结合场景使用有一定局限性。3.1就绪探测readinessProbe 就绪探测通过添加就绪探测解决尤其是在扩容时保证提供给用户的服务是可用的如果pod内部的C不添加就绪探测默认C处于就绪状态。如果添加了就绪探测只有就绪探测通过后才标记修改为就绪状态。当前pod内的所有C都就绪才标记当前pod就绪。每次探测都将获得以下三种结果之一成功容器通过了诊断将当前的C标记为就绪失败容器未通过诊断静默不采取任何行动未知这种情况比如说一个C在将要返回状态码时死了探测收不到返回码了。不知所措了因此会保持静默不会采取任何行动就绪探测字段说明在某些字段不配置的情况下pod会按照默认数值执行。intiaIDelaySeconds容器启动后要等待多少秒后探针开始工作单位“秒”默认0最小0periodSeconds执行探测时间间隔单位“秒”默认10最小1timeoutSeconds探针执行检测请求后探测的超时后等待多少秒。默认值是1 。最小值是1successThreshold探针在失败后被视为成功的最小连续成功数。默认值是 1。failureThreshold探测失败的重试次数重试一定次数后将认为失败默认值3最小值1做个示例方便理解。创建两个nginxPod提供给用户访问初始版修改默认主页内容为1v1版修改默认主页内容为2。镜像版本尽量和我保持一致因为有的版本不支持内部修改。而且k8s也是极度不推荐在容器内部修改配置的但是因为要做实验嘛就凑合下#初始版 apiVersion: v1 kind: Pod metadata: name: pod-1 labels: app: nginx spec: containers: - name: nginx-1 image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent #v1版 apiVersion: v1 kind: Pod metadata: name: pod-2 labels: app: nginx spec: containers: - name: nginx-2 image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent这时候分别访问都是没问题的并且两个Pod IP也不一样。众所周知nginx要做负载均衡因此在k8s中提供了更简化的负载均衡方式service后面会学。创建这个service资源时会指定标签选择器labels比如标签选择器的值为appmyapp。这时Service会做匹配选中符合标签的Pod做负载均衡并赋予这个Service一个IP这个IP可以理解为当前负载均衡的vip只要访问这个IP就可以访问服务​访问试一下可以看到负载均衡成功了的​假设用户太多负载均衡需要扩容又用deploymentpod控制器后面会学创建了一个nginxPod这个Pod标签也是appmyapp这个标签也会被service匹配到。Service标签匹配要满足两个条件满足子集匹配pod必须为就绪状态关于子集匹配。假设你有一个大的商品清单A和小的商品清单B清单A此清单包括很多商品如苹果、香蕉、橙子、葡萄、桃子。清单B只有部分商品如苹果、香蕉。子集匹配的任务就是检查清单B的商品是否都能在清单A中找到问题来了如果新pod内nginx还没启动用户就已经连接进来了不就访问错误了么这时候我们可以在扩容的nginxPod上加一个就绪探测。通过探测pod状态来决定是否将扩容的nginx加入负载均衡集群中HTTPGetActionapiVersion: v1 kind: Pod metadata: name: readiness-httpget-pod namespace: default labels:。 app: myapp env: test spec: containers: - name: readiness-httpget-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent # 定义镜像拉取策略如果本地没有该镜像才拉取。 readinessProbe: # 定义容器的就绪探针用于检查容器是否可接收流量。 httpGet: # 使用 HTTP GET 方法探测。 port: 80 # 探测的端口号这里是容器内的80端口。有的是映射在8080 path: /index1.html # 探测的路径这里是 /index1.html。 initialDelaySeconds: 1 # 在容器启动后延迟 1 秒开始进行探测。 periodSeconds: 3 # 探测的时间间隔每 3 秒进行一次探测。启动pod可以看到pod在运行确认标签是否被service匹配到以及是否能加入到负载均衡集群中​用curl访问service的ip可以看到这个pod并没有加载到集群中并且一直处于未就绪状态前面提过Service匹配要满足两个条件满足子集匹配和容器必须为就绪状态。用命令看下创建Pod过程中是否记录了未就绪原因可以发现报错404找不到index1.html这个主页​就绪探测应该是一个自然而然的状态。比如一个服务启动需要3秒3秒后启动成功了这就是正常情况。上面的例子为了方便理解所以写了一个无法恢复的情况。想让探测通过就要手动创建index1.html文件。进入容器内部到nginx主页下创建一个index1.html文件。退出容器再看pod已经准备就绪了​测试是否加入了负载均衡集群​出现了1 2 和扩容pod的默认nginx主页所以只要在创建或扩容新的pod时添加一个就绪探测只要能达到就绪状态就会自动添加到负载均衡集群这就是真正就绪探测的意义ExecActionapiVersion: v1 kind: Pod metadata: name: readiness-exec-pod labels: env: test app: nginx spec: containers: - name: readiness-exec-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent readinessProbe: exec: # 使用执行命令的方法进行探测。 command: # 探测命令检查文件是否存在。 - test - -e - /usr/share/nginx/html/index1.html #命令写法有两种实验中的另一种是command: [“命令”“参数”“执行对象”]每部分需用逗号隔开 initialDelaySeconds: 1 periodSeconds: 3还有另一种实时观测的办法kubectl get pod -w #实时查看pod状态apiVersion: v1 kind: Pod metadata: name: readiness-exec2-pod labels: env: test app: nginx spec: containers: - name: readiness-exec-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 imagePullPolicy: IfNotPresent command: - /bin/sh - -c - | # 用于定义保留换行符的多行字符串。通俗的说加了这个下面的命令就可以顺序执行 sleep 10 touch /tmp/test.txt sleep 3600 readinessProbe: exec: command: - test - -e - /tmp/test.txt initialDelaySeconds: 1 periodSeconds: 3从上图看执行结果容器创建后先是延迟1秒进行探测执行休眠10秒的命令期间间隔探测也在继续10秒后创建文件探测立马成功Pod状态RunningTCPSocketAction这种探测方式多用于数据库消息队列缓存等服务apiVersion: v1 kind: Pod metadata: name: readiness-tcpsocket labels: app: nginx spec: containers: - name: readiness-tcpsocket-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent command: - sh - -c - | sleep 30 nginx -g daemon off; #容器内nginx启动命令正常启动命令无法容器内使用 readinessProbe: tcpSocket: port: 80 periodSeconds: 3 #3秒探测一次 failureThreshold: 10 #探测失败的重试次数重试10次后将认为失败 #比较简单的测试方法这个更容易理解 apiVersion: v1 kind: Pod metadata: name: readiness-tcpsocket labels: app: nginx spec: containers: - name: readiness-tcpsocket-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 imagePullPolicy: IfNotPresent command: - sh - -c - | sleep 20 nc -l -p 80 -k -e echo READY #通过nc命令打开80端口持续监听 sleep 3600 readinessProbe: tcpSocket: port: 80 periodSeconds: 3 #3秒探测一次 failureThreshold: 10 #探测失败的重试次数重试10次后将认为失败看pod创建过程nginx默认启动命令我放在了休眠后所以在容器创建时立马就进行了探测探测3秒一次看时间8m8s容器创建成功7m38s到创建成功正好30秒并且30秒内探测失败了12次。嗯12次是不是不太对根据字段设置重试10次探测就认为失败为什么会有12次这是因为k8s设计哲学容器是可能自我恢复的。当探测10次后标记容器不健康但是探测还是在继续的举个例子公司规定连续3天体温38° → 回家隔离failureThreshold: 3实际情况第1天38.5° → 记录1第2天38.8° → 记录2第3天39.0° → ❗达到阈值回家隔离但是检测继续第4天还在测体温万一降到37°就能回来第5天还在测体温就是这个道理3.2存活探测livenessProbe 存活探测通过添加存活探测解决虽然活着但是已经死了的问题。如果pod内部不指定存活探测可能会发生容器运行但是无法提供服务的情况每次探测都将获得以下三种结果之一成功静默失败根据重启的策略进行重启的动作本质上是重建谁死了就把它鲨了创建新的对应容器未知静默存活探测字段说明在某些字段不配置的情况下他会按照默认数值执行。intiaIDelaySeconds容器启动后要等待多少秒后探针开始工作单位“秒”默认0最小0periodSeconds执行探测时间间隔单位“秒”默认10最小1timeoutSeconds探针执行检测请求后探测的超时后等待多少秒。默认值是1 。最小值是1successThreshold探针在失败后被视为成功的最小连续成功数。默认值是 1。 存活探测的这个值必须是1。最小值是1就是说设置探测成功几次才算真正的成功failureThreshold探测失败的重试次数重试一定次数后将认为失败默认值3最小值1HTTPGetActionapiVersion: v1 kind: Pod metadata: name: liveness-http labels: app: nginx spec: containers: - name: liveness-http-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent livenessProbe: httpGet: port: 80 path: /index.html initialDelaySeconds: 1 #通过GET http://PodIP:port/index.html(这个在应用层协议HTTP的请求头中)探测nginx默认主页返回http状态码。只有2xx/3xx状态码才算成功​kubectl exec -it liveness-httpget-pod -c liveness-httpget-container -- /bin/bash进入容器给主页改个名字可以看到改完名字后就退出容器了在我们的理解中它变成了一种即存在但又无法访问的情况所以要把这个容器杀死。但是pod重启策略又是Always总是重启所以会创建新的容器取代它​再次进入容器看看是否为新的容器会发现新的index.html主页刚才改名的不存在了​还可以用另一种方式查看是否为重建的新容器kubectl get po -o wide #找到pod所在节点​docker ps -a |grep pod-name​k8s_container-name_pod-name_namespaces_唯一标识符UUID_重启次数探测失败后发现个问题失败的容器没有被删除新的就被创建了。经过测试发现探测失败的容器会保留重建容器的前一个比如有容器0和1pod新建了容器2那么失败的1会被保留0被删除ExecActionapiVersion: v1 kind: Pod metadata: name: liveness-exec-pod namespace: default spec: containers: - name: liveness-exec-container image: busybox imagePullPolicy: IfNotPresent command: [/bin/sh,-c,touch /tmp/live ;sleep 60 ;rm -fr /tmp/live ;sleep 3600] livenessProbe: exec: command: [test, -e, /tmp/live] initialDelaySeconds: 1 periodSeconds: 3kubectl get po -w监控这个pod的状态可以看到pod被重启重建了两次​为什么会被不停的重建呢这就要提到探测失败后的重启策略了先查一下kubectl get po liveness-exec-pod -o yamlliveness-exec-pod的 Pod 的详细信息以 YAML 格式输出其中有这么一行这是默认的重启重启策略Always总是也有Nerver策略​TCPSocketAction此探测方式使用场景比较有局限性。使用较少作为了解即可因为他的探测就相当于执行了nc -zv 127.0.0.1 80这个操作只能检查tcp链接是否建立无法检查服务是否健康。典型的就是web应用探测到tcp链接但是返回码500这种情况。所以tcp探测一般作为补充通常http就能满足我们的绝大部分需求apiVersion: v1 kind: Pod medadata: name: liveness-tcp-pod spec: container: - name: liveness-tcp-container image: nginx imagePullPolicy: IfNotPresent livenessProbe: initialDelaySeconds: 5 timeoutSeconds: 1 tcpSocket: port: 803.3启动探测startupProbe 启动探测k8s在1.16版本以后官方新增功能。保障存活探针在执行的时候不会因为时间设定问题导致无限死亡或着延迟很长的情况启动探针专门为启动时间长或初始化过程复杂的容器设计它的功能是 确保容器完全启动后再开始执行存活和就绪探针。启动探针可以避免容器在启动过程中因延迟或未完成初始化而被过早杀死每次探测都将获得以下三种结果之一成功开始允许存活探测或就绪探测开始执行失败静默未知静默以下是启动探测字段说明intiaIDelaySeconds容器启动后要等待多少秒后探针开始工作单位“秒”默认0最小0periodSeconds执行探测时间间隔单位“秒”默认10最小1timeoutSeconds探针执行检测请求后探测的超时后等待多少秒。默认值是1 。最小值是1successThreshold探针在失败后被视为成功的最小连续成功数。默认值是 1。 启动探测的这个值必须是1。最小值是1就是说设置探测成功几次才算真正的成功failureThreshold探测失败的重试次数重试一定次数后将认为失败默认值3最小值1httpGetActionapiVersion: v1 kind: Pod metadata: name: start-http-pod labels: app: myapp namespace: default spec: containers: - name: start-http-nginx image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent startupProbe: httpGet: path: /index2.html port: 80 failureThreshold: 30 periodSeconds: 10 readinessProbe: httpGet: path: /index1.html port: 80 initialDelaySeconds: 3 periodSeconds: 3 应用程序有最多5分钟failureThreshold*periodSeconds30*10300s的时间来完成其启动过程启动探测是优先于存活或就绪探测的同志们可以先创建index1.html观察pod就绪状况再创建index2.html就可以确定探测顺序了ExecActionapiVersion: v1 kind: Pod metadata: name: start-exec-pod labels: app: myapp namespace: default spec: containers: - name: start-exec-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent startupProbe: exec: command: - sh - -c - [ -f /tmp/ready.txt ] initialDelaySeconds: 20 periodSeconds: 3 failureThreshold: 10我做实验的栗子都是简单的同志们可以自己加难度比如检查服务文件啥的TCPSocketActionapiVersion: v1 kind: Pod metadata: name: start-tcp-pod labels: app: myapp namespace: default spec: containers: - name: start-tcp-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent startupProbe: tcpSocket: port: 80 initialDelaySeconds: 0 periodSeconds: 5 failureThreshold: 604、钩子其实钩子可以做的事情不是很多按需使用。钩子的使用场合仅在于pod生命周期的边界即“容器启动后立即执行和容器停止前立即执行”通俗来说“启动后钩子”适用于初始化、注册等操作“停止前钩子”适用于清理、注销等操作。且尽量避免在钩子上执行长时间运行的任务钩子分为两种PostStart启动后钩子这个回调在容器被创建之后立即被执行。 但是不能保证回调会在容器入口点ENTRYPOINT之前执行。 没有参数传递给处理程序。PreStop结束前钩子在容器因 API 请求或者管理事件诸如存活态探针、启动探针失败、资源抢占、资源竞争等 而被终止之前此回调会被调用。 如果容器已经处于已终止或者已完成状态则对 preStop 回调的调用将失败。 在用来停止容器的 TERM 信号被发出之前回调必须执行结束。 Pod 的终止宽限周期在PreStop回调被执行之前即开始计数 所以无论回调函数的执行结果如何容器最终都会在 Pod 的终止宽限期内被终止。 没有参数会被传递给处理程序钩子执行方式execapiVersion: v1 kind: Pod metadata: name: postart labels: lifecycle: hook namespace: default spec: containers: - name: poststart-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent lifecycle: # 定义容器生命周期的钩子 postStart: # postStart 钩子在容器启动后执行的命令 exec: command: #容器运行后执行的命令 - sh - -c - | echo poststart /usr/share/message preStop: # preStop 钩子在容器停止前执行的命令 exec: command: #容器停止前执行的命令 - sh - -c - | echo prestop /usr/share/message创建对象后进入容器内查看文件内容如下证明了启动后钩子执行没有问题kubectl exec -it podName -c containerName -- /bin/bash #-c是可选选项pod内只有单一容器的话忽略此选项​现在来验证停止前钩子执行是否可行在容器内写个死循环不停查看文件while true ;do cat /usr/share/message ;done​​从上图可以观测到容器停止前执行了停止前钩子的命令钩子执行方式HTTP随便一个节点前台先启动一个web服务并创建对象pod是否有发起访问请求​apiVersion: v1 kind: Pod metadata: name: lifecycle-http labels: app: myapp spec: containers: - name: lifecycle-http-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 imagePullPolicy: IfNotPresent command: - sh - -c - sleep 3600 lifecycle: postStart: httpGet: host: 192.168.100.102 port: 1234 path: /index.html preStop: httpGet: host: 192.168.100.102 port: 1234 path: /index.html启动pod后再看前台访问记录会发现有一条访问记录这是启动后钩子poststart起作用了​紧接着删除pod会发现新增了一条访问记录这是关闭前钩子起作用了​从实验结果来看两个钩子的执行是没有任何问题的钩子的延伸说明postStartpostStart的成败和容器主进程是并行执行的postStart永远不会阻塞容器主进程的启动postStart永远不阻塞容器主进程的启动这是设计决定如果 postStart 的操作与主进程无关如发送通知、记录日志则完全不影响postStart是否影响容器正常运行取决于主进程是否依赖 postStart 的操作结果。如果主进程需要等待 postStart 的结果则需要额外的协调机制initContainer、readinessProbe、等待循环比如postStart: exec: command: [sh, -c, 生成配置文件] # 如果主进程需要这个配置文件就会出现问题 containers: - name: app command: [./app, --config, /tmp/config.yml] # ❌ 可能文件还没生成preStop则与postStart完全相反它是阻塞执行的操作主要用于实现优雅终止。它的核心作用是在容器被强制终止前给应用程序一个清理和完成现有工作的机会。总之局限性很大用到了在探索也不迟5、融合所有功能写一个pod#创建个域名为init容器做准备 kubectl create svc clusterip myservice --tcp80:80 #EXEC版本 apiVersion: v1 kind: Pod metadata: name: all labels: function: all namespace: default spec: initContainers: - name: init-all-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 imagePullPolicy: IfNotPresent command: - sh - -c - until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done containers: - name: main-all-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 imagePullPolicy: IfNotPresent command: - sh - -c - | echo The app is running! sleep 3600 startupProbe: exec: command: - sh - -c - [ -f /tmp/start.txt ] initialDelaySeconds: 3 periodSeconds: 3 timeoutSeconds: 3 successThreshold: 1 failureThreshold: 3 readinessProbe: exec: command: - sh - -c - [ -f /tmp/read.txt ] initialDelaySeconds: 3 periodSeconds: 3 timeoutSeconds: 3 successThreshold: 3 failureThreshold: 3 livenessProbe: exec: command: - sh - -c - [ -f /tmp/liven.txt ] initialDelaySeconds: 3 periodSeconds: 3 timeoutSeconds: 3 successThreshold: 1 failureThreshold: 3 lifecycle: postStart: exec: command: - sh - -c - | touch /tmp/start.txt touch /tmp/read.txt touch /tmp/liven.txt preStop: exec: command: - sh - -c - echo bye~ #注意钩子的执行过程信息是不会打印出来的 #另外。这个资源清单逻辑上比较简单但是有一个小小的不和谐。那就是启动后钩子的命令可以放在容器启动的执行主命令中并且在主命令中执行一定会在探测之前创建结束所以生产中EXEC方式要比HTTP方式稍微稳定一些由此可见钩子的局限性按需使用 ---------------分割线------------------- #由于poststart和主服务进程启动顺序未知http方式钩子实验效果不是很好展示所以可以在任意节点用docker起一个容器用钩子进行访问观察容器日志即可 docker run -it -p 1234:80 --name nginx-container 镜像ID #HTTP版本 apiVersion: v1 kind: Pod metadata: name: all-http labels: function: http spec: initContainers: - name: init-all-http-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 imagePullPolicy: IfNotPresent command: - sh - -c - until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done containers: - name: main-all-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent command: - sh - -c - | touch /usr/share/nginx/html/index1.html touch /usr/share/nginx/html/index2.html touch /usr/share/nginx/html/index3.html nginx -g daemon off; startupProbe: httpGet: path: /index1.html port: 80 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 10 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /index2.html port: 80 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 10 successThreshold: 3 failureThreshold: 5 livenessProbe: httpGet: path: /index3.html port: 80 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 10 successThreshold: 1 failureThreshold: 5 lifecycle: postStart: httpGet: path: /index.html port: 1234 host: 192.168.100.102 #如果不指定此字段默认就是 Pod IP自己 preStop: httpGet: path: /index.html port: 1234 host: 192.168.100.102 ---------------分割线------------------- apiVersion: v1 kind: Pod metadata: name: test labels: test: test spec: initContainers: - name: init-1 image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 imagePullPolicy: IfNotPresent command: [sh,-c,sleep 10] - name: init-2 image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 imagePullPolicy: IfNotPresent command: [sh,-c,sleep 10] containers: - name: main-container image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.0 imagePullPolicy: IfNotPresent lifecycle: postStart: exec: command: [sh,-c,sleep 20 touch /tmp/test.txt] #启动后钩子增加延时确保不和主容器进程并行执行。像这个操作就是不规范的避免在生产中出现因为是做实验所以不讲究 preStop: exec: command: [sh,-c,sleep 30] #容器停止前会阻塞30秒才会被杀死 startupProbe: tcpSocket: port: 80 initialDelaySeconds: 3 periodSeconds: 3 timeoutSeconds: 3 successThreshold: 1 failureThreshold: 3 readinessProbe: exec: command: [test,-f,/tmp/test.txt] initialDelaySeconds: 3 periodSeconds: 3 timeoutSeconds: 3 successThreshold: 3 failureThreshold: 3 livenessProbe: httpGet: path: /index.html port: 806、pod如何被调度运行​

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价