【问题标题】:Can anyone explain docker.sock谁能解释 docker.sock
【发布时间】:2016-01-31 03:55:18
【问题描述】:

我试图了解在docker-compose.yml 文件中安装docker.sock 的实际原因。是为了自动发现吗?

volumes:
  - /var/run/docker.sock:/var/run/docker.sock

【问题讨论】:

    标签: docker


    【解决方案1】:

    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

    【讨论】:

    • 除了@boynux 提供的警告之外,您还可以在文章Docker Security Best-practices 中找到更多信息。在这一点上,他们说:“在容器内安装/var/run/docker.sock 是一种常见但非常危险的做法。攻击者可以执行 docker 服务可以运行的任何命令,这通常提供对整个主机系统的访问作为docker 服务以 root 身份运行。"
    【解决方案2】:

    我知道有点晚了,但我希望我的回答能提供很多见解

    我先说一下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

    【讨论】:

    • 太好了,我不知道也可以使用 REST 与非 TCP 套接字通信。只是一个问题,想知道是否也可以使用nc 与它交谈? 更新: 我想我知道答案了,可能 nc 通过原始传输消息进行通信,所以用它传递 REST 请求可能很痛苦,所以必须使用另一个工具来为我们生成请求以 REST 格式,并且还能够与套接字对话,即curl
    【解决方案3】:

    它基本上将主机 docker 守护进程暴露给容器。所以你可以从你的容器中调用 docker api/client 来启动/停止/构建镜像/容器,就像直接在主机上调用这些命令一样。

    【讨论】:

      【解决方案4】:

      当你在机器上安装 docker 时。有两个不同的程序:

      • Docker 客户端
      • 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-19
        • 2017-04-07
        • 2015-12-21
        • 1970-01-01
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多