在 k8s pod 启动时启动 tomcat 后运行脚本



在 pod 中启动 tomcat 后,我正在尝试运行一个 pod 引导脚本(基本上运行一个 java 程序(。我的 pod 运行一个基于 tomcat 的容器。这是我正在处理和重新处理的代码片段:

- image: myreg/mydir/myimg:local
name: tomcat-adminapp
command: ["/bin/sh"]
args: ["-c", "$CATALINA_HOME/bin/startup.sh && /scripts/runUpg.sh"]

runUpg.sh 脚本:

#!/bin/sh
ls -l $CATALINA_HOME/webapps/app/WEB-INF/lib/
chmod 755 $CATALINA_HOME/webapps/app/WEB-INF/lib/*
java -classpath "$CATALINA_HOME/webapps/app/WEB-INF/lib/*" com.myclass.Upg <args> 
tail -f /dev/nul

它正在启动 tomcat,但我的脚本执行失败。当我进入 pod 时,我看到战争被爆发,CATALINA_HOME设置好了,雄猫进程正在运行。但是我在 kubectl 日志中看到以下脚本错误:

ls:无法访问'/userhome/tomcat/webapps/app/WEB-INF/lib/':没有这样的文件或目录 chmod:无法访问'/userhome/tomcat/webapps/app/WEB-INF/lib/*':没有这样的文件或目录 错误:找不到或加载主类 com.myclass.upg 原因:java.lang.ClassNotFoundException: com.myclass.Upg

从错误中,我猜测 shell 脚本可能不会等待 tomcat 完成启动。我不知道为什么..

当我从 pod 内部手动运行脚本时,它运行良好。

这里的任何指示都值得赞赏。

更新:我确认这确实是时间问题。当我使用$CATALINA_HOME/bin/startup.sh && sleep 60 && /scripts/runUpg.sh时,脚本似乎运行良好。但我认为这是黑客式的,不是在 Web 应用程序中实现对类的调用的正确方法。

考虑在容器启动后执行脚本的 postStart 钩子。

示例参考


apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]

有些事情对我来说看起来很"可疑":

  1. /userhome/tomcate/webapps/app/WEB-INF/lib- 不应该是/user/home吗? (这只是一个旁注,我假设你已经正确定义了它(

  2. 真正的问题。我不记得 tomcat 脚本是如何定义的,但是如果没有 kubernetes,您可以尝试运行 tomcat 启动脚本并立即在 lib 文件夹上运行类似ls的东西。该文件夹确实不存在的可能性,这就是原因(在我的理解中,再次(:

Tomcat(作为一个独立的进程(的编写方式是"始终"运行,但在某些时间点,您可以将"WAR"放入webapps文件夹中,它将提取WAR并启动应用程序。然后你可以稍后再次发动另一场战争,依此类推。换句话说,Tomcat 作为一个进程的生命周期并不绑定到应用程序的生命周期。

tomcat 本身的启动过程应该读取配置,创建 HTTP 连接器以侦听端口 8080 或其他内容,仅此而已,在脚本完成之后,tomcat 启动。

在解决方案方面:

不要依赖 tomcat 为你创建进程的类路径,这是错误的。 相反,您可以:

  1. 将您的进程包装到 WAR 中,以便雄猫也可以管理它,同样它可以服务器许多 WAR,而不仅仅是一个 WAR。
  2. 使用应用程序创建一个挎斗容器,以便 2 个容器将在 Pod 中并行运行。这是一种 kubernetes 的做事方式,可能是最好的解决方案。在任何情况下,com.myclass.Upg进程都应该是自包含的(意味着包含自己的依赖项(。

最新更新