使用containerd的ctr以容器中的另一个用户身份执行命令

bud*_*eru 5 docker kubernetes containerd microk8s

我在 Ubuntu 上安装了 microk8s,以拥有一个简单的 Kubernetes 集群用于测试目的。

我有一个用例,我必须使用另一个用户(而不是用于运行容器的用户)在容器(在 kubernetes pod 中)中执行命令。

由于 kubectl 不提供这种可能性,因此 docker 环境的解决方法是使用docker exec -u. 但microk8s安装的Kubernetes集群并没有使用docker作为容器运行时,而只使用containerd。

我没有找到使用containerd的ctr cli作为另一个用户在容器中执行命令(因为可以使用docker)的可能性。

有可能吗?

Daw*_*ruk 4

正如评论中指出的:

@buderu,恐怕根据本文档,containerd 的 ctrl cli 不可能做到这一点。

引用上述文档:

从 docker cli 到 crictl 的映射

下面映射表的确切版本适用于 docker cli v1.40 和 crictl v1.19.0。

docker 命令行 克里特尔 描述 不支持的功能
附加到正在运行的容器 --分离密钥,--sig-代理
执行 执行 在正在运行的容器中运行命令 --特权、--用户、--分离密钥

解决该问题的方法如下:使用crictl exec运行 UID 更改程序,该程序又运行所需的有效负载;例如,bash以 UID 1000 的用户身份运行登录 shell:

  • $ crictl exec -i -t gosu 1000 bash -l

一句话关于gosu。这是基于 Go的setuid+++setgid程序:setgroupsexec

$ gosu
Usage: ./gosu user-spec command [args]
   eg: ./gosu tianon bash
       ./gosu nobody:root bash -c 'whoami && id'
       ./gosu 1000:1 id

./gosu version: 1.1 (go1.3.1 on linux/amd64; gc)
Run Code Online (Sandbox Code Playgroud)

您可以通过关注它的 github 页面来了解更多相关信息:

值得注意的是,上述解决方案不适用于通用容器。

用户需要通过以下任一方式安装上述程序:

  • 创建容器镜像时将安装部分包含在 Dockerfile 中。
  • 下载到容器中(前提是容器有能力用curl或来下载文件wget):
    • $ crictl exec my-container wget -O /gosu https://github.com/tianon/gosu/releases/download/1.12/gosu-amd64
    • $ crictl exec -i -t my-container /gosu 1000 some-other-command

附注!

使用第二个选项(直接下载到容器中)还需要运行:

  • $ chmod +x ./gosu

需要考虑的其他注意事项:

  • su适用sudo于成熟的 UNIX 系统,除非安装了 PAM 并且要切换到的用户列在/etc/passwd

  • gosu并且setpriv更简单,基本上只运行 Linuxsetuid()系统调用,然后执行指定的有效负载

  • gosu作为一个Go程序,可以轻松地静态编译,从而简化部署(只需复制容器中的二进制文件)