我有一个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容器中(。