访问容器中的Docker套接字

访问容器中的Docker套接字,docker,Docker,我正在尝试创建一个容器,该容器可以通过docker套接字文件(host machine-/var/run/docker.sock)访问主机docker远程API 答案建议将请求代理到套接字。我该怎么做呢?我想出来了。您只需通过volume参数传递套接字文件 docker run -v /var/run/docker.sock:/container/path/docker.sock 正如@zarathustra所指出的,这可能不是最好的想法。请参阅:如果打算从容器中使用Docker,他应该清楚地

我正在尝试创建一个容器,该容器可以通过docker套接字文件(host machine-/var/run/docker.sock)访问主机docker远程API


答案建议将请求代理到套接字。我该怎么做呢?

我想出来了。您只需通过volume参数传递套接字文件

docker run -v /var/run/docker.sock:/container/path/docker.sock

正如@zarathustra所指出的,这可能不是最好的想法。请参阅:

如果打算从容器中使用Docker,他应该清楚地了解安全含义

从容器内访问Docker很简单:

  • 使用
    docker
    官方图像或在容器内安装docker。或者,您也可以使用docker客户端二进制文件下载归档文件,如下所述
  • 从主机到容器公开Docker unix套接字
  • 这就是为什么

    docker run -v /var/run/docker.sock:/var/run/docker.sock \
           -ti docker
    
    我们应该做到这一点

    或者,您可以将其暴露在容器中并使用

    UPD:此答案的前一版本(基于的前一版本)建议将docker二进制文件从主机绑定到容器。这不再可靠,因为Docker引擎不再作为(几乎)静态库分发

    考虑事项:
  • 所有主机容器都可以被容器访问,所以它可以像顶级Docker容器中的任何用户一样停止、删除、运行任何命令
  • 所有创建的容器都在顶级Docker中创建
  • 当然,您应该了解,若容器可以访问主机的Docker守护进程,那个么它就有权访问整个主机系统。根据容器和系统(AppArmor)的配置,其危险性可能更小或更高
  • 这里还有其他警告
  • 向容器公开
    /var/lib/docker
    等其他方法可能会导致数据损坏。有关更多详细信息,请参阅

    官方Jenkins CI容器用户注意事项 在这个容器中(可能在许多其他容器中),jenkins进程以非root用户的身份运行。这就是为什么它没有与docker套接字交互的权限。因此,快速而肮脏的解决方案正在运行

    docker exec -u root ${NAME} /bin/chmod -v a+s $(which docker)
    

    启动容器后。它允许容器中的所有用户使用根权限运行docker二进制文件。更好的方法是允许通过无密码sudo运行docker binary,但官方Jenkins CI映像似乎缺少sudo子系统。

    我在试图使docker套接字调用从作为
    无人
    用户运行的容器中工作时,偶然发现了此页面

    在我的例子中,当
    我的服务
    试图调用docker套接字以列出可用容器时,我遇到了拒绝访问错误

    我最终使用代理docker套接字到我的服务
    。这是访问容器内docker套接字的另一种方法,因此我想我会共享它

    我使
    my service
    能够通过
    docker\u host
    环境变量接收它应该与之对话的docker主机,
    docker socker proxy
    ,在这种情况下

    请注意,
    docker socket proxy
    需要以
    root
    用户身份运行,才能将docker socket代理到
    my service

    示例
    docker compose.yml

    version: "3.1"
    
    services:
      my-service:
        image: my-service
        environment:
          - DOCKER_HOST=tcp://docker-socket-proxy:2375
        networks:
          - my-service_my-network
      docker-socket-proxy:
        image: tecnativa/docker-socket-proxy
        environment:
          - SERVICES=1
          - TASKS=1
          - NETWORKS=1
          - NODES=1
        volumes:
         - /var/run/docker.sock:/var/run/docker.sock
        networks:
          - my-service_my-network
        deploy:
          placement:
            constraints: [node.role == manager]
    
    networks:
      my-network:
        driver: overlay
    

    请注意,上面的撰写文件是swarm ready(
    docker stack deploy my service
    ),但它也应该在撰写模式下工作(
    docker compose up-d
    )。这种方法的好处是,
    我的服务
    不再需要在swarm manager上运行。

    另外,还有一篇很棒的高级文章:装载docker二进制文件是:
    本文的早期版本建议将装载docker二进制文件从主机绑定到容器。这不再可靠,因为Docker引擎不再作为(几乎)静态库分发。
    您不应该这样做,请参阅@Zarathustra同意并感谢。然而,问题不是是否应该这样做。我将在这里更新答案,并发出警告。这就是Portainer的工作方式,因此有什么替代方案?您是否介意解释一下为什么您的网络被称为
    my-network
    ,但您的服务将其称为
    my-service\u my-network