问题描述
我已经在 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。
- 将其下载到容器中(前提是容器能够使用
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 并且要切换到的用户列在 {{1} } -
/etc/passwd
和gosu
简单得多,基本上只会运行 Linuxsetpriv
系统调用,然后执行指定的负载 -
setuid()
是一个 Go 程序,可以轻松地进行静态编译,从而简化部署(只需将二进制文件复制到容器中即可)