首页 > 解决方案 > 使用 containerd 的 ctr 作为容器中的另一个用户执行命令

问题描述

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

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

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

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

有没有可能?

标签: dockerkubernetesmicrok8scontainerd

解决方案


如评论中所述:

@buderu 恐怕根据本文档使用 containerd 的 ctrl cli 是不可能的。

引用上述文档:

从 docker cli 映射到 crictl

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

码头工人cli crictl 描述 不支持的功能
附加到正在运行的容器 --detach-keys, --sig-proxy
执行 执行 在正在运行的容器中运行命令 --privileged, --user , --detach-keys

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

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

一句话gosu。它是基于 Go的setuid++程序setgidsetgroupsexec

$ 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 页面了解更多信息:

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

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

  • 在创建容器镜像时包括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 程序,可以很容易地静态编译,从而简化部署(只需复制容器中的二进制文件)


推荐阅读