如何在容器内部运行Podman?

28

我希望能够运行podman容器,以运行CI/CD管道。然而,我一直从podman容器中收到以下错误:

$ podman info
ERRO[0000] 'overlay' is not supported over overlayfs
Error: could not get runtime: 'overlay' is not supported over overlayfs: backing file system is unsupported for this graph driver

我正在使用Jenkins Kubernetes插件编写CI/CD流水线,以作为Kubernetes集群中的容器运行。我已成功编写了使用Docker-in-Docker容器运行docker builddocker push命令的流水线。
然而,在容器内运行Docker客户端和Docker Daemon会使CI/CD环境非常臃肿、难以配置,不是理想的工作方式。因此,我想我可以使用podman从Dockerfiles构建Docker镜像,而不使用庞大的Docker Daemon。
问题在于podman太新了,以至于我还没有看到有人尝试过这样做,也不是足够熟练的podman专家来正确执行这个任务。
因此,使用Ubuntu上的podman安装说明,我创建了以下Dockerfile:
FROM ubuntu:16.04

RUN apt-get update -qq \
    && apt-get install -qq -y software-properties-common uidmap \
    && add-apt-repository -y ppa:projectatomic/ppa \
    && apt-get update -qq \
    && apt-get -qq -y install podman

# To keep it running
CMD tail -f /dev/null

于是我构建了这个镜像并按照以下方式运行它:

# Build
docker build -t podman:ubuntu-16.04 .

# Run
docker run --name podman -d podman:ubuntu-16.04

然后在正在运行的容器上运行此命令时,我遇到了一个错误:
$ docker exec -ti podman bash -c "podman info"

ERRO[0000] 'overlay' is not supported over overlayfs
Error: could not get runtime: 'overlay' is not supported over overlayfs: backing file system is unsupported for this graph driver

我在一台运行Ubuntu 16.04的机器上安装了podman,并运行了相同的命令podman info,结果符合预期:
host:
  BuildahVersion: 1.8-dev
  Conmon:
    package: 'conmon: /usr/libexec/crio/conmon'
    path: /usr/libexec/crio/conmon
    version: 'conmon version , commit: '
  Distribution:
    distribution: ubuntu
    version: "16.04"
  MemFree: 2275770368
  MemTotal: 4142137344
  OCIRuntime:
    package: 'cri-o-runc: /usr/lib/cri-o-runc/sbin/runc'
    path: /usr/lib/cri-o-runc/sbin/runc
    version: 'runc version spec: 1.0.1-dev'
  SwapFree: 2146758656
  SwapTotal: 2146758656
  arch: amd64
  cpus: 2
  hostname: jumpbox-4b3620b3
  kernel: 4.4.0-141-generic
  os: linux
  rootless: false
  uptime: 222h 46m 33.48s (Approximately 9.25 days)
insecure registries:
  registries: []
registries:
  registries:
  - docker.io
store:
  ConfigFile: /etc/containers/storage.conf
  ContainerStore:
    number: 0
  GraphDriverName: overlay
  GraphOptions: null
  GraphRoot: /var/lib/containers/storage
  GraphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Using metacopy: "false"
  ImageStore:
    number: 15
  RunRoot: /var/run/containers/storage
  VolumePath: /var/lib/containers/storage/volumes

有人知道我该如何修复这个错误并让podman在容器中正常工作吗?

3个回答

13

你的Dockerfile还应该安装iptables:

FROM ubuntu:16.04

RUN apt-get update -qq \
    && apt-get install -qq -y software-properties-common uidmap \
    && add-apt-repository -y ppa:projectatomic/ppa \
    && apt-get update -qq \
    && apt-get -qq -y install podman \
    && apt-get install -y iptables

# To keep it running
CMD tail -f /dev/null

然后使用以下命令运行:

docker run -ti --rm podman:test bash -c "podman --storage-driver=vfs info"

这应该会给你期望的响应。


