【问题标题】:Permission denied trying to use rootless Podman + docker-compose + Traefik with podman.sock权限被拒绝尝试使用无根 Podman + docker-compose + Traefik 和 podman.sock
【发布时间】:2022-09-22 23:45:48
【问题描述】:

TL:DR: 尝试通过 podman socket 使用 rootless Podman 和 docker-compose,并使用 Traefik 容器(与 podman socket 对话)将流量代理到其他容器,与 https://stackoverflow.com/a/73774327/1469083 相关

我得到了权限被拒绝的错误,我可以用我不想使用的特权容器来修复它。

设置

我在 RHEL 8 上运行

$ cat /etc/redhat-release 
Red Hat Enterprise Linux release 8.6 (Ootpa)

Podman 是预装的,我添加了 docker-compose (\"standalone\") 和 podman-docker:

$ curl -SL https://github.com/docker/compose/releases/download/v2.10.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
$ chmod a+x /usr/local/bin/docker-compose
$ sudo yum install podman-docker

并激活无根 podman 套接字,以便 podman 和 docker-compose 可以相互通信:

$ systemctl --user enable podman.socket
$ systemctl --user start podman.socket
$ systemctl --user status podman.socket
$ export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock
$ echo $DOCKER_HOST
unix:///run/user/1001/podman/podman.sock

我还将网络后端切换到 netavark,如果没有更改,DNS 就无法工作

$ podman info |grep -i networkbackend
  networkBackend: netavark

问题

首先,我尝试了 https://stackoverflow.com/a/73774327/1469083 的 compose 堆栈,并稍作修改:

version: \"3\"
services:
  frontend:
    image: \"docker.io/traefik:v2.8\"
    ports:
      - \"3000:80\"
      - \"127.0.0.1:3080:8080\"
    command:
      - --api.insecure=true
      - --providers.docker
    volumes:
      - /run/user/$UID/podman/podman.sock:/var/run/docker.sock

  backend:
    labels:
      traefik.http.routers.backend.rule: Host(`localhost`)
    image: \"tomcat:latest\"
    scale: 3

我的设置不喜欢 $UID 变量:

WARN[0000] The \"UID\" variable is not set. Defaulting to a blank string. 
...
Error response from daemon: make cli opts(): error making volume mountpoint for volume /run/user//podman/podman.sock: mkdir /run/user//podman: permission denied

我用硬编码的 UID=1001 替换了卷映射(它是运行 rootless podman 的用户的 UID,我认为我应该使用那个?)。套接字看起来像这样:

ls -la /run/user/1001/podman/podman.sock 
srw-rw----. 1 myrootlessuser myrootlessuser 0 22. 9. 11:28 /run/user/1001/podman/podman.sock


volumes:
  - /run/user/1001/podman/podman.sock:/var/run/docker.sock

但是现在我从 Traefik 尝试连接到 /var/run/docker.sock 失败时获得了权限被拒绝的错误:

example-docker-compose-frontend-1  | time=\"2022-09-22T12:04:52Z\" level=error msg=\"Provider connection error Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get \\\"http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version\\\": dial unix /var/run/docker.sock: connect: permission denied, retrying in 5.656635591s\" providerName=docker

如果我将 Traefik-container 更改为privileged: true,这可以解决问题。我不再收到错误,并且代理工作正常。

但是,出于安全原因,我宁愿不使用特权容器,或者至少理解为什么会这样。

问题

  1. 如何使用非特权 Traefik 容器进行这项工作?

  2. 如何验证无根 docker/podman 套接字是否正常工作?我见过这样的命令来测试有根的 podman 套接字,但在无根上没有成功

    $ sudo curl -H \"Content-Type: application/json\" --unix-socket /var/run/docker.sock http://localhost/_ping

    curl: (7) Couldn\'t connect to server

  3. 在哪里可以找到为无根 Podman 设置 docker 套接字的文档?我的设置是否正确(systemctl --user enable podman.socket 等)?我只能找到一些关于此的博客,并且建议各不相同,并且通常针对较旧的 Podman 版本。例如:

    标签: docker-compose traefik podman rootless


    【解决方案1】:

    问题 1 和 2

    如果您正在使用

    export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock
    

    您正在使用无根(非特权)Podman(即使您在 Compose 文件中指定 privileged: true)。

    要使用容器中泄漏的套接字,您需要使用命令行选项--security-opt label=disable 运行podman run

    例子:

    启动并启用 podman 套接字

    $ systemctl --user enable --now podman.socket
    Created symlink /home/testuser/.config/systemd/user/sockets.target.wants/podman.socket → /usr/lib/systemd/user/podman.socket.
    

    测试 Docker API 服务。 结果:失败。卷曲印花Couldn't connect to server

    $ podman run --rm \
      -v $XDG_RUNTIME_DIR/podman/podman.sock:/var/run/docker.sock \
      docker.io/library/fedora \
        /usr/bin/curl \
          -H "Content-Type: application/json" \
          --unix-socket /var/run/docker.sock \
            http://localhost/_ping
    curl: (7) Couldn't connect to server
    

    再次测试 Docker API 服务,但现在添加 --security-opt label=disable。 结果:成功

    $ podman run --rm \
      --security-opt label=disable \
      -v $XDG_RUNTIME_DIR/podman/podman.sock:/var/run/docker.sock \
      docker.io/library/fedora \
        /usr/bin/curl \
          -Hs "Content-Type: application/json" \
          --unix-socket /var/run/docker.sock \
            http://localhost/_ping
    OK$
    

    Docker API 服务以文本字符串响应好的.

    (在上面的命令中,我还添加了 curl 选项-s以便 curl 打印更少的调试输出)

    我猜想在 Compose 文件中添加 privileged: true 与提供 - 特权podman run 的命令行选项。

    使用效果之一 - 特权是它暗示--security-opt 标签=禁用.

    问题 3

    概括:

    播客服务通常按需运行(即以套接字激活podman.socket) 所以如果播客服务已启用 (systemctl --user enable podman.service)。

    更长的版本:

    如果podman.socket处于活动状态,则播客服务将在客户端连接时启动。 (Podman 支持套接字激活)

    播客服务也将在重新启动后启动,如果播客服务已启用 (systemctl --user enable podman.service) 并启用延迟 (loginctl enable-linger)。

    播客服务也将在用户登录时启动,如果播客服务已启用 (systemctl --user enable podman.service)。

    podman 进程运行在播客服务将在一段时间不活动后自动退出(默认为 5 秒)。

    在 Fedora 36 计算机上,Restart 指令设置为 no(默认值):

    $ grep Restart= /usr/lib/systemd/user/podman.service
    $ 
    

    这意味着是否真的无关紧要

    systemctl --user enable podman.service
    

    是否已运行。服务播客服务如果没有客户端访问它,无论如何都会在 5 秒内停止。

    【讨论】:

      猜你喜欢
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-08
      • 2021-01-09
      • 2019-06-05
      • 2020-06-12
      • 1970-01-01
      相关资源
      最近更新 更多