一个月前我遇到了类似的挑战,并且可以获得你想要的东西(即使我在 Kubernetes 上工作而不是使用 docker-compose)。
Docker 提供了一个内部 DNS 解析系统,如 StackOverflow question 中所述。
如果您稍微修改一下dig,您会发现容器使用的 DNS IP 与您的主机不同。
特别是,launching the Wordpress example 形成 docker-compose 文档,您可以通过以下方式查看它:
mkdir /tmp/test && cd /tmp/test
# create a docker-compose.yaml file and past the example from the link above
docker-compose up -d
# it should be test_default, check it out with `docker network ls`
docker run --rm -it --network test_default ubuntu /bin/bash
然后,在容器内输入:
apt-get update && apt-get install -y dnsutils
dig wordpress
你应该得到类似这样的东西:
root@91e47b426ed3:/# dig wordpress
; <<>> DiG 9.11.3-1ubuntu1.3-Ubuntu <<>> wordpress
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17239
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;wordpress. IN A
;; ANSWER SECTION:
wordpress. 600 IN A 172.18.0.3
;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Sun Feb 17 19:39:24 UTC 2019
;; MSG SIZE rcvd: 52
在这里你看到SERVER 字段显示127.0.0.11#53,在我的例子中,这是内部 Docker DNS 系统。您可以检查该地址是否是报告的地址(在我的情况下为172.18.0.3)安装curl 并在端口80 到达它。
考虑到这一点,您可以创建一个脚本或程序来定期执行地址解析,获取 DNS 为该服务返回的地址列表,并相应地更新您的白名单。
如何在运行时或构建阶段解析容器服务名称?
以 Java 为例,您可以使用 InetAddress 类,该类给定一个 URL,它返回一个 IP4 和 IP6 地址列表(您可以使用 Apache 公共库中的 InetAddressValidator 过滤它们)。你可以看到更多here(这就是我解决问题的方法)。在 Linux 中,有一个特定的系统调用 getaddrinfo,用于获取给定 URL 的 IP 列表。
使用 docker-compose 构建时,它是否会为容器分配静态地址,或者是否有可能在重启后容器 IP 发生变化?
关于第二个问题,docker-compose 使用与docker build 相同的逻辑,因此不会分配静态IP 地址或类似地址。最重要的是,如果容器崩溃并重新启动,它的 IP 可能会发生变化。