2
还需注意的是,存储驱动程序 VFS 的性能显著较低,并且占用更多的空间。详情请参阅:https://docs.docker.com/storage/storagedriver/vfs-driver/ - Vasili Angapov
2
真的,你宁愿拥有一个较慢的管道,也不愿以root身份运行它。 - Mihai
3
在 Mac 上按照此示例执行 podman info 命令会产生错误,输出如下:ERRO[0000] unable to write system event: "write unixgram @00006->/run/systemd/journal/socket: sendmsg: no such file or directory"。当我尝试运行容器 podman --storage-driver=vfs run docker.io/hello-world 时,会出现更多错误。 - Eldad Assis
1
@EldadAssis 我曾经也遇到过同样的问题。添加这个标志似乎可以解决它:--cgroup-manager=cgroupfs。即使没有 --privileged,它似乎也能正常工作。 - el-davo
3
它对我不起作用...我在哪里可以找到一个简单的例子来“从容器内运行podman”? - Thomas Suedbroecker

2

mihai的建议对于info是有效的,但是当我尝试执行例如run --rm docker.io/library/hello-world时,我遇到了一个错误:

最初的回答:

error creating network namespace for container …: mount --make-rshared /var/run/netns failed: "operation not permitted"
failed to mount shm tmpfs "/var/lib/containers/storage/vfs-containers/…/userdata/shm": operation not permitted

我只能通过为镜像设置非root用户,然后在特权模式下运行容器来解决这个问题,但这违背了练习的目的,因为DinD已经可以做到这一点:

最初的回答:

FROM ubuntu:18.04

RUN apt-get update -qq \
    && apt-get install -qq -y software-properties-common uidmap \
    && add-apt-repository -y ppa:projectatomic/ppa \
    && apt-get update -qq \
    && apt-get -qq -y install podman \
    && apt-get install -y iptables

RUN adduser --disabled-login --gecos test test

USER test

ENTRYPOINT ["podman", "--storage-driver=vfs"]
CMD ["info"]

used as

docker build -t podman:test .
docker run --rm --privileged podman:test run --rm docker.io/library/hello-world

可以在 hello-world 镜像上工作,但在 alpine 和 ubuntu 镜像上失败了。ERRO [0002] 应用层时出错: - Kuberchaun

2
我尝试了一下更宽松的配置 (--privileged=true),将存储卷从主机挂载到容器中,并且安装了iptables,并成功运行它(即 sudo apt-get install iptables)。
$ podman run -it --rm -v /var/run/containers/storage:/var/run/containers/storage -v /var/lib/containers/storage:/var/lib/containers/storage --storage-driver=overlay --privileged=true  mine bash
root@e275668d7c36:/# apt-get install -y -qq iptables
...
root@e275668d7c36:/# podman info
host:
  BuildahVersion: 1.8-dev
  Conmon:
    package: 'conmon: /usr/libexec/crio/conmon'
    path: /usr/libexec/crio/conmon
    version: 'conmon version , commit: '
  Distribution:
    distribution: ubuntu
    version: "16.04"
  MemFree: 71659520
  MemTotal: 482099200
  OCIRuntime:
    package: 'cri-o-runc: /usr/lib/cri-o-runc/sbin/runc'
    path: /usr/lib/cri-o-runc/sbin/runc
    version: 'runc version spec: 1.0.1-dev'
  SwapFree: 0
  SwapTotal: 0
  arch: amd64
  cpus: 2
  hostname: e275668d7c36
  kernel: 4.15.0-1035-aws
  os: linux
  rootless: false
  uptime: 315h 17m 53s (Approximately 13.12 days)
insecure registries:
  registries: []
registries:
  registries: []
store:
  ConfigFile: /etc/containers/storage.conf
  ContainerStore:
    number: 2
  GraphDriverName: overlay
  GraphOptions: null
  GraphRoot: /var/lib/containers/storage
  GraphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Using metacopy: "false"
  ImageStore:
    number: 4
  RunRoot: /var/run/containers/storage
  VolumePath: /var/lib/containers/storage/volumes

如果您想使用docker,也可以使用--privileged标志。请注意,还有其他专门设计用于构建容器的工具,其中一些不需要特权模式:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接