将主机 Unix 套接字绑定到容器端口

将主机 Unix 套接字绑定到容器端口

我有一个 Docker 容器,它向应用程序公开端口(例如 Redis,它公开端口 6379)。我不想在我的主机上公开 6379(因此 1. 占用我为数不多的 65535 端口号之一,2. 将 Redis 缓存公开给我主机上的所有用户),而是想通过本地目录中的 Unix 套接字连接到 Redis(例如通过使用$ redis-cli -s ~/redis.sock)。

然而,Docker 似乎只提供端口到端口的转发(通过ports中的选项docker compose,或-p中的开关docker run)或套接字到套接字转发(通过公开套接字所在的目录)。是否有其他方法(在任何符合 GCI 的容器系统中)可以进行我正在寻找的直接套接字到端口转换,或者这是 GCI 标准固有的限制?

我知道 Redis 本身可以监听 Unix 套接字,但我对没有该功能的应用程序很感兴趣。

答案1

docker 没有原生支持此功能,但你可以使用类似socat在容器中运行以在 unix 套接字和网络套接字之间进行代理(并使用绑定挂载在主机文件系统中公开 unix 套接字)。

redis个例子,我们可以做这样的事情:

services:
  redis:
    image: docker.io/redis
    healthcheck:
      test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
      interval: 10s

  redis-socket-proxy:
    image: docker.io/alpine/socat
    volumes:
      - ./sockets:/sockets
    command:
    - unix-listen:/sockets/redis.socket,fork,mode=0777
    - tcp-connect:redis:6379
    depends_on:
      redis:
        condition: service_healthy

./sockets/redis.socket现在您有一个可以连接 redis 服务的unix 套接字。


也就是说,您不仅有 65535 个可用的网络套接字;因为您可以将套接字绑定到特定的 IP 地址,所以您可以拥有比这多很多倍的套接字。这里有两个 redis 服务器,它们都使用两个不同的本地主机地址绑定到主机上的端口 6379:

services:
  redis1:
    image: docker.io/redis
    ports:
      - 127.0.0.1:6379:6379

  redis2:
    image: docker.io/redis
    ports:
      - 127.0.0.2:6379:6379

在许多情况下,您甚至不需要在主机上绑定端口;如果您有一个像 redis 或数据库这样的服务,或者被用作另一个容器化应用程序的后端的东西,就不需要发布后端服务端口;您只需要公开前端服务。

当然,无论您是否发布了端口,您始终可以使用容器 IP 地址连接到服务方向。

对于本身不支持绑定到 unix 套接字的服务,您可能很难找到知道如何通过 unix 套接字连接到服务的客户端库或其他工具。

相关内容