<p>I set the securityContext to run as a different User as definded in the Docker Image, but it still gets deployed and the App starts without problems.</p>
<p>Shouldn't it be failing or do I get something wrong here?</p>
<p>I am using GKE and Helm.
Kubernetes 1.22</p>
<p>Dockerfile:</p>
<pre><code>FROM openjdk:17-alpine as java17

FROM alpine:3.15.4

COPY --from=java17 /opt/openjdk-17 /opt/openjdk-17
ENV JAVA_HOME=/opt/openjdk-17
ENV PATH=$PATH:${JAVA_HOME}/bin
ARG JAVA_FILE=&quot;1.0-SNAPSHOT&quot;

RUN apk add --no-cache java-cacerts &amp;&amp; addgroup -S 10033 &amp;&amp; adduser -S 10033 -G 10033

USER 10033:10033

COPY --chown=10033:10033 ${JAVA_FILE} /opt/app/app.jar

ENTRYPOINT [&quot;java&quot;,&quot;-jar&quot;,&quot;/opt/app/app.jar&quot;, &quot;$JVM_OPTS&quot;]
</code></pre>
<p>Deployment:</p>
<pre><code>  containers:
  - name: &quot;myproject&quot;
    image: &quot;eu.gcr.io/mycompany/myproject:1.0&quot;
    imagePullPolicy: &quot;IfNotPresent&quot;
    securityContext:
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      privileged: false
      runAsUser: 10005
      runAsGroup: 20050
      runAsNonRoot: true
</code></pre>
<p>kubectl version</p>
<pre><code>Client Version: version.Info{Major:&quot;1&quot;, Minor:&quot;22&quot;, GitVersion:&quot;v1.22.5&quot;, GitCommit:&quot;5c99e2ac2ff9a3c549d9ca665e7bc05a3e18f07e&quot;, GitTreeState:&quot;clean&quot;, BuildDate:&quot;2021-12-16T08:38:33Z&quot;, GoVersion:&quot;go1.16.12&quot;, Compiler:&quot;gc&quot;, Platform:&quot;windows/amd64&quot;}
Server Version: version.Info{Major:&quot;1&quot;, Minor:&quot;22&quot;, GitVersion:&quot;v1.22.7-gke.1500&quot;, GitCommit:&quot;565bc494bfc66bfb42aec331000c61f72b020f1a&quot;, GitTreeState:&quot;clean&quot;, BuildDate:&quot;2022-03-10T09:33:51Z&quot;, GoVersion:&quot;go1.16.14b7&quot;, Compiler:&quot;gc&quot;, Platform:&quot;linux/amd64&quot;}
</code></pre>
<p>EDIT:</p>
<p>I have build the image with root user and it still works.</p>
<pre><code>/opt/app $ ls -la
total 73024
drwxr-xr-x    2 root     root          4096 May 20 12:03 .      
drwxr-xr-x    1 root     root          4096 May 20 12:04 ..     
-rw-r--r--    1 root     root      74765459 May 20 12:01 app.jar
</code></pre>
<p>I also check the following and somehow its working, but strange is that the app.jar, which is owned by root, can be executed. I think I am missing some concepts here.</p>
<p>So it would be possible to run any image as a specific user set from outside, which is very cool. Its kind a magic for me, so maybe someone can explain how this works?</p>
<pre><code>/ $ id
uid=10005 gid=20050 groups=101(20050)

/ $ ps aux
PID   USER     TIME  COMMAND
    1 10005     0:40 java -jar /opt/app/app.jar $JVM_OPTS
   45 10005     0:00 sh
   61 10005     0:00 ps aux
</code></pre>

Tim Schwalbe
<p>Files are typically world-readable, unless you explicitly set otherwise.  Your <code>ls -l</code> output shows that too: in the output <code>-rw-r--r--</code>, the file (leading <code>-</code>) is readable and writable but not executable by its owner (<code>rw-</code>), and readable but not writeable or executable by its group owner (<code>r--</code>) and also anyone else (<code>r--</code>).</p>
<p>This means that it doesn't actually matter which user owns the jar file.  You generally don't want your application code to be writable by the user that's running it, lest a bug causes it to be modified at runtime.  I'd suggest it's a good practice to have your application code owned by root, and not writable by other users.</p>
<pre class="lang-sh prettyprint-override"><code># without a --chown option, so it's owned by root
COPY ${JAVA_FILE} /opt/app/app.jar

# change users as the last thing in your Dockerfile
USER 10333
CMD [&quot;java&quot;, &quot;-jar&quot;, &quot;/opt/app/app.jar&quot;]
</code></pre>
<p>If your application needs to write data inside its container, first consider if it can write it elsewhere like a database.  This is doubly true on Kubernetes where you frequently will have multiple replicas of a pod and pods can be deleted outside your control.  If you really do need container-local state, keep it in a single directory; make that one directory owned by the default container user in the Dockerfile; and mount a volume over that directory when you run the container (in Kubernetes, via a StatefulSet).</p>
