我正在docker上运行tomcat (tomcat:9-jre11),当启动它时,它记录以下内容,然后崩溃:
Cannot find /usr/local/tomcat/bin/setclasspath.sh
This file is needed to run this program
我的第一个问题实际上是进入容器,因为我不能在崩溃的容器上使用docker exec,但我通过在Rancher中设置一个入口点作为/bin/bash来管理它。
现在setclaspath .sh在容器的/usr/local/tomcat/bin/目录下。它之前有所有的读和执行权,我把它设置为777只是为了确保,仍然有同样的问题。更改所有者也是如此(tomcat似乎正在使用root,即使我在另一个用户上手动启动catalina.sh,并更改了文件所有者)。我用了比较强硬的方法,把整个文件夹设置为777,还是一样的:
drwxrwxrwx 1 root root 4096 Jun 29 14:53 .
drwxr-xr-x 1 root root 4096 Jun 29 14:31 ..
-rwxrwxrwx 1 root root 34699 Jun 2 21:08 bootstrap.jar
-rwxrwxrwx 1 root root 25523 Jun 29 14:00 catalina.sh
-rwxrwxrwx 1 root root 1664 Jun 2 21:08 catalina-tasks.xml
-rwxrwxrwx 1 root root 2007 Jun 28 03:01 ciphers.sh
-rwxrwxrwx 1 root root 25410 Jun 2 21:08 commons-daemon.jar
-rwxrwxrwx 1 root root 211777 Jun 2 21:08 commons-daemon-native.tar.gz
-rwxrwxrwx 1 root root 1932 Jun 28 03:01 configtest.sh
-rwxrwxrwx 1 root root 9110 Jun 28 03:01 daemon.sh
-rwxrwxrwx 1 root root 1975 Jun 28 03:01 digest.sh
-rwxrwxrwx 1 root root 3392 Jun 28 03:01 makebase.sh
-rwxrwxrwx 1 root root 3718 Jun 28 03:01 setclasspath.sh
-rwxrwxrwx 1 root root 1912 Jun 28 03:01 shutdown.sh
-rwxrwxrwx 1 root root 1914 Jun 28 03:01 startup.sh
-rwxrwxrwx 1 root root 46898 Jun 2 21:08 tomcat-juli.jar
-rwxrwxrwx 1 root root 5550 Jun 28 03:01 tool-wrapper.sh
-rwxrwxrwx 1 root root 1918 Jun 28 03:01 version.sh
我查看了catalina.sh脚本,导致问题的部分如下:
if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then
. "$CATALINA_HOME"/bin/setclasspath.sh
else
echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh"
echo "This file is needed to run this program"
fi
- r里面的条件是坏的。我已经读过了,如果文件存在并且是可读的,它填充了所有条件。我用-a添加了elif和- f条件和确实返回true,但权利似乎是问题,尽管它们被设置为777或不。我也在脚本中添加了一个whoami,它是根用户,所以不是所有权的问题。
startup.sh脚本也有类似的问题,在-x条件下,它找不到catalina.sh…
我们今天刚好碰到这个问题。
我们有一个Ubuntu 18.04服务器是从16.04升级的。docker包的版本为:
docker-ce/now 5:19.03.1~3-0~ubuntu-xenial amd64
docker-ce-cli/now 5:19.03.1~3-0~ubuntu-xenial amd64
docker-compose/bionic,bionic,now 1.17.1-2 all
内核是:4.15.0-154-generic x86_64
在这台机器上,运行当前版本的tomcat:9-jre11[0]会导致与问题中描述的相同的问题。
为了缩小范围,我们只是像这样启动一个bash:
docker run -it --rm --entrypoint=/bin/bash tomcat:9-jre11
现在出现了您观察到的奇怪行为,这与tomcat完全无关:
root@f338debf92f6:/usr/local/tomcat# [[ -r /bin/bash ]]
root@f338debf92f6:/usr/local/tomcat# echo $?
1
在我们测试的任何其他机器上,结果都是预期的,例如:
root@0083a80a9ec2:/usr/local/tomcat# [[ -r /bin/bash ]]
root@0083a80a9ec2:/usr/local/tomcat# echo $?
0
不幸的是,我无法使用新安装的Ubuntu 18.04重现这种行为。我甚至降级了内核版本,并从xenial repo安装了docker。
试图谷歌一个解决方案,我发现:https://github.com/alpinelinux/docker-alpine/issues/156 issuecomment - 912645029
所以我尝试了strace,这里的问题是可见的:
在Ubuntu 18.04:
...
read(255, "#!/bin/bashn[[ -r /bin/bash ]]n", 31) = 31
faccessat2(AT_FDCWD, "/bin/bash", R_OK, AT_EACCESS) = -1 EPERM (Operation not permitted)
read(255, "", 31) = 0
...
在我测试的任何其他机器上:
...
read(255, "#!/bin/bashn[[ -r /bin/bash ]]n", 31) = 31
faccessat2(AT_FDCWD, "/bin/bash", R_OK, AT_EACCESS) = -1 ENOSYS (Function not implemented)
faccessat(AT_FDCWD, "/bin/bash", R_OK) = 0
read(255, "", 31)
...
研究faccessat2系统调用表明,它不应该返回EPERM[1]。我不能确切地指出这种行为是在哪里引入的——在glibc和seccomp之间的某个地方,但这一切都归结为运行时对于这个新的系统调用来说太旧了。
以下是我们提出的解决方案:
- 升级你的机器-这可能不可行,虽然:)
- 使用基于旧版本Debian/Ubuntu的tomcat映像。对我们来说
tomcat:9.0.64-jre11-openjdk-slim-bullseye
工作好。 - 通过
--privileged
开关运行容器。这规避了系统调用特权问题,但通常是一个坏主意
引用
- digest sha256:f0c2eb420166a7d609c0031699e0778e11256f280cc2bfb5bfd61cde7ae45c61
- https://man7.org/linux/man-pages/man2/faccessat.2.html
更新Docker到最新版本帮助我启动tomcat
问题是描绘:
https://github.com/docker-library/tomcat/issues/269
Tomcat容器中的基本映像(Eclipse Temurin)已更新为Ubuntu LTS 22.04基于Jammy的Temurin镜像
如果你在你的主机上使用旧Docker版本和libseccomp,你会遇到"-r"的问题。bash中的标志。
我们的解决方案是使用Tomcattomcat:9-jdk11-temurin-focal
我在运行tomcat:9-jdk8映像时遇到了同样的问题,运行在一个debian 10.3虚拟机上,这个虚拟机不是最新的。
升级整个系统
sudo apt-get update
sudo apt upgrade
-> reboot VM
解决了这个问题。当前实际版本:docker-client: 20.10.17, docker engine: 19.03.9, kernel: 4.19.0-21-amd64
有趣的是:这个问题只在运行在这个过时的系统上构建的映像时发生。相同的tomcat形象建立在我们的詹金斯服务器开始没有问题在我当地的过时的VM。