访问容器内的Docker套接字

时间:2014-03-03 00:56:19

标签: docker

我正在尝试创建一个可以通过docker socket文件(主机 - /var/run/docker.sock)访问主机docker远程API的容器。

答案here建议代理对套接字的请求。我该怎么做呢?

3 个答案:

答案 0 :(得分:23)

我明白了。您只需通过卷参数

传递套接字文件即可
docker run -v /var/run/docker.sock:/container/path/docker.sock

正如@zarathustra指出的那样,这可能不是最好的主意。请参阅:https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html

答案 1 :(得分:18)

如果打算在容器内使用Docker,他应该清楚地了解安全隐患。

从容器内访问Docker很简单:

  1. 使用docker官方图片或在容器内安装Docker。或者您可以按照 here
  2. 所述,使用docker client binary下载存档
  3. 将Docker unix套接字从主机暴露给容器
  4. 这就是为什么

    docker run -v /var/run/docker.sock:/var/run/docker.sock \
           -ti docker
    

    应该这样做。

    或者,您可以展示到容器中并使用 Docker REST API

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

    注意事项:

    1. 容器可以访问所有主机容器,因此它可以阻止它们,删除,以顶级Docker容器内的任何用户运行任何命令。
    2. 所有创建的容器都是在顶级Docker中创建的。
    3. 当然,您应该了解如果容器可以访问主机的Docker守护程序,则它具有对整个主机系统的特权访问权限。根据容器和系统(AppArmor)配置,它可能更少或更危险
    4. 此处有其他警告dont-expose-the-docker-socket
    5. /var/lib/docker暴露给容器等其他方法可能会导致数据损坏。有关详细信息,请参阅 do-not-use-docker-in-docker-for-ci

      官方Jenkins CI容器用户的注意事项

      在这个容器中(可能在许多其他容器中),jenkins进程以非root用户身份运行。这就是为什么它没有与docker socket交互的权限。所以快速和彻底的解决方案正在运行

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

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

答案 2 :(得分:3)

我偶然发现了这个页面,同时尝试使用作为nobody用户运行的容器来进行docker socket调用。

在我的情况下,当my-service尝试调用docker socket以列出可用容器时,我收到了拒绝访问错误。

我最终使用docker-socket-proxy将docker套接字代理到my-service。这是访问容器中的docker socket的另一种方法,所以我会分享它。

我让my-service能够通过docker-socker-proxy环境变量接收它应该与之交谈的泊坞主机DOCKER_HOST

请注意,docker-socket-proxy需要以root用户身份运行才能将泊坞窗套接字代理为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

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