我正在尝试创建一个容器,可以通过docker套接字文件(主机- /var/run/docker.sock)访问主机docker远程API。
这里的答案建议将请求代理到套接字。我该如何做?
docker
镜像或在容器内安装Docker。或者您可以按照此处所述下载docker客户端二进制文件的归档文件。
2. 将Docker Unix套接字从主机暴露给容器。docker run -v /var/run/docker.sock:/var/run/docker.sock \
-ti docker
应该可以解决问题。
或者,您可以将其暴露到容器中并使用 Docker REST API。
更新:此答案的早期版本(基于以前版本的 jpetazzo post)建议从主机向容器绑定挂载Docker二进制文件。这不再可靠,因为Docker引擎不再作为(几乎)静态库分发。
像将/var/lib/docker
暴露给容器这样的其他方法很可能会导致数据损坏。有关详细信息,请参见不要在CI中使用Docker in Docker。
在此容器中(可能在许多其他容器中),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 socket调用时,我偶然发现了这个页面。
我的情况是,当my-service
尝试调用docker套接字以列出可用容器时,我遇到了访问被拒绝的错误。
最终,我使用docker-socket-proxy将docker socket代理到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
请注意,上述的compose文件已经准备好用于Swarm(docker stack deploy my-service
),但也可以在Compose模式下工作(docker-compose up -d
)。这种方法的好处是my-service
不再需要在Swarm manager上运行。
my-network
,但您的服务将其称为 my-service_my-network
吗? - Geoff
此前版本的文章建议将主机上的Docker二进制文件绑定到容器中。这已经不再可靠,因为Docker引擎不再作为(几乎)静态库分发。
- Murmel