【发布时间】:2014-03-03 00:56:19
【问题描述】:
我正在尝试创建一个容器,该容器可以通过 docker 套接字文件(主机 - /var/run/docker.sock)访问主机 docker 远程 API。
答案here 建议将请求代理到套接字。我该怎么做呢?
【问题讨论】:
标签: docker
我正在尝试创建一个容器,该容器可以通过 docker 套接字文件(主机 - /var/run/docker.sock)访问主机 docker 远程 API。
答案here 建议将请求代理到套接字。我该怎么做呢?
【问题讨论】:
标签: docker
如果打算在容器中使用 Docker,他应该清楚地了解安全隐患。
从容器内访问 Docker 很简单:
docker官方镜像或者在容器内安装Docker。或者您可以按照 here 的描述使用 docker 客户端二进制文件下载存档
这就是为什么
docker run -v /var/run/docker.sock:/var/run/docker.sock \
-ti docker
应该可以解决问题。
或者,您可以暴露到容器中并使用 Docker REST API
UPD:此答案的先前版本(基于 jpetazzo post 的先前版本)建议将 docker 二进制文件从主机绑定安装到容器。这不再可靠,因为 Docker 引擎不再作为(几乎)静态库分发。
将/var/lib/docker 暴露给容器等其他方法可能会导致数据损坏。详情请见 do-not-use-docker-in-docker-for-ci 。
在这个容器(可能还有很多其他容器)中,jenkins 进程以非 root 用户身份运行。这就是它无权与 docker socket 交互的原因。如此快速而肮脏的解决方案正在运行
docker exec -u root ${NAME} /bin/chmod -v a+s $(which docker)
启动容器后。这允许容器中的所有用户以 root 权限运行 docker 二进制文件。更好的方法是允许通过无密码 sudo 运行 docker 二进制文件,但官方 Jenkins CI 映像似乎缺少 sudo 子系统。
【讨论】:
Former versions of this post advised to bind-mount the docker binary from the host to the container. This is not reliable anymore, because the Docker Engine is no longer distributed as (almost) static libraries.
我在尝试使 docker 套接字调用从以 nobody 用户身份运行的容器中工作时偶然发现。
在我的情况下,当my-service 尝试调用 docker 套接字以列出可用容器时,我遇到了拒绝访问错误。
我最终使用 docker-socket-proxy 将 docker 套接字代理到 my-service。这是在容器中访问 docker 套接字的另一种方法,所以我想分享它。
我让my-service 能够接收它应该与之通信的docker 主机,在这种情况下是docker-socker-proxy,通过DOCKER_HOST 环境变量。
请注意,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 文件已准备好 (docker stack deploy my-service),但它也应该在 compose 模式下工作 (docker-compose up -d)。这种方法的好处是 my-service 不再需要在 swarm manager 上运行。
【讨论】:
my-network,而您的服务将其称为my-service_my-network吗?
我想通了。您可以简单地通过卷参数传递套接字文件
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/
【讨论】: