You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制基于tomcat:9.0.87镜像的K8s容器的kubectl exec登录访问?

如何限制基于tomcat:9.0.87镜像的K8s容器的kubectl exec登录访问?

看起来你踩了个常见的坑:想通过删除容器里的shell来阻止kubectl exec登录,但没想到直接删掉bash会导致Tomcat启动失败。这是因为Tomcat的catalina.sh启动脚本依赖bash运行,你删掉bash后,脚本找不到解释器,自然就启动失败了,也就是你看到的/usr/bin/env: ‘bash’: No such file or directory错误。

我给你几个可行的解决方案,你可以根据实际情况选择:

方案一:绕过catalina.sh,直接启动Tomcat的Java进程

既然catalina.sh依赖bash,那我们可以跳过这个脚本,直接用Java命令启动Tomcat,这样就不需要bash了,也就可以安全删除shell文件。

首先你需要找到catalina.sh run最终执行的Java命令:可以先运行原镜像,进入容器执行ps aux查看Tomcat的启动命令,或者直接查看catalina.sh的内容提取出Java命令。

然后修改你的Dockerfile,把Java命令直接作为CMD执行,同时删除shell:

FROM public.int.repositories.cloud.sap/tomcat:9.0.87 as deploy
COPY --from=build /cdi-web/target/cdi-web.war /usr/local/tomcat/webapps
# 删除所有交互shell
RUN rm -rf /bin/sh /bin/dash /bin/bash
EXPOSE 8080
# 直接用Java命令启动Tomcat,替换成你提取到的完整命令
CMD ["java", "-Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties", "-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager", "-Djdk.tls.ephemeralDHKeySize=2048", "-Djava.protocol.handler.pkgs=org.apache.catalina.webresources", "-Dorg.apache.catalina.security.SecurityListener.UMASK=0027", "-Dignore.endorsed.dirs=", "-classpath", "/usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar", "-Dcatalina.base=/usr/local/tomcat", "-Dcatalina.home=/usr/local/tomcat", "-Djava.io.tmpdir=/usr/local/tomcat/temp", "org.apache.catalina.startup.Bootstrap", "start"]

这样容器启动时直接运行Java进程,不需要依赖bash,同时用户执行kubectl exec时找不到可用的shell,也就无法进入容器。

方案二:保留bash但限制普通用户的访问权限(需调整启动逻辑)

如果你不想修改Tomcat的启动方式,可以保留bash,但通过权限配置让容器的运行用户无法执行bash,但需要调整启动逻辑避免Tomcat启动失败:

  1. 创建一个非root用户用来运行Tomcat
  2. 将bash移动到仅root可访问的目录,修改catalina.sh的shebang指向该路径
  3. 切换到非root用户启动Tomcat

对应的Dockerfile:

FROM public.int.repositories.cloud.sap/tomcat:9.0.87 as deploy
COPY --from=build /cdi-web/target/cdi-web.war /usr/local/tomcat/webapps
# 创建仅root可访问的目录存放bash
RUN mkdir -p /root/restricted_bin && mv /bin/bash /root/restricted_bin/
# 修改catalina.sh的shebang,让它用root目录下的bash执行
RUN sed -i 's|#!/usr/bin/env bash|#!/root/restricted_bin/bash|' /usr/local/tomcat/bin/catalina.sh
# 删除公共路径下的shell软链接
RUN rm -rf /bin/sh /bin/dash /bin/bash
# 创建非root用户并切换
RUN useradd -m tomcat
USER tomcat
EXPOSE 8080
CMD ["catalina.sh", "run"]

这样Tomcat启动时能通过修改后的shebang找到bash,而普通用户(容器运行用户)无法访问/root/restricted_bin/下的bash,执行kubectl exec时会因找不到shell而失败。

方案三:通过Kubernetes SecurityContext限制exec操作权限

另一种更优雅的方式是不修改镜像,而是通过Kubernetes的SecurityContext配置来限制容器的权限,降低exec后的风险:

  • 在Pod/Deployment的spec中设置runAsNonRoot: true,让容器以非root用户运行
  • 设置allowPrivilegeEscalation: false,禁止权限提升
  • 如果集群启用了PodSecurity Admission Controller,给命名空间配置restricted策略,进一步限制容器的特权操作

虽然这个方法不能完全阻止用户exec进入容器,但会极大限制用户在容器内的操作权限,降低安全风险。

总结一下,最直接解决你当前问题的是方案一,绕过catalina.sh直接启动Java进程,既可以删除shell阻止exec登录,又不会影响Tomcat的正常启动。

备注:内容来源于stack exchange,提问作者Amrutha V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 07:54:37