2014-03-03 180 views
14

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

答案here建议代理请求到套接字。我会如何去做这件事?

回答

20

我想通了。你可以简单的通过量参数

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

你不应该这样做,请参阅https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html – Zarathustra

+0

@Zarathustra同意并感谢。然而,问题不在于是否应该完成。我会在此更新答案并提出警告。 –

15

如果有人打算从容器内使用Docker,他应该清楚地理解安全含义。

从容器内访问泊坞窗很简单:

  1. 使用docker官方图片或安装泊坞窗的容器内。或描述 here
  2. 从主机暴露泊坞窗Unix套接字集装箱

这就是为什么

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

应该做的伎俩,你可以下载存档与泊坞窗客户端二进制文件。

或者,你可能会暴露到容器中,并使用 Docker REST API

UPD:这个答案的前版本(基于以前的版本的 jpetazzo post)建议绑定贴装从主机到容器中的泊坞窗二进制文件。这不再可靠,因为Docker Engine不再是(几乎)静态库。

注意事项:

  1. 所有主机的容器将是容器访问,所以它可以在任何命令阻止他们,删除,运行作为顶级Docker容器内部的任何用户
  2. 所有创建的容器都是在顶级Docker中创建的。
  3. 当然,您应该明白,如果容器可以访问主机的Docker守护进程,则它具有对整个主机系统的特权访问权限。根据容器和系统(AppArmor的)的配置,也可能要小或者更危险
  4. 其他在这里警告dont-expose-the-docker-socket

喜欢暴露/var/lib/docker集装箱都可能导致数据损坏的其他方法。有关更多详细信息,请参见 do-not-use-docker-in-docker-for-ci

注官方詹金斯CI容器

的用户在该容器中(也可能在其他很多)詹金斯进程作为非root用户。这就是为什么它没有与docker套接字进行交互的权限。这么快&肮脏的解决方案开始容器运行后

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

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

+1

另外,还有一篇很棒的高级文章:http://jpetazzo.github.io/2016/04/03/one-container-to-rule-them-all/ – Dmitriusan

+0

装载docker二进制文件[阻止](https: //jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/#the-solution):'此版本的前版本建议绑定挂载docker二进制文件从主机到容器。这是不可靠的,因为Docker引擎不再作为(几乎)静态库来分发。“ – Murmel

+1

谢谢,将会更新一个帖子 – Dmitriusan

0

我偶然发现这个页面,同时试图让Docker套接字调用在作为nobody用户运行的容器中工作。

在我的情况下,当my-service尝试调用docker套接字来列出可用容器时,我得到拒绝访问错误。

我结束了使用docker-socket-proxy代理码头插座my-service。这是访问容器内的docker套接字的不同方法,所以我尽管我会分享它。

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

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

注意上面撰写文件被群聚就绪(docker stack deploy my-service),但它应该在撰写模式工作,以及(docker-compose up -d)。这种方法的好处在于my-service不再需要在swarm管理器上运行。