使用 containerd 的 ctr 以容器中的另一个用户身份执行命令 从 docker cli 到 crictl 的映射

问题描述

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

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

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

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

有没有可能?

解决方法

如评论中所述:

@buderu 恐怕根据此 documentation 使用 containerd 的 ctrl cli 是不可能的。

引用上述文档:

从 docker cli 到 crictl 的映射

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

docker cli crictl 说明 不支持的功能
附上 附上 附加到正在运行的容器 --detach-keys,--sig-proxy
执行 执行 在正在运行的容器中运行命令 --privileged、--user、--detach-keys

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

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

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

$ 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)

您可以通过关注它的 github 页面阅读更多相关信息:

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

用户需要通过以下任一方式安装提到的程序:

  • 在创建容器的图像时包括 installation part in Dockerfile
  • 将其下载到容器中(前提是容器能够使用curlwget下载文件):
    • $ 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

要考虑的其他注意事项:

  • susudo 适用于成熟的 UNIX 系统,除非安装了 PAM 并且要切换到的用户列在 {{1} }

  • /etc/passwdgosu 简单得多,基本上只会运行 Linux setpriv 系统调用,然后执行指定的负载

  • setuid() 是一个 Go 程序,可以轻松地进行静态编译,从而简化部署(只需将二进制文件复制到容器中即可)