如何在容器中对镜像进行操作

Docker VS Podman

由于只需要对镜像进行 pull、tag、push 操作,因此不需要全套的 Docker 服务,这里选择了 Podman。Podman 有一个子命令就是 buildah,它主要负责镜像相关的操作,这样会更加精简。

问题描述

在镜像中添加完 buildah 的依赖后,在容器中运行 buildah 时,报如下错误:
现象

解决方案

此问题的其中一个解决方案为:在宿主机中,修改 /proc/sys/user/max_user_namespaces 文件里面的值。但若采取此种方案,会导致线上环境 K8S 所在的宿主机,可能也要修改,这样的操作是不太可行的。

同事的踩坑经验:可以在 k8s 的 yaml 配置中,为 pod 开启特权模式,这样可以避免使用 user namespace。在 pod 定义处,添加配置,修改如下:

1
2
securityContext: 
privileged: true

修改后,buildah 在容器中不再报错。但对上面的修改,一方面持有安全疑虑,另一方面不太明白其中的原理。

为什么

为什么在本地的 K8S 环境中 rosco 执行没有问题?

图片

为什么将 pod 设置成特权模式之后便能正常执行 buildah?

  • 一篇比较具有参考价值的相关 issue。通过上述 issue 得知,即使使用 root 启动 buildah ,还是需要 user namespace 来获取相应的 capabilities
  • privileged 参数应该是会添加所有的 capabilities 到容器中(参考Docker文档)。

如何改进

只给 buildah 所需的 Linux capabilities,初步验证在 testing 运行 ok。

1
2
3
4
5
securityContext: 
# privileged: true
capabilities:
add:
- "SYS_ADMIN"

其中 CAP_SYS_ADMIN 的作用是:允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等。