当不以 ROOT 身份运行我不想编辑的 Tomcat Docker 映像时,如何写入 ROOT 拥有的目录?



我有一个docker映像,我正试图使用K8运行它。我可以让它在我的家庭环境中运行,但不能在我的工作场所运行,因为我们不能在k8集群上以root身份运行。

docker镜像是一个Tomcat服务器,其中有一个WAR文件:

/usr/local/tomcat/webapps/ROOT.war

在启动过程中,Tomcat试图将WAR分解到以下目录中:

/usr/local/tomcat/webapps/ROOT

但它不能做到这一点,因为/usr/local/tomcat/webapps/是ROOT所有的。

所以我认为最好的解决方法是装载一个带有emptyDir{}的卷,如下所示:

apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers: 
...
name: test-container
volumeMounts:
- mountPath: //usr/local/tomcat/webapps/ROOT
name: tomcat
volumes:
- name: tomcat
emptyDir: {}

但这不起作用,因为它只是在webapps下创建了一个空的ROOT文件夹,Tomcat无法将WAR分解到该文件夹,因为它希望自己创建ROOT。

我也试过这个:

volumeMounts:
- mountPath: //usr/local/tomcat/webapps
name: tomcat

但现在/webapps只是一个空文件夹,因为我认为我正在覆盖容器启动时为我设置的内容。

我显然错过了一些重要的东西。。。我不想编辑图像,因为我相信必须有另一种方法来解决这个问题。我只是希望/tomcat/webapps可以由非root的runAsUser写入。

最好的方法是什么?

如果您还没有,只需为您的图像创建一个Dockerfile,并在其中添加以下行:

...
ENV USER=<YOUR-CONTAINER-USER>
ENV UID=10014
ENV GID=10014
RUN addgroup "$USER" --gid "$GID" 
&& adduser 
--disabled-password 
--gecos "" 
--home "$(pwd)" 
--ingroup "$USER" 
--no-create-home 
--uid "$UID" 
"$USER"
RUN chown -R "$USER":"$USER" /usr/local/tomcat/webapps/ROOT
USER "$USER"
...

修复该问题的简单方法是通过initContainer:,尽管fsGroup:是更具声明性的修复方法,只要集群的安全策略允许设置该字段

spec:
initContainers:
- name: chown
image: docker.io/library/busybox:latest
command:
- chown
- -R
- whatever-the-uid-is-for-your-tomcat-image
- /usr/local/tomcat/webapps/ROOT
volumeMounts:
- mountPath: /usr/local/tomcat/webapps/ROOT
name: tomcat
containers:
# ... as before

我建议在Docker级别上解决这个问题,因为您很可能无论如何都要为应用程序创建一个子映像。这种方法的优点是,您可以在部署到K8之前进行测试。此外,您可以产生更高质量的图像,而不是需要"高质量"的图像;调整";用于保存部署。

使用Docker这样做看起来是这样的:

FROM tomcat
RUN addgroup --system -gid 1000 app && adduser --system -uid 1000 -gid 1000 app
RUN chown -R app /usr/local/tomcat/
USER app
COPY --chown=1000:root your-war /usr/local/tomcat/webapps

任何基于K8s的解决方案,比如用卷覆盖webapp文件夹并为该卷分配非根权限,都会遇到很难将WAR复制到webapp文件夹中的问题。虽然init容器的复杂装置在理论上是可能的,但它们很脆弱,过于复杂(对于初学者来说,你必须确保init容器和主容器中的用户和组相同。此外,你的WAR需要在init容器中(。

最新更新