访问容器中的Docker套接字



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

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

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

从容器中访问Docker很简单:

  1. 使用docker官方镜像或在容器内安装Docker。或者,您可以下载带有docker客户端二进制文件的归档文件,如下所述
  2. 从主机到容器公开Docker unix套接字

这就是的原因

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

应该做到这一点。

或者,您可以将其暴露到容器中,并使用Docker REST API

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

注意事项:

  1. 容器可以访问所有主机容器,因此它可以在顶级Docker容器内以任何用户的身份停止、删除、运行任何命令
  2. 所有创建的容器都是在顶级Docker中创建的
  3. 当然,您应该明白,如果容器可以访问主机的Docker守护进程,那么它就有权访问整个主机系统。根据容器和系统(AppArmor)配置的不同,它的危险性可能会更小或更大
  4. 此处的其他警告不要暴露docker套接字

其他方法,如向容器公开/var/lib/docker,可能会导致数据损坏。有关更多详细信息,请参阅不要在docker中使用docker for ci。

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

在这个容器中(可能还有许多其他容器中),jenkins进程以非root用户的身份运行。这就是为什么它没有权限与docker套接字进行交互。这么快&脏溶液正在运行

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

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

我想明白了。您可以简单地通过卷参数传递套接字文件

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/

我在尝试从作为nobody用户运行的容器中进行docker套接字调用时偶然发现了这个页面。

在我的案例中,当my-service尝试调用docker套接字以列出可用容器时,我遇到了拒绝访问错误。

我最终使用了dockersocket代理来将docker套接字代理到my-service。这是一种访问容器中docker套接字的不同方法,所以我想我会共享它

我使my-service能够通过DOCKER_HOST环境变量接收它应该与之对话的docker主机,在本例中为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不再需要在群管理器上运行。

最新更新