<p>I've installed microk8s on Ubuntu to have a simple Kubernetes cluster for test purposes.</p>
<p>I have a usecase where I have to execute a command in a container (in a kubernetes pod) with another user than the one which is used to run the container.</p>
<p>Since kubectl does not provide such a possibility, the workaround for docker environment is to use <code>docker exec -u</code>. But the Kubernetes cluster installed by microk8s does not use docker as container runtime, but only containerd.</p>
<p>I did not find a possibility to execute a command (as it is possible with docker) in a container as another user with containerd's ctr cli.</p>
<p>Is there a possibility?</p>

<p>As noted in the comment:</p>
<blockquote>
<p>@buderu I'm afraid this will not be possible with containerd's ctrl cli as per this <a href="https://kubernetes.io/docs/tasks/debug-application-cluster/crictl/#mapping-from-docker-cli-to-crictl" rel="nofollow noreferrer">documentation</a>.</p>
</blockquote>
<p>Citing above documentation:</p>
<blockquote>
<h3>Mapping from docker cli to crictl</h3>
<p>The exact versions for below mapping table are for docker cli v1.40 and crictl v1.19.0.</p>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>docker cli</th>
<th>crictl</th>
<th>Description</th>
<th><strong>Unsupported Features</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>attach</td>
<td>attach</td>
<td>Attach to a running container</td>
<td>--detach-keys, --sig-proxy</td>
</tr>
<tr>
<td>exec</td>
<td>exec</td>
<td>Run a command in a running container</td>
<td>--privileged, <strong>--user</strong>, --detach-keys</td>
</tr>
</tbody>
</table>
</div></blockquote>
<hr />
<p>A way to approach the problem would be the following:
use <code>crictl exec</code> to run a UID-changing program which in turn runs the desired payload; for example, to run a login <code>bash</code> shell as user with UID 1000:</p>
<ul>
<li><code>$ crictl exec -i -t gosu 1000 bash -l</code></li>
</ul>
<p>A word about <code>gosu</code>. It's Go-based <code>setuid</code>+<code>setgid</code>+<code>setgroups</code>+<code>exec</code> program:</p>
<pre class="lang-sh prettyprint-override"><code>$ gosu
Usage: ./gosu user-spec command [args]
   eg: ./gosu tianon bash
       ./gosu nobody:root bash -c 'whoami &amp;&amp; id'
       ./gosu 1000:1 id

./gosu version: 1.1 (go1.3.1 on linux/amd64; gc)
</code></pre>
<p>You can read more about it by following it's github page:</p>
<ul>
<li><em><a href="https://github.com/tianon/gosu" rel="nofollow noreferrer">Github.com: Tianon: gosu</a></em></li>
</ul>
<p><strong>It's worth noting that the solution above won't work with a generic container.</strong></p>
<p>User is required to install mentioned program by either:</p>
<ul>
<li>Including the <a href="https://github.com/tianon/gosu/blob/master/INSTALL.md" rel="nofollow noreferrer">installation part in Dockerfile</a> when creating container's image.</li>
<li>Downloading it into the container (provided that the container have the ability to download files with <code>curl</code> or <code>wget</code>):
<ul>
<li><code>$ crictl exec my-container wget -O /gosu https://github.com/tianon/gosu/releases/download/1.12/gosu-amd64</code></li>
<li><code>$ crictl exec -i -t my-container /gosu 1000 some-other-command</code></li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>A side note!</strong></p>
<p>Using second option (downloading straight into the container) required also to run:</p>
<ul>
<li><code>$ chmod +x ./gosu</code></li>
</ul>
</blockquote>
<hr />
<p>Additional notes to consider:</p>
<ul>
<li><p><code>su</code> and <code>sudo</code> are meant for a full-fledged UNIX system, and likely won't work unless PAM is installed and the user to switch to is listed in <code>/etc/passwd</code></p>
</li>
<li><p><code>gosu</code> and <code>setpriv</code> are much simpler and will basically only run Linux <code>setuid()</code> syscall and then execute the specified payload</p>
</li>
<li><p><code>gosu</code>, being a Go program, can be easily compiled statically which simplifies deployment (just copy the binary in the container)</p>
</li>
</ul>
