<p>I learnt that to run a container as rootless, you need to specify either the SecurityContext:runAsUser 1000 or specify the USER directive in the DOCKERFILE.</p>
<p>Question on this is that there is no UID 1000 on the Kubernetes/Docker host system itself.</p>
<p>I learnt before that Linux User Namespacing allows a user to have a different UID outside it's original NS.</p>
<p>Hence, how does UID 1000 exist under the hood? Did the original root (UID 0) create a new user namespace which is represented by UID 1000 in the container?</p>
<p>What happens if we specify UID 2000 instead?</p>

<p>Hope this answer helps you</p>
<blockquote>
<p>I learnt that to run a container as rootless, you need to specify
either the SecurityContext:runAsUser 1000 or specify the USER
directive in the DOCKERFILE</p>
</blockquote>
<p>You are correct except in <code>runAsUser: 1000</code>. you can specify any UID, not only <code>1000</code>. Remember any UID you want to use (<code>runAsUser: UID</code>), that <code>UID</code> should already be there!</p>
<hr />
<p>Often, base images will already have a user created and available but leave it up to the development or deployment teams to leverage it. For example, the official Node.js image comes with a user named node at UID <code>1000</code> that you can run as, but they do not explicitly set the current user to it in their Dockerfile. We will either need to configure it at runtime with a <code>runAsUser</code> setting or change the current user in the image using a <code>derivative Dockerfile</code>.</p>
<pre class="lang-yaml prettyprint-override"><code>runAsUser: 1001          # hardcode user to non-root if not set in Dockerfile
runAsGroup: 1001         # hardcode group to non-root if not set in Dockerfile
runAsNonRoot: true       # hardcode to non-root. Redundant to above if Dockerfile is set USER 1000
</code></pre>
<p>Remmeber that <code>runAsUser</code> and <code>runAsGroup</code> <strong>ensures</strong> container processes do not run as the <code>root</code> user but don’t rely on the <code>runAsUser</code> or <code>runAsGroup</code> settings to guarantee this. Be sure to also set <code>runAsNonRoot: true</code>.</p>
<hr />
<p>Here is full example of <code>securityContext</code>:</p>
<pre class="lang-yaml prettyprint-override"><code># generic pod spec that's usable inside a deployment or other higher level k8s spec

apiVersion: v1
kind: Pod
metadata:
  name: mypod

spec:

  containers:

      # basic container details
    - name: my-container-name
      # never use reusable tags like latest or stable
      image: my-image:tag
      # hardcode the listening port if Dockerfile isn't set with EXPOSE
      ports:
        - containerPort: 8080
          protocol: TCP

      readinessProbe:        # I always recommend using these, even if your app has no listening ports (this affects any rolling update)
        httpGet:             # Lots of timeout values with defaults, be sure they are ideal for your workload
          path: /ready
          port: 8080
      livenessProbe:         # only needed if your app tends to go unresponsive or you don't have a readinessProbe, but this is up for debate
        httpGet:             # Lots of timeout values with defaults, be sure they are ideal for your workload
          path: /alive
          port: 8080

      resources:             # Because if limits = requests then QoS is set to &quot;Guaranteed&quot;
        limits:
          memory: &quot;500Mi&quot;    # If container uses over 500MB it is killed (OOM)
          #cpu: &quot;2&quot;          # Not normally needed, unless you need to protect other workloads or QoS must be &quot;Guaranteed&quot;
        requests:
          memory: &quot;500Mi&quot;    # Scheduler finds a node where 500MB is available
          cpu: &quot;1&quot;           # Scheduler finds a node where 1 vCPU is available

      # per-container security context
      # lock down privileges inside the container
      securityContext:
        allowPrivilegeEscalation: false # prevent sudo, etc.
        privileged: false               # prevent acting like host root
  
  terminationGracePeriodSeconds: 600 # default is 30, but you may need more time to gracefully shutdown (HTTP long polling, user uploads, etc)

  # per-pod security context
  # enable seccomp and force non-root user
  securityContext:

    seccompProfile:
      type: RuntimeDefault   # enable seccomp and the runtimes default profile

    runAsUser: 1001          # hardcode user to non-root if not set in Dockerfile
    runAsGroup: 1001         # hardcode group to non-root if not set in Dockerfile
    runAsNonRoot: true       # hardcode to non-root. Redundant to above if Dockerfile is set USER 1000
</code></pre>
<hr />
<p>sources:</p>
<ul>
<li><a href="https://github.com/BretFisher/podspec" rel="nofollow noreferrer">Kubernetes Pod Specification Good Defaults</a></li>
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/security-context" rel="nofollow noreferrer">Configure a Security Context for a Pod or Container</a></li>
<li><a href="https://snyk.io/blog/10-kubernetes-security-context-settings-you-should-understand/" rel="nofollow noreferrer">10 Kubernetes Security Context settings you should understand</a></li>
</ul>
