【发布时间】:2016-01-31 03:55:18
【问题描述】:
我试图了解在docker-compose.yml 文件中安装docker.sock 的实际原因。是为了自动发现吗?
volumes:
- /var/run/docker.sock:/var/run/docker.sock
【问题讨论】:
标签: docker
我试图了解在docker-compose.yml 文件中安装docker.sock 的实际原因。是为了自动发现吗?
volumes:
- /var/run/docker.sock:/var/run/docker.sock
【问题讨论】:
标签: docker
docker.sock 是 Docker 守护程序正在侦听的 UNIX 套接字。它是 Docker API 的主要入口点。它也可以是 TCP 套接字,但出于安全原因,Docker 默认使用 UNIX 套接字。
Docker cli 客户端默认使用这个套接字来执行 docker 命令。您也可以覆盖这些设置。
您可能需要在容器中安装 Docker 套接字的原因可能不同。就像从另一个容器中启动新容器一样。或用于自动服务发现和日志记录目的。这会增加攻击面,因此如果将 docker 套接字安装在容器内,则应小心,该容器内运行受信任的代码,否则您可以简单地破坏运行 docker 守护进程的主机,因为 Docker 默认以 root 身份启动所有容器。
Docker 套接字在大多数安装中都有一个 docker 组,因此该组中的用户可以在没有 root 权限的情况下对 docker socket 运行 docker 命令,但实际的 docker 容器仍然获得 root 权限,因为 docker 守护进程以 root 身份有效运行(它需要 root 权限才能访问命名空间和 cgroups)。
我希望它能回答你的问题。
更多信息:https://docs.docker.com/engine/reference/commandline/dockerd/#examples
【讨论】:
/var/run/docker.sock 是一种常见但非常危险的做法。攻击者可以执行 docker 服务可以运行的任何命令,这通常提供对整个主机系统的访问作为docker 服务以 root 身份运行。"
我知道有点晚了,但我希望我的回答能提供很多见解
我先说一下Unix Sockets
术语套接字通常是指 IP 套接字。这些是绑定到端口(和地址)的端口,我们向其发送 TCP 请求并从中获取响应。
另一种类型的 Socket 是 Unix Socket,这些套接字用于 IPC(进程间通信)。它们也被称为 Unix 域套接字 (UDS)。 Unix 套接字使用本地文件系统进行通信,而 IP 套接字使用网络。
Docker 守护进程可以通过三种不同类型的 Socket 监听 Docker Engine API 请求:unix, tcp, and fd。
默认情况下,在 /var/run/docker.sock 中创建一个 unix 域套接字(或 IPC 套接字)
让我们看一些活生生的例子:
Docker Server使用这个socket监听REST API,客户端使用这个socket向服务器发送API请求。
curl 可以通过
--unix-socket标志与 Unix 套接字通信。由于 Docker 服务器 API 是作为 REST 公开的,我们需要发送命令 HTTP。另外,由于这个服务器是本地的(记住,文件系统),我们 可以在 URL 中传递任何主机名(或坚持使用 localhost,这将 工作也很好!)。服务器不关心主机名,只关心 路径。
curl --unix-socket /var/run/docker.sock http://localhost/images/json | jq
[
{
"Containers": -1,
"Created": 1525888860,
"Id": "sha256:24a77bfbb9ee3aeef9e24766ad6e9fa57f85c67596f154e8916e4f314067e149",
"Labels": null,
"ParentId": "",
"RepoDigests": [
"postgres@sha256:b06cdddba62f1550a1c674270814e72eaa8734d95912019b4ddc288b650ad67d"
],
"RepoTags": null,
"SharedSize": -1,
"Size": 39507096,
"VirtualSize": 39507096
}
]
一些命令:
你可以用 docker.sock 做很多事情
看看这个漂亮的article
【讨论】:
nc 与它交谈? 更新: 我想我知道答案了,可能 nc 通过原始传输消息进行通信,所以用它传递 REST 请求可能很痛苦,所以必须使用另一个工具来为我们生成请求以 REST 格式,并且还能够与套接字对话,即curl。
它基本上将主机 docker 守护进程暴露给容器。所以你可以从你的容器中调用 docker api/client 来启动/停止/构建镜像/容器,就像直接在主机上调用这些命令一样。
【讨论】:
当你在机器上安装 docker 时。有两个不同的程序:
Docker 服务器通过套接字接收命令(通过网络或通过“文件”)
Docker 客户端通过网络进行通信,并向 Docker 服务器发送消息,说明创建容器、启动容器、停止容器等。
当客户端和服务器在同一台计算机上运行时,它们可以通过一个称为套接字的特殊文件进行连接。而且由于它们可以通过文件进行通信,而 Docker 可以在主机和容器之间有效地共享文件,这意味着您可以在 Docker 本身内部运行客户端。
这是一个示例:
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock docker sh
此命令创建一个容器,docker 客户端安装在其中。并查看音量部分:-v /var/run/docker.sock:/var/run/docker.sock
使用-v 标志,它共享主机docker.sock 文件,因此您可以通过容器操作主机内的容器。
/ # docker run --rm -it ubuntu bash --> Creates a new container via container
在主机终端上运行docker ps。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0f9e333b59fe ubuntu "bash" 5 seconds ago Up 4 seconds zealous_wilson
b4a8af31416b docker "docker-entrypoint.s…" 16 minutes ago Up 16 minutes epic_elion
【讨论】: