docker 来自容器的主机和端口信息

docker host and port info from the container

我正在 Docker 容器中部署应用程序。应用程序使用回调 URL 向另一台服务器发送请求。回调 URL 包含应用 运行s.

实际所在的主机名和端口名

在“稳定、非动态”的测试环境中配置此回调 URL 很容易,因为我们知道应用 运行 所在的 IP 和端口。但是在Docker中,回调URL是宿主机的IP地址+在docker-compose.yml文件中配置的端口。所以这两个参数都是动态的,不能在Docker图像中硬编码。

我需要 docker 主机 IP 和容器中容器信息公开的端口。

这就是我的容器获取 docker 主机 IP 的方式:

version: '3'
services:
    my-server:
        image: ...
        container_name: my-server
        hostname: my-server
        ports:
            - "1234:9876"
        environment:
            - DOCKER_HOST_IP=${HOST_IP}

我在启动容器时设置主机 IP:

HOST_IP=$(hostname -i) docker-compose up

也许这不是一种优雅的方式,但这是迄今为止我能做的最好的方式。

但是我不知道如何获取容器内暴露的端口信息。 我的想法是,一旦我知道容器中的主机 IP,我就可以使用 nmap $HOST_IP 来获取打开的端口列表,并以某种方式 grep 找到正确的行。但这不起作用,因为我 运行 这个主机上有很多 Docker 容器,而且我无法 select 使用 grep 的正确行。

这是 nmap 的结果:

PORT      STATE SERVICE
22/tcp    open  ssh
111/tcp   open  rpcbind
443/tcp   open  https
5001/tcp  open  commplex-link
5002/tcp  open  rfe
7201/tcp  open  dlip
1234/tcp  open  vcom-tunnel
1235/tcp  open  vcom-tunnel
1236/tcp  open  teradataordbms
60443/tcp open  unknown

因此,当我从容器中执行 nmap 时,我可以看到主机中所有打开的端口。但是我不知道如何 select 属于我所在容器的行。

我可以在 docker 启动容器之前以某种方式自定义服务名称吗?

获取容器在主机上打开的端口号的最佳方法是什么?

您应该将完整的外部可见回调 URL 传递给应用程序。

ports:
  - "1234:9876"
environment:
  - CALLBACK_URL=http://physical-host.example.com:1234/path

您可以想象主机 IP 地址也不能直接路由的各种有趣场景。作为一个基本示例,假设您在家中 运行 在笔记本电脑上安装容器。膝上型电脑的 IP 地址可能是 192.168.1.2/24 但那仍然是一个“私有”地址;您需要路由器的外部可见 IP 地址,但没有简单的方法可以发现它。

xx.xx.xx.xx /--------\ 192.168.1.1   192.168.1.2 /----------------\
------------| Router |---------------------------| Laptop         |
            \--------/                           |   Docker       |
                                                 |     172.17.1.2 |
Callback address must be                         |     Server     |
http://xx.xx.xx.xx/path                          \----------------/

在云环境中,您可以想象使用负载平衡器的类似设置。您的容器可能 运行 在某些云托管实例上。容器可能会侦听端口 11111,您将其重新映射到实例上的端口 22222。但是在这之前,你有一个负载均衡器,它监听普通的 HTTPS 端口 443,进行 TLS 终止,然后转发到实例,你有一个连接到该负载均衡器的 DNS 名称;回调地址将是 https://service.example.com/path,但如果不明确告诉容器这一点,它就无法解决这个问题。