首页 > 其他分享 >记一次因Pod钩子引起Pod 持续Containercreating事件

记一次因Pod钩子引起Pod 持续Containercreating事件

时间:2023-09-18 17:35:08浏览次数:39  
标签:脚本 容器 Containercreating 钩子 Pod 执行 运行

前言

在Kubernetes 日常维护中,都会出现各种业务需求,比如当一个Deployment Pod 资源类型启动之后,我还需要让它在业务容器生命周期中,执行一些自定义任务内容,那么该如何满足这一需求呢?这时候就引入一个概念Pod Hook(钩子)。本篇将会结合实际生产案例,带大家了解一下Pod Hook独特魅力

Pod Hook类型

Init Containers Hook

对于初始化容器钩子,它们在Pod中所有容器Running之前运行,这意味着初始化容器钩子将在Pod中的任何其它容器的ENTRYONINT之前执行,允许执行在正式容器启动之前执行一些额外的逻辑,例如初始化数据,创建配置文件等,初始化容器钩子可以用来确保Pod的各个容器都具备运行所需要的环境和资源

Contrainer Lifecycle Hook

Pod Hook是由Kubelet发起的,当一个容器进程启动后或者终止前运行,这是存在于容器生命周期中,我们可以根据业务需求来为Pod配置Hook

Kubernetes为我们提供了两种钩子函数:

PostStart(容器启动后): 这个钩子在容器创建后开始执行设设定的逻辑,例如注册服务,健康检测,或者执行脚本任务等等

PreStop(容器停止前):在容器停止之前执行所设定的逻辑,例如保存数据,清理资源等等。容器生命周期钩子可以用于实现一些容器级别的操作,例如与外部服务交互、监控、日志记录等等,

无论是初始化容器钩子,还是容器生命周期钩子,它们都是可以通过定义在Pod的Spec字段中的initContainers和Containers 属性中的lifecycle字段来配置,使用这些钩子可以在Pod的不同阶段执行自定义逻辑,以满足特定的需求和业务场景

 背景需求

某个业务场景需要在Pod生命周期中,添加一个自定义Shell脚本任务,该脚本是一个循环执行的内容,为了复现问题,先给出一个任务脚本,如下:

该脚本会每间隔2s就会创建一个以数字为前缀的txt文件,且是不断递增创建新文件

#!/bin/bash
count=1
while true
do
    filename="$count.txt"
    touch "/usr/share/nginx/html/$filename"
    echo "Created $filename"
    count=$((count + 1))
    sleep 2
done

我们以ConfigMap的形式创建并挂载

kind: ConfigMap
apiVersion: v1
metadata:
  name: filebash
  namespace: middleware
  annotations:
    kubesphere.io/creator: admin
data:
  file.sh: |-
    #!/bin/bash
    count=1
    while true
    do
        filename="b$count.txt"
        touch "/usr/share/nginx/html/$filename"
        echo "Created $filename"
        count=$((count + 1))
        sleep 2
    done

记一次因Pod钩子引起Pod 持续Containercreating事件_Pod

此时你会发现一个问题,最新Pod状态一直处于ContainerCreating,一直持续了半个小时仍然没有变成Running状态

记一次因Pod钩子引起Pod 持续Containercreating事件_Kubernetes_02

常见原因

那么综上所述,通常这个情况,导致Pod一直处于ContainerCreating状态,其中肯定是有一些问题阻止了容器的成功创建,常见的原因包括:

  • 镜像拉取问题

这是最常见的问题之一,可能指定的镜像不存在,镜像名称拼写有误或者网络问题导致镜像无法响应等,可使用kubectl describe pod <pod name>查看镜像拉取的相关问题

  • 资源不足

如果pod所调度的节点内存或者CPU资源不足,也会导致容器无法正常创建,那么Pod就会一直处于ContainerCreating,需检查集群的资源(cpu、内存)是否足以启动Pod中的容器,可以使用kubectl describe node命令查看所调度的节点使用情况

#kubectl describe node
  • 网络问题

kubernetes集群网络一般都依赖于CNI(容器网络接口)插件出现了问题,可能会导致容器重建,确保Pod能够与Kubernetes集群网络正常通信,

#kubectl exec -it nginx-669d46686d-scfmk -n middleware bash
  • Docker运行出现问题

如果Docker守护进程或者容器运行的问题,可能会阻止容器的创建

  • 持久卷问题

Pod依赖于一个持久卷声明(PVC)并且该PVC不可用或因为某些原因无法挂载,那么Pod将保持在“ControllerCreating”状态

  • pod上下文问题

如果一个pod或者容器的安全上下文没有正确配置(例如,Pod试图以一个不存在的用户身份运行),它会阻止启动

问题排查

尝试用kubectl describe pod命令来检查pod的事件,看是否出现异常关键信息

# kubectl describe  pod nginx-669d46686d-vk6k2 -n middleware

记一次因Pod钩子引起Pod 持续Containercreating事件_执行上下文_03

很显然没有任何异常信息,随后我检查了pod网络是否异常,发现网络也正常

记一次因Pod钩子引起Pod 持续Containercreating事件_生命周期_04

经过一系列排查,看来都不是因为简单的异常导致的,冷静下来进行思索...羊毛出在羊身上。

问题定位

为什么之前引用shell脚本作为Pod hook,Pod都正常创建呢,而这次不行呢?这时候大概率可以是任务脚本内容本身的问题,随后我们把目光锁定在脚本内容上。我发现Pod hook脚本仍在执行,于是乎便开始思考:PostStart钩子它是在Pod状态Running之前运行还是Running之后在执行Pod hook呢?

记一次因Pod钩子引起Pod 持续Containercreating事件_Pod_05

由上图可以发现,Pod hook任务正在执行,但是Pod状态仍然是ContainerCreateing,, 由此可见,postStart钩子是在容器状态就绪之前就已执行,因为脚本是无限循环创建文件的状态,不会停止,假设状态不停止,那么Pod 一直就会处于ContainerCreateing 。由此可得出结论 正常需要在钩子完成之后才能继续进行容器的创建和启动,而无限循环的脚本会一直占用钩子的执行上下文,导致钩子无法完成

拓展知识点

上面说到Pod执行上下文,那么什么是Pod执行上下文呢?

在Kubernetes中,Pod的执行上下文(Excution Context )指的是容器运行时所处的环境和条件,这个上下文包括了容器运行所需的各种资源、配置和运行状态等信息。Pod的执行上下文包括以下方面

资源限制和需求:

指定了Pod中每个容器的CPU、内存等资源的限制和需求。这些限制和需求会影响容器在节点上的调度和运行。

网络配置:

指定了Pod的网络配置,包括网络插件、IP地址、端口映射等。这些配置决定了容器之间以及容器与外部网络的通信方式。

存储卷:

指定了Pod中容器的存储卷配置,包括持久卷、临时卷等。这些存储卷可以用于容器之间的数据共享或持久化存储。

环境变量和配置:

指定了容器的环境变量和配置文件等信息。这些信息可以影响容器内部的应用程序的行为和配置。

生命周期钩子:

指定了容器的生命周期钩子,包括postStartpreStop等。这些钩子会在容器启动前和停止后执行特定的操作。

总结

Pod的执行上下文在Pod创建和调度过程中起着重要的作用。它会影响容器的启动、运行和终止过程,确保容器能够在正确的环境下运行,并满足其所需的资源和配置要求。

问题解决

定位了问题所在,那么想要解决该问题也就好办了,于是乎,我这里给罗列出很多解决办法,可供大家参考

修改钩子脚本

将无限循环的脚本改为执行完所需操作后自动退出,以释放钩子的执行上下文。例如,在脚本中添加适当的条件判断,当满足条件时跳出循环或执行退出命令。

使用其他机制

如果需要在容器启动后执行长时间运行的任务,可以考虑使用Kubernetes中的其他机制,如Init Containers或Sidecar Containers。这些机制可以在容器启动后运行额外的容器来执行需要长时间运行的任务,而不会阻塞主容器的启动。

调整重启策略

如果无法修改钩子脚本或使用其他机制,可以考虑调整Pod的重启策略。将重启策略设置为Never,这样当钩子脚本无法完成时,Pod将不会被终止和重启,而是保持在ContainerCreating状态。但请注意,这可能会导致其他问题,如容器无法正常启动或无法自动恢复。 无论哪种方法,都建议在修改Pod的配置之前,先进行测试和验证,确保修改后的配置能够正常运行,并且不会引入其他问题。

脚本后台运行

将脚本设定为后台执行,可以通过nohup将脚本放入后台执行,此时就不会占用前台的上下文环境。

在这里,我们选择将脚本通过nohup置于后台运行

lifecycle:
   postStart:
     exec:
       command:
         - /bin/sh
         - '-c'
         - ' nohup sh /opt/file.sh >/tmp/file.log &'

记一次因Pod钩子引起Pod 持续Containercreating事件_Kubernetes_06

将脚本置于后台运行之后,可以发现,脚本仍然正常执行,并且Pod running正常

记一次因Pod钩子引起Pod 持续Containercreating事件_执行上下文_07

记一次因Pod钩子引起Pod 持续Containercreating事件_生命周期_08

END!


标签:脚本,容器,Containercreating,钩子,Pod,执行,运行
From: https://blog.51cto.com/u_11880730/7512433

相关文章

  • 如何巧妙应用SHOPLINE的POD(商品定制)来提升店铺销量?
    如今,消费者追求个性化产品的趋势愈发明显。据德勤消费者评论报告数据显示,有超过50%的消费者表示有兴趣为自己、朋友和家人购买个性化产品,五分之一的消费者表示愿意为个性化产品多支付20%的价格。面对这样的趋势,我们该怎样抓住机会,既能满足消费者的个性化需求,还能提升店铺产品销......
  • 图解几种常见 Kubernetes Pod 驱逐场景
    图解几种常见KubernetesPod驱逐场景sysdig 奇妙的Linux世界 2023-09-1708:20 发表于重庆 1人听过收录于合集#云原生263个#Kubernetes280个#Docker203个#开源461个公众号关注 「奇妙的Linux世界」设为「星标」,每天带你玩转Linux! KubernetesPod被......
  • vue--day88--缓存路由组件和 两个新的生命周期钩子
    ###10.缓存路由组件 1.作用:让不展示的路由组件保持挂载,不被销毁。 2.具体编码:   ```vue  <keep-aliveinclude="News">     <router-view></router-view>  </keep-alive>  ``` ###11.两个新的生命周期钩子 1.作用:路由组件所独有的两......
  • k8s安装Dashboard出现了 pod 状态为CrashLoopBackOff
    1、问题现象2、解决办法(1)先看一下pods日志信息kubectllogs-f-nkubernetes-dashboardkubernetes-dashboard-658485d5c7-h75rs(2)错误信息:Get"https://10.96.0.1:443/api/v1/namespaces/kubernetes-dashboard/secrets/kubernetes-dashboard-csrf":dialtcp10.9......
  • 调整节点部署pod数上限
    默认单节点部署pod数上限是110,超过时会调度失败。vim/var/lib/kubelet/config.yamlmaxPods:300systemctlrestartkubelet......
  • pod详解
    目录一、pod详解二、pause容器三、Pod分类四、容器的分类五、镜像拉取策略六、harbor仓库使用yaml拉取镜像     一、pod详解1.Pod基础概念Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行......
  • flask从入门到精通之钩子、异常、context、jinjia模板、过滤器
    一、请求全局钩子【hook】此处的全局钩子,其实就是类似django里面的中间件。也就是只要调用或者注册了,在http请求响应中是必然执行的。在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:在项目运行开始时,建立数据库连接,或创建连接池;在客户端请求开始时,根据......
  • K8S系列(八)持久化存储(Pod Volumes,PV和PVC)
    一、概述:官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/在kubernetes集群中,使用subPath,有时,在单个Pod中共享卷以供多方使用是很有用的。volumeMounts.subPath属性可用于指定所引用的卷内的子路径,而不是其根路径。1、subPath是在挂载的卷......
  • k8s Pod管理脚本
    1.背景场景:1  测试环境k8s集群中例如业务启动的pod长时间没有进行维护导致僵死场景:2pod输出的日志文件太多量太大导致日志收集容器出现收集不到或者日志内容延迟的相关问题. 场景:3应用多容器采用pod代理管控流量方式代码层面导致容器连接长时间失败. 故  1.降低人工......
  • 3.4 DLL注入:全局消息钩子注入
    SetWindowHookEx是Windows系统的一个函数,可用于让一个应用程序安装全局钩子,但读者需要格外注意该方法安装的钩子会由操作系统注入到所有可执行进程内,虽然该注入方式可以用于绕过游戏保护实现注入,但由于其属于全局注入所以所有的进程都会受到影响,而如果想要解决这个问题,则需要在Dll